1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { DataTable, DataColumn, ColumnSelector } from "../../components/data-table";
7 import { Typography, Grid, Paper, Toolbar } from '@material-ui/core';
8 import IconButton from '@material-ui/core/IconButton';
9 import MoreVertIcon from "@material-ui/icons/MoreVert";
10 import { formatFileSize, formatDate } from '../../common/formatters';
11 import { DataItem } from './data-item';
12 import { mockAnchorFromMouseEvent } from '../popover/helpers';
13 import ContextMenu from '../context-menu/context-menu';
15 export interface DataExplorerContextActions {
16 onAddToFavourite: (dataIitem: DataItem) => void;
17 onCopy: (dataIitem: DataItem) => void;
18 onDownload: (dataIitem: DataItem) => void;
19 onMoveTo: (dataIitem: DataItem) => void;
20 onRemove: (dataIitem: DataItem) => void;
21 onRename: (dataIitem: DataItem) => void;
22 onShare: (dataIitem: DataItem) => void;
24 interface DataExplorerProps {
26 onItemClick: (item: DataItem) => void;
27 contextActions: DataExplorerContextActions;
30 interface DataExplorerState {
31 columns: Array<DataColumn<DataItem>>;
33 anchorEl?: HTMLElement;
38 class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState> {
39 state: DataExplorerState = {
44 render: item => this.renderName(item)
48 render: item => renderStatus(item.status)
52 render: item => renderType(item.type)
56 render: item => renderOwner(item.owner)
60 render: item => renderFileSize(item.fileSize)
62 name: "Last modified",
64 render: item => renderDate(item.lastModified)
69 renderHeader: () => null,
70 render: item => this.renderActions(item)
74 contextMenuActions = [[{
75 icon: "fas fa-users fa-fw",
77 onClick: this.handleContextAction("onShare")
79 icon: "fas fa-sign-out-alt fa-fw",
81 onClick: this.handleContextAction("onMoveTo")
83 icon: "fas fa-star fa-fw",
84 name: "Add to favourite",
85 onClick: this.handleContextAction("onAddToFavourite")
87 icon: "fas fa-edit fa-fw",
89 onClick: this.handleContextAction("onRename")
91 icon: "fas fa-copy fa-fw",
93 onClick: this.handleContextAction("onCopy")
95 icon: "fas fa-download fa-fw",
97 onClick: this.handleContextAction("onDownload")
99 icon: "fas fa-trash-alt fa-fw",
101 onClick: this.handleContextAction("onRemove")
108 {...this.state.contextMenu}
109 actions={this.contextMenuActions}
110 onClose={this.closeContextMenu} />
112 <Grid container justify="flex-end">
114 columns={this.state.columns}
115 onColumnToggle={this.toggleColumn} />
119 columns={this.state.columns}
120 items={this.props.items}
121 onRowContextMenu={this.openItemMenuOnRowClick} />
126 toggleColumn = (column: DataColumn<DataItem>) => {
127 const index = this.state.columns.indexOf(column);
128 const columns = this.state.columns.slice(0);
129 columns.splice(index, 1, { ...column, selected: !column.selected });
130 this.setState({ columns });
133 renderName = (item: DataItem) =>
139 onClick={() => this.props.onItemClick(item)}>
144 <Typography color="primary">
150 renderActions = (item: DataItem) =>
151 <Grid container justify="flex-end">
152 <IconButton onClick={event => this.openItemMenuOnActionsClick(event, item)}>
157 openItemMenuOnRowClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
158 event.preventDefault();
161 anchorEl: mockAnchorFromMouseEvent(event),
167 openItemMenuOnActionsClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
170 anchorEl: event.currentTarget,
176 closeContextMenu = () => {
177 this.setState({ contextMenu: {} });
180 handleContextAction(action: keyof DataExplorerContextActions) {
181 return (item: DataItem) => {
182 this.closeContextMenu();
183 this.props.contextActions[action](item);
189 const renderIcon = (dataItem: DataItem) => {
190 switch (dataItem.type) {
191 case "arvados#group":
192 return <i className="fas fa-folder fa-lg" />;
193 case "arvados#groupList":
194 return <i className="fas fa-th fa-lg" />;
200 const renderDate = (date: string) =>
205 const renderFileSize = (fileSize?: number) =>
207 {formatFileSize(fileSize)}
210 const renderOwner = (owner: string) =>
211 <Typography noWrap color="primary">
215 const renderType = (type: string) =>
220 const renderStatus = (status?: string) =>
221 <Typography noWrap align="center">
225 export default DataExplorer;