Extend DataColumn and DataTable to handle sorting
[arvados.git] / src / components / data-explorer / data-explorer.tsx
index 026820be2849b11ad4ef5273d22190fd4d7c63a9..ded1b5e39cfdfa2c5e0651f6cc6677a8ee7ca492 100644 (file)
@@ -3,14 +3,15 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { DataTable, DataColumn, ColumnSelector } from "../../components/data-table";
+import { DataTable, DataColumn, ColumnSelector, toggleSortDirection, SortDirection, resetSortDirection } from "../../components/data-table";
 import { Typography, Grid, Paper, Toolbar } from '@material-ui/core';
 import IconButton from '@material-ui/core/IconButton';
 import MoreVertIcon from "@material-ui/icons/MoreVert";
+import TableSortLabel from '@material-ui/core/TableSortLabel';
 import { formatFileSize, formatDate } from '../../common/formatters';
 import { DataItem } from './data-item';
 import { mockAnchorFromMouseEvent } from '../popover/helpers';
-import ContextMenu, { ContextMenuActionGroup } from '../context-menu/context-menu';
+import ContextMenu from '../context-menu/context-menu';
 
 export interface DataExplorerContextActions {
     onAddToFavourite: (dataIitem: DataItem) => void;
@@ -32,47 +33,17 @@ interface DataExplorerState {
     contextMenu: {
         anchorEl?: HTMLElement;
         item?: DataItem;
-        actions: Array<ContextMenuActionGroup<DataItem>>;
     };
 }
 
 class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState> {
     state: DataExplorerState = {
-        contextMenu: {
-            actions: [[{
-                icon: "fas fa-users fa-fw",
-                name: "Share",
-                onClick: this.handleContextAction("onShare")
-            }, {
-                icon: "fas fa-sign-out-alt fa-fw",
-                name: "Move to",
-                onClick: this.handleContextAction("onMoveTo")
-            }, {
-                icon: "fas fa-star fa-fw",
-                name: "Add to favourite",
-                onClick: this.handleContextAction("onAddToFavourite")
-            }, {
-                icon: "fas fa-edit fa-fw",
-                name: "Rename",
-                onClick: this.handleContextAction("onRename")
-            }, {
-                icon: "fas fa-copy fa-fw",
-                name: "Make a copy",
-                onClick: this.handleContextAction("onCopy")
-            }, {
-                icon: "fas fa-download fa-fw",
-                name: "Download",
-                onClick: this.handleContextAction("onDownload")
-            }], [{
-                icon: "fas fa-trash-alt fa-fw",
-                name: "Remove",
-                onClick: this.handleContextAction("onRemove")
-            }
-            ]]
-        },
+        contextMenu: {},
         columns: [{
             name: "Name",
             selected: true,
+            sortDirection: "asc",
+            onSortToggle: () => this.toggleSort("Name"),
             render: item => this.renderName(item)
         }, {
             name: "Status",
@@ -93,6 +64,7 @@ class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState>
         }, {
             name: "Last modified",
             selected: true,
+            onSortToggle: () => this.toggleSort("Last modified"),
             render: item => renderDate(item.lastModified)
         }, {
             name: "Actions",
@@ -103,10 +75,42 @@ class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState>
         }]
     };
 
+    contextMenuActions = [[{
+        icon: "fas fa-users fa-fw",
+        name: "Share",
+        onClick: this.handleContextAction("onShare")
+    }, {
+        icon: "fas fa-sign-out-alt fa-fw",
+        name: "Move to",
+        onClick: this.handleContextAction("onMoveTo")
+    }, {
+        icon: "fas fa-star fa-fw",
+        name: "Add to favourite",
+        onClick: this.handleContextAction("onAddToFavourite")
+    }, {
+        icon: "fas fa-edit fa-fw",
+        name: "Rename",
+        onClick: this.handleContextAction("onRename")
+    }, {
+        icon: "fas fa-copy fa-fw",
+        name: "Make a copy",
+        onClick: this.handleContextAction("onCopy")
+    }, {
+        icon: "fas fa-download fa-fw",
+        name: "Download",
+        onClick: this.handleContextAction("onDownload")
+    }], [{
+        icon: "fas fa-trash-alt fa-fw",
+        name: "Remove",
+        onClick: this.handleContextAction("onRemove")
+    }
+    ]];
+
     render() {
         return <Paper>
             <ContextMenu
                 {...this.state.contextMenu}
+                actions={this.contextMenuActions}
                 onClose={this.closeContextMenu} />
             <Toolbar>
                 <Grid container justify="flex-end">
@@ -156,25 +160,25 @@ class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState>
 
     openItemMenuOnRowClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
         event.preventDefault();
-        this.setContextMenuState({
-            anchorEl: mockAnchorFromMouseEvent(event),
-            item
+        this.setState({
+            contextMenu: {
+                anchorEl: mockAnchorFromMouseEvent(event),
+                item
+            }
         });
     }
 
     openItemMenuOnActionsClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
-        this.setContextMenuState({
-            anchorEl: event.currentTarget,
-            item
+        this.setState({
+            contextMenu: {
+                anchorEl: event.currentTarget,
+                item
+            }
         });
     }
 
     closeContextMenu = () => {
-        this.setContextMenuState({});
-    }
-
-    setContextMenuState = (contextMenu: { anchorEl?: HTMLElement; item?: DataItem; }) => {
-        this.setState(prev => ({ contextMenu: { ...contextMenu, actions: prev.contextMenu.actions } }));
+        this.setState({ contextMenu: {} });
     }
 
     handleContextAction(action: keyof DataExplorerContextActions) {
@@ -184,6 +188,13 @@ class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState>
         };
     }
 
+    toggleSort = (columnName: string) => {
+        this.setState({
+            columns: this.state.columns.map((column, index) =>
+                column.name === columnName ? toggleSortDirection(column) : resetSortDirection(column))
+        });
+    }
+
 }
 
 const renderIcon = (dataItem: DataItem) => {