1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { Typography, Grid, Paper, Toolbar } from '@material-ui/core';
7 import IconButton from '@material-ui/core/IconButton';
8 import MoreVertIcon from "@material-ui/icons/MoreVert";
9 import { formatFileSize, formatDate } from '../../common/formatters';
10 import { DataItem } from './data-item';
11 import ContextMenu from "../../components/context-menu/context-menu";
12 import ColumnSelector from "../../components/column-selector/column-selector";
13 import DataTable from "../../components/data-table/data-table";
14 import { mockAnchorFromMouseEvent } from "../../components/popover/helpers";
15 import { DataColumn, toggleSortDirection, resetSortDirection } from "../../components/data-table/data-column";
17 export interface DataExplorerContextActions {
18 onAddToFavourite: (dataIitem: DataItem) => void;
19 onCopy: (dataIitem: DataItem) => void;
20 onDownload: (dataIitem: DataItem) => void;
21 onMoveTo: (dataIitem: DataItem) => void;
22 onRemove: (dataIitem: DataItem) => void;
23 onRename: (dataIitem: DataItem) => void;
24 onShare: (dataIitem: DataItem) => void;
26 interface DataExplorerProps {
28 onItemClick: (item: DataItem) => void;
29 contextActions: DataExplorerContextActions;
32 interface DataExplorerState {
33 columns: Array<DataColumn<DataItem>>;
35 anchorEl?: HTMLElement;
40 class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState> {
41 state: DataExplorerState = {
47 onSortToggle: () => this.toggleSort("Name"),
48 render: item => this.renderName(item)
52 onFiltersChange: console.log,
60 render: item => renderStatus(item.status)
64 onFiltersChange: console.log,
72 render: item => renderType(item.type)
76 render: item => renderOwner(item.owner)
80 render: item => renderFileSize(item.fileSize)
82 name: "Last modified",
84 onSortToggle: () => this.toggleSort("Last modified"),
85 render: item => renderDate(item.lastModified)
90 renderHeader: () => null,
91 render: item => this.renderActions(item)
95 contextMenuActions = [[{
96 icon: "fas fa-users fa-fw",
98 onClick: this.handleContextAction("onShare")
100 icon: "fas fa-sign-out-alt fa-fw",
102 onClick: this.handleContextAction("onMoveTo")
104 icon: "fas fa-star fa-fw",
105 name: "Add to favourite",
106 onClick: this.handleContextAction("onAddToFavourite")
108 icon: "fas fa-edit fa-fw",
110 onClick: this.handleContextAction("onRename")
112 icon: "fas fa-copy fa-fw",
114 onClick: this.handleContextAction("onCopy")
116 icon: "fas fa-download fa-fw",
118 onClick: this.handleContextAction("onDownload")
120 icon: "fas fa-trash-alt fa-fw",
122 onClick: this.handleContextAction("onRemove")
129 {...this.state.contextMenu}
130 actions={this.contextMenuActions}
131 onClose={this.closeContextMenu} />
133 <Grid container justify="flex-end">
135 columns={this.state.columns}
136 onColumnToggle={this.toggleColumn} />
140 columns={this.state.columns}
141 items={this.props.items}
142 onRowContextMenu={this.openItemMenuOnRowClick} />
147 toggleColumn = (column: DataColumn<DataItem>) => {
148 const index = this.state.columns.indexOf(column);
149 const columns = this.state.columns.slice(0);
150 columns.splice(index, 1, { ...column, selected: !column.selected });
151 this.setState({ columns });
154 renderName = (item: DataItem) =>
160 onClick={() => this.props.onItemClick(item)}>
165 <Typography color="primary">
171 renderActions = (item: DataItem) =>
172 <Grid container justify="flex-end">
173 <IconButton onClick={event => this.openItemMenuOnActionsClick(event, item)}>
178 openItemMenuOnRowClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
179 event.preventDefault();
182 anchorEl: mockAnchorFromMouseEvent(event),
188 openItemMenuOnActionsClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
191 anchorEl: event.currentTarget,
197 closeContextMenu = () => {
198 this.setState({ contextMenu: {} });
201 handleContextAction(action: keyof DataExplorerContextActions) {
202 return (item: DataItem) => {
203 this.closeContextMenu();
204 this.props.contextActions[action](item);
208 toggleSort = (columnName: string) => {
210 columns: this.state.columns.map((column, index) =>
211 column.name === columnName ? toggleSortDirection(column) : resetSortDirection(column))
217 const renderIcon = (dataItem: DataItem) => {
218 switch (dataItem.type) {
219 case "arvados#group":
220 return <i className="fas fa-folder fa-lg" />;
221 case "arvados#groupList":
222 return <i className="fas fa-th fa-lg" />;
228 const renderDate = (date: string) =>
233 const renderFileSize = (fileSize?: number) =>
235 {formatFileSize(fileSize)}
238 const renderOwner = (owner: string) =>
239 <Typography noWrap color="primary">
243 const renderType = (type: string) =>
248 const renderStatus = (status?: string) =>
249 <Typography noWrap align="center">
253 export default DataExplorer;