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 { DataColumns } from "../../components/data-table/data-table";
12 import ContextMenu from "../../components/context-menu/context-menu";
13 import ColumnSelector from "../../components/column-selector/column-selector";
14 import DataTable from "../../components/data-table/data-table";
15 import { mockAnchorFromMouseEvent } from "../../components/popover/helpers";
16 import { DataColumn } from "../../components/data-table/data-column";
18 export interface DataExplorerContextActions {
19 onAddToFavourite: (dataIitem: DataItem) => void;
20 onCopy: (dataIitem: DataItem) => void;
21 onDownload: (dataIitem: DataItem) => void;
22 onMoveTo: (dataIitem: DataItem) => void;
23 onRemove: (dataIitem: DataItem) => void;
24 onRename: (dataIitem: DataItem) => void;
25 onShare: (dataIitem: DataItem) => void;
27 interface DataExplorerProps {
29 onItemClick: (item: DataItem) => void;
30 contextActions: DataExplorerContextActions;
33 interface DataExplorerState {
34 columns: DataColumns<DataItem>;
36 anchorEl?: HTMLElement;
41 class DataExplorer extends React.Component<DataExplorerProps, DataExplorerState> {
42 state: DataExplorerState = {
47 render: item => this.renderName(item)
51 render: item => renderStatus(item.status)
55 render: item => renderType(item.type)
59 render: item => renderOwner(item.owner)
63 render: item => renderFileSize(item.fileSize)
65 name: "Last modified",
67 render: item => renderDate(item.lastModified)
72 renderHeader: () => null,
73 render: item => this.renderActions(item)
77 contextMenuActions = [[{
78 icon: "fas fa-users fa-fw",
80 onClick: this.handleContextAction("onShare")
82 icon: "fas fa-sign-out-alt fa-fw",
84 onClick: this.handleContextAction("onMoveTo")
86 icon: "fas fa-star fa-fw",
87 name: "Add to favourite",
88 onClick: this.handleContextAction("onAddToFavourite")
90 icon: "fas fa-edit fa-fw",
92 onClick: this.handleContextAction("onRename")
94 icon: "fas fa-copy fa-fw",
96 onClick: this.handleContextAction("onCopy")
98 icon: "fas fa-download fa-fw",
100 onClick: this.handleContextAction("onDownload")
102 icon: "fas fa-trash-alt fa-fw",
104 onClick: this.handleContextAction("onRemove")
111 {...this.state.contextMenu}
112 actions={this.contextMenuActions}
113 onClose={this.closeContextMenu} />
115 <Grid container justify="flex-end">
117 columns={this.state.columns}
118 onColumnToggle={this.toggleColumn} />
122 columns={this.state.columns}
123 items={this.props.items}
124 onRowContextMenu={this.openItemMenuOnRowClick} />
129 toggleColumn = (column: DataColumn<DataItem>) => {
130 const index = this.state.columns.indexOf(column);
131 const columns = this.state.columns.slice(0);
132 columns.splice(index, 1, { ...column, selected: !column.selected });
133 this.setState({ columns });
136 renderName = (item: DataItem) =>
142 onClick={() => this.props.onItemClick(item)}>
147 <Typography color="primary">
153 renderActions = (item: DataItem) =>
154 <Grid container justify="flex-end">
155 <IconButton onClick={event => this.openItemMenuOnActionsClick(event, item)}>
160 openItemMenuOnRowClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
161 event.preventDefault();
164 anchorEl: mockAnchorFromMouseEvent(event),
170 openItemMenuOnActionsClick = (event: React.MouseEvent<HTMLElement>, item: DataItem) => {
173 anchorEl: event.currentTarget,
179 closeContextMenu = () => {
180 this.setState({ contextMenu: {} });
183 handleContextAction(action: keyof DataExplorerContextActions) {
184 return (item: DataItem) => {
185 this.closeContextMenu();
186 this.props.contextActions[action](item);
192 const renderIcon = (dataItem: DataItem) => {
193 switch (dataItem.type) {
194 case "arvados#group":
195 return <i className="fas fa-folder fa-lg" />;
196 case "arvados#groupList":
197 return <i className="fas fa-th fa-lg" />;
203 const renderDate = (date: string) =>
208 const renderFileSize = (fileSize?: number) =>
210 {formatFileSize(fileSize)}
213 const renderOwner = (owner: string) =>
214 <Typography noWrap color="primary">
218 const renderType = (type: string) =>
223 const renderStatus = (status?: string) =>
224 <Typography noWrap align="center">
228 export default DataExplorer;