From 200c9bf47cb031904dbb6274da6795fe1d7a8b4f Mon Sep 17 00:00:00 2001 From: Nidhi Bhat G <44032758+nidhibhatg@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:21:21 +0530 Subject: [PATCH] [frontend] Implementation of sorting columns in Storage browser table (#3588) * [frontend] Implementation of sorting columns in Storage browser table * [frontend] Added option to unsort the table and suggested improvements * [frontend] Replaced empty div with null in ternary operator * [frontend] Moved enum to types.ts file and necessary changes --- .../StorageBrowserTabContent.tsx | 19 +++++-- .../StorageBrowserTable.scss | 12 +++++ .../StorageBrowserTable.tsx | 53 +++++++++++++++++-- .../js/reactComponents/FileChooser/api.ts | 13 +++-- .../js/reactComponents/FileChooser/types.ts | 10 +++- 5 files changed, 93 insertions(+), 14 deletions(-) diff --git a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx index 5c581d5d90..670cf4f83a 100644 --- a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx +++ b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx @@ -37,7 +37,8 @@ import { fetchFiles } from '../../../../reactComponents/FileChooser/api'; import { PathAndFileData, StorageBrowserTableData, - PageStats + PageStats, + SortOrder } from '../../../../reactComponents/FileChooser/types'; import './StorageBrowserTabContent.scss'; @@ -62,6 +63,10 @@ const StorageBrowserTabContent: React.FC = ({ const [pageStats, setPageStats] = useState(); const [pageSize, setPageSize] = useState(); const [pageNumber, setPageNumber] = useState(1); + const [sortByColumn, setSortByColumn] = useState(''); + const [sortOrder, setSortOrder] = useState(SortOrder.NONE); + //TODO: Add filter functionality + const [filterData, setFilterData] = useState(''); const { t } = i18nReact.useTranslation(); @@ -132,16 +137,16 @@ const StorageBrowserTabContent: React.FC = ({ useEffect(() => { setloadingFiles(true); - fetchFiles(filePath, pageSize, pageNumber) + fetchFiles(filePath, pageSize, pageNumber, filterData, sortByColumn, sortOrder) .then(responseFilesData => { setFilesData(responseFilesData); const tableData: StorageBrowserTableData[] = responseFilesData.files.map(file => ({ name: file.name, size: file.humansize, user: file.stats.user, - groups: file.stats.group, + group: file.stats.group, permission: file.rwx, - lastUpdated: file.mtime, + mtime: file.mtime, type: file.type, path: file.path })); @@ -156,7 +161,7 @@ const StorageBrowserTabContent: React.FC = ({ .finally(() => { setloadingFiles(false); }); - }, [filePath, pageSize, pageNumber]); + }, [filePath, pageSize, pageNumber, sortByColumn, sortOrder]); return ( @@ -217,6 +222,10 @@ const StorageBrowserTabContent: React.FC = ({ onFilepathChange={setFilePath} onPageSizeChange={setPageSize} onPageNumberChange={setPageNumber} + onSortByColumnChange={setSortByColumn} + onSortOrderChange={setSortOrder} + sortByColumn={sortByColumn} + sortOrder={sortOrder} > diff --git a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.scss b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.scss index 6a6fc54755..8e724d7927 100644 --- a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.scss +++ b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.scss @@ -37,6 +37,10 @@ $cell-height: 40px; th.ant-table-cell { text-align: left; } + + table { + width: 100%; + } } .hue-storage-browser__table-row { @@ -55,3 +59,11 @@ $cell-height: 40px; .hue-storage-browser__table-cell-name { color: vars.$fluidx-blue-700; } + +.hue-storage-browser__table-column-header { + display: flex; +} + +.hue-storage-browser__table-column-title { + text-transform: capitalize; +} diff --git a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.tsx b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.tsx index 4185d004ec..4fc115b1a4 100644 --- a/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.tsx +++ b/desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.tsx @@ -19,10 +19,16 @@ import { i18nReact } from '../../../../utils/i18nReact'; import Table from 'cuix/dist/components/Table'; import { ColumnProps } from 'antd/lib/table'; import FolderIcon from '@cloudera/cuix-core/icons/react/ProjectIcon'; +import SortAscending from '@cloudera/cuix-core/icons/react/SortAscendingIcon'; +import SortDescending from '@cloudera/cuix-core/icons/react/SortDescendingIcon'; //TODO: Use cuix icon (Currently fileIcon does not exist in cuix) import { FileOutlined } from '@ant-design/icons'; -import { PageStats, StorageBrowserTableData } from '../../../../reactComponents/FileChooser/types'; +import { + PageStats, + StorageBrowserTableData, + SortOrder +} from '../../../../reactComponents/FileChooser/types'; import Pagination from '../../../../reactComponents/Pagination/Pagination'; import './StorageBrowserTable.scss'; import Tooltip from 'antd/es/tooltip'; @@ -33,8 +39,12 @@ interface StorageBrowserTableProps { onFilepathChange: (path: string) => void; onPageNumberChange: (pageNumber: number) => void; onPageSizeChange: (pageSize: number) => void; + onSortByColumnChange: (sortByColumn: string) => void; + onSortOrderChange: (sortOrder: SortOrder) => void; pageSize: number; pageStats: PageStats; + sortByColumn: string; + sortOrder: SortOrder; rowClassName?: string; testId?: string; } @@ -51,6 +61,10 @@ const StorageBrowserTable: React.FC = ({ onFilepathChange, onPageNumberChange, onPageSizeChange, + onSortByColumnChange, + onSortOrderChange, + sortByColumn, + sortOrder, pageSize, pageStats, rowClassName, @@ -61,12 +75,43 @@ const StorageBrowserTable: React.FC = ({ const { t } = i18nReact.useTranslation(); + const onColumnTitleClicked = (columnClicked: string) => { + if (columnClicked === sortByColumn) { + if (sortOrder === SortOrder.NONE) { + onSortOrderChange(SortOrder.ASC); + } else if (sortOrder === SortOrder.ASC) { + onSortOrderChange(SortOrder.DSC); + } else { + onSortOrderChange(SortOrder.NONE); + } + } else { + onSortByColumnChange(columnClicked); + onSortOrderChange(SortOrder.ASC); + } + }; + const getColumns = file => { const columns: ColumnProps[] = []; for (const [key] of Object.entries(file)) { const column: ColumnProps = { - dataIndex: `${key}`, - title: t(`${key}`.charAt(0).toUpperCase() + `${key}`.slice(1)), + dataIndex: key, + title: ( +
onColumnTitleClicked(key)} + > +
+ {key === 'mtime' ? t('Last Updated') : t(key)} +
+ {key === sortByColumn ? ( + sortOrder === SortOrder.DSC ? ( + + ) : sortOrder === SortOrder.ASC ? ( + + ) : null + ) : null} +
+ ), key: `${key}` }; if (key === 'name') { @@ -81,7 +126,7 @@ const StorageBrowserTable: React.FC = ({ ); } else { - column.width = key === 'lastUpdated' ? '15%' : '10%'; + column.width = key === 'mtime' ? '15%' : '10%'; } columns.push(column); } diff --git a/desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts b/desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts index 32c7be483b..4d49dd2f79 100644 --- a/desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts +++ b/desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts @@ -16,7 +16,7 @@ import { get } from '../../api/utils'; import { CancellablePromise } from '../../api/cancellablePromise'; -import { PathAndFileData } from './types'; +import { PathAndFileData, SortOrder } from './types'; const FILESYSTEMS_API_URL = '/api/v1/storage/filesystems'; const VIEWFILES_API_URl = '/api/v1/storage/view='; @@ -35,14 +35,21 @@ export const fetchFiles = ( pagenum?: number, filter?: string, sortby?: string, - descending?: boolean + sortOrder?: SortOrder ): CancellablePromise => { + let descending = false; + if (sortOrder === SortOrder.ASC) { + descending = false; + } else if (sortOrder === SortOrder.DSC) { + descending = true; + } else { + sortby = ''; + } //If value is undefined default value is assigned. pagesize = pagesize || 10; pagenum = pagenum || 1; filter = filter || ''; sortby = sortby || ''; - descending = descending || false; return get( VIEWFILES_API_URl + filePath + diff --git a/desktop/core/src/desktop/js/reactComponents/FileChooser/types.ts b/desktop/core/src/desktop/js/reactComponents/FileChooser/types.ts index 28a58a2d5d..7ddc58c99e 100644 --- a/desktop/core/src/desktop/js/reactComponents/FileChooser/types.ts +++ b/desktop/core/src/desktop/js/reactComponents/FileChooser/types.ts @@ -50,9 +50,9 @@ export interface StorageBrowserTableData { name: string; size: string; user: string; - groups: string; + group: string; permission: string; - lastUpdated: string; + mtime: string; type: string; path: string; } @@ -79,3 +79,9 @@ export interface PathAndFileData { page: PageStats; pagesize: number; } + +export enum SortOrder { + ASC = 'ascending', + DSC = 'descending', + NONE = 'none' +}