Эх сурвалжийг харах

[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
Nidhi Bhat G 1 жил өмнө
parent
commit
200c9bf47c

+ 14 - 5
desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTabContents/StorageBrowserTabContent.tsx

@@ -37,7 +37,8 @@ import { fetchFiles } from '../../../../reactComponents/FileChooser/api';
 import {
 import {
   PathAndFileData,
   PathAndFileData,
   StorageBrowserTableData,
   StorageBrowserTableData,
-  PageStats
+  PageStats,
+  SortOrder
 } from '../../../../reactComponents/FileChooser/types';
 } from '../../../../reactComponents/FileChooser/types';
 
 
 import './StorageBrowserTabContent.scss';
 import './StorageBrowserTabContent.scss';
@@ -62,6 +63,10 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
   const [pageStats, setPageStats] = useState<PageStats>();
   const [pageStats, setPageStats] = useState<PageStats>();
   const [pageSize, setPageSize] = useState<number>();
   const [pageSize, setPageSize] = useState<number>();
   const [pageNumber, setPageNumber] = useState<number>(1);
   const [pageNumber, setPageNumber] = useState<number>(1);
+  const [sortByColumn, setSortByColumn] = useState<string>('');
+  const [sortOrder, setSortOrder] = useState<SortOrder>(SortOrder.NONE);
+  //TODO: Add filter functionality
+  const [filterData, setFilterData] = useState<string>('');
 
 
   const { t } = i18nReact.useTranslation();
   const { t } = i18nReact.useTranslation();
 
 
@@ -132,16 +137,16 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
 
 
   useEffect(() => {
   useEffect(() => {
     setloadingFiles(true);
     setloadingFiles(true);
-    fetchFiles(filePath, pageSize, pageNumber)
+    fetchFiles(filePath, pageSize, pageNumber, filterData, sortByColumn, sortOrder)
       .then(responseFilesData => {
       .then(responseFilesData => {
         setFilesData(responseFilesData);
         setFilesData(responseFilesData);
         const tableData: StorageBrowserTableData[] = responseFilesData.files.map(file => ({
         const tableData: StorageBrowserTableData[] = responseFilesData.files.map(file => ({
           name: file.name,
           name: file.name,
           size: file.humansize,
           size: file.humansize,
           user: file.stats.user,
           user: file.stats.user,
-          groups: file.stats.group,
+          group: file.stats.group,
           permission: file.rwx,
           permission: file.rwx,
-          lastUpdated: file.mtime,
+          mtime: file.mtime,
           type: file.type,
           type: file.type,
           path: file.path
           path: file.path
         }));
         }));
@@ -156,7 +161,7 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
       .finally(() => {
       .finally(() => {
         setloadingFiles(false);
         setloadingFiles(false);
       });
       });
-  }, [filePath, pageSize, pageNumber]);
+  }, [filePath, pageSize, pageNumber, sortByColumn, sortOrder]);
 
 
   return (
   return (
     <Spin spinning={loadingFiles}>
     <Spin spinning={loadingFiles}>
@@ -217,6 +222,10 @@ const StorageBrowserTabContent: React.FC<StorageBrowserTabContentProps> = ({
           onFilepathChange={setFilePath}
           onFilepathChange={setFilePath}
           onPageSizeChange={setPageSize}
           onPageSizeChange={setPageSize}
           onPageNumberChange={setPageNumber}
           onPageNumberChange={setPageNumber}
+          onSortByColumnChange={setSortByColumn}
+          onSortOrderChange={setSortOrder}
+          sortByColumn={sortByColumn}
+          sortOrder={sortOrder}
         ></StorageBrowserTable>
         ></StorageBrowserTable>
       </div>
       </div>
     </Spin>
     </Spin>

+ 12 - 0
desktop/core/src/desktop/js/apps/storageBrowser/StorageBrowserPage/StorageBrowserTable/StorageBrowserTable.scss

@@ -37,6 +37,10 @@ $cell-height: 40px;
   th.ant-table-cell {
   th.ant-table-cell {
     text-align: left;
     text-align: left;
   }
   }
+
+  table {
+    width: 100%;
+  }
 }
 }
 
 
 .hue-storage-browser__table-row {
 .hue-storage-browser__table-row {
@@ -55,3 +59,11 @@ $cell-height: 40px;
 .hue-storage-browser__table-cell-name {
 .hue-storage-browser__table-cell-name {
   color: vars.$fluidx-blue-700;
   color: vars.$fluidx-blue-700;
 }
 }
+
+.hue-storage-browser__table-column-header {
+  display: flex;
+}
+
+.hue-storage-browser__table-column-title {
+  text-transform: capitalize;
+}

+ 49 - 4
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 Table from 'cuix/dist/components/Table';
 import { ColumnProps } from 'antd/lib/table';
 import { ColumnProps } from 'antd/lib/table';
 import FolderIcon from '@cloudera/cuix-core/icons/react/ProjectIcon';
 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)
 //TODO: Use cuix icon (Currently fileIcon does not exist in cuix)
 import { FileOutlined } from '@ant-design/icons';
 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 Pagination from '../../../../reactComponents/Pagination/Pagination';
 import './StorageBrowserTable.scss';
 import './StorageBrowserTable.scss';
 import Tooltip from 'antd/es/tooltip';
 import Tooltip from 'antd/es/tooltip';
@@ -33,8 +39,12 @@ interface StorageBrowserTableProps {
   onFilepathChange: (path: string) => void;
   onFilepathChange: (path: string) => void;
   onPageNumberChange: (pageNumber: number) => void;
   onPageNumberChange: (pageNumber: number) => void;
   onPageSizeChange: (pageSize: number) => void;
   onPageSizeChange: (pageSize: number) => void;
+  onSortByColumnChange: (sortByColumn: string) => void;
+  onSortOrderChange: (sortOrder: SortOrder) => void;
   pageSize: number;
   pageSize: number;
   pageStats: PageStats;
   pageStats: PageStats;
+  sortByColumn: string;
+  sortOrder: SortOrder;
   rowClassName?: string;
   rowClassName?: string;
   testId?: string;
   testId?: string;
 }
 }
@@ -51,6 +61,10 @@ const StorageBrowserTable: React.FC<StorageBrowserTableProps> = ({
   onFilepathChange,
   onFilepathChange,
   onPageNumberChange,
   onPageNumberChange,
   onPageSizeChange,
   onPageSizeChange,
+  onSortByColumnChange,
+  onSortOrderChange,
+  sortByColumn,
+  sortOrder,
   pageSize,
   pageSize,
   pageStats,
   pageStats,
   rowClassName,
   rowClassName,
@@ -61,12 +75,43 @@ const StorageBrowserTable: React.FC<StorageBrowserTableProps> = ({
 
 
   const { t } = i18nReact.useTranslation();
   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 getColumns = file => {
     const columns: ColumnProps<unknown>[] = [];
     const columns: ColumnProps<unknown>[] = [];
     for (const [key] of Object.entries(file)) {
     for (const [key] of Object.entries(file)) {
       const column: ColumnProps<unknown> = {
       const column: ColumnProps<unknown> = {
-        dataIndex: `${key}`,
-        title: t(`${key}`.charAt(0).toUpperCase() + `${key}`.slice(1)),
+        dataIndex: key,
+        title: (
+          <div
+            className="hue-storage-browser__table-column-header"
+            onClick={() => onColumnTitleClicked(key)}
+          >
+            <div className="hue-storage-browser__table-column-title">
+              {key === 'mtime' ? t('Last Updated') : t(key)}
+            </div>
+            {key === sortByColumn ? (
+              sortOrder === SortOrder.DSC ? (
+                <SortDescending />
+              ) : sortOrder === SortOrder.ASC ? (
+                <SortAscending />
+              ) : null
+            ) : null}
+          </div>
+        ),
         key: `${key}`
         key: `${key}`
       };
       };
       if (key === 'name') {
       if (key === 'name') {
@@ -81,7 +126,7 @@ const StorageBrowserTable: React.FC<StorageBrowserTableProps> = ({
           </Tooltip>
           </Tooltip>
         );
         );
       } else {
       } else {
-        column.width = key === 'lastUpdated' ? '15%' : '10%';
+        column.width = key === 'mtime' ? '15%' : '10%';
       }
       }
       columns.push(column);
       columns.push(column);
     }
     }

+ 10 - 3
desktop/core/src/desktop/js/reactComponents/FileChooser/api.ts

@@ -16,7 +16,7 @@
 
 
 import { get } from '../../api/utils';
 import { get } from '../../api/utils';
 import { CancellablePromise } from '../../api/cancellablePromise';
 import { CancellablePromise } from '../../api/cancellablePromise';
-import { PathAndFileData } from './types';
+import { PathAndFileData, SortOrder } from './types';
 
 
 const FILESYSTEMS_API_URL = '/api/v1/storage/filesystems';
 const FILESYSTEMS_API_URL = '/api/v1/storage/filesystems';
 const VIEWFILES_API_URl = '/api/v1/storage/view=';
 const VIEWFILES_API_URl = '/api/v1/storage/view=';
@@ -35,14 +35,21 @@ export const fetchFiles = (
   pagenum?: number,
   pagenum?: number,
   filter?: string,
   filter?: string,
   sortby?: string,
   sortby?: string,
-  descending?: boolean
+  sortOrder?: SortOrder
 ): CancellablePromise<PathAndFileData> => {
 ): CancellablePromise<PathAndFileData> => {
+  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.
   //If value is undefined default value is assigned.
   pagesize = pagesize || 10;
   pagesize = pagesize || 10;
   pagenum = pagenum || 1;
   pagenum = pagenum || 1;
   filter = filter || '';
   filter = filter || '';
   sortby = sortby || '';
   sortby = sortby || '';
-  descending = descending || false;
   return get(
   return get(
     VIEWFILES_API_URl +
     VIEWFILES_API_URl +
       filePath +
       filePath +

+ 8 - 2
desktop/core/src/desktop/js/reactComponents/FileChooser/types.ts

@@ -50,9 +50,9 @@ export interface StorageBrowserTableData {
   name: string;
   name: string;
   size: string;
   size: string;
   user: string;
   user: string;
-  groups: string;
+  group: string;
   permission: string;
   permission: string;
-  lastUpdated: string;
+  mtime: string;
   type: string;
   type: string;
   path: string;
   path: string;
 }
 }
@@ -79,3 +79,9 @@ export interface PathAndFileData {
   page: PageStats;
   page: PageStats;
   pagesize: number;
   pagesize: number;
 }
 }
+
+export enum SortOrder {
+  ASC = 'ascending',
+  DSC = 'descending',
+  NONE = 'none'
+}