e9dc2a9ebf65e595296fef0014a1170253f985b0
[arvados-workbench2.git] / src / views-components / project-explorer / project-explorer.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { ProjectExplorerItem } from './project-explorer-item';
7 import { Grid, Typography } from '@material-ui/core';
8 import { formatDate, formatFileSize } from '../../common/formatters';
9 import DataExplorer from '../data-explorer/data-explorer';
10 import { DataColumn } from '../../components/data-table/data-column';
11 import { DataTableFilterItem } from '../../components/data-table-filters/data-table-filters';
12 import { ContextMenuAction } from '../../components/context-menu/context-menu';
13 import { DispatchProp, connect } from 'react-redux';
14 import actions from "../../store/data-explorer/data-explorer-action";
15 import { DataColumns } from '../../components/data-table/data-table';
16
17 export const PROJECT_EXPLORER_ID = "projectExplorer";
18 class ProjectExplorer extends React.Component<DispatchProp> {
19     render() {
20         return <DataExplorer
21             id={PROJECT_EXPLORER_ID}
22             contextActions={contextMenuActions}
23             onColumnToggle={this.toggleColumn}
24             onFiltersChange={this.changeFilters}
25             onRowClick={console.log}
26             onSortToggle={this.toggleSort}
27             onSearch={this.search}
28             onContextAction={this.executeAction}
29             onChangePage={this.changePage}
30             onChangeRowsPerPage={this.changeRowsPerPage} />;
31     }
32
33     componentDidMount() {
34         this.props.dispatch(actions.SET_COLUMNS({ id: PROJECT_EXPLORER_ID, columns }));
35     }
36
37     toggleColumn = (toggledColumn: DataColumn<ProjectExplorerItem>) => {
38         this.props.dispatch(actions.TOGGLE_COLUMN({ id: PROJECT_EXPLORER_ID, columnName: toggledColumn.name }));
39     }
40
41     toggleSort = (toggledColumn: DataColumn<ProjectExplorerItem>) => {
42         this.props.dispatch(actions.TOGGLE_SORT({ id: PROJECT_EXPLORER_ID, columnName: toggledColumn.name }));
43     }
44
45     changeFilters = (filters: DataTableFilterItem[], updatedColumn: DataColumn<ProjectExplorerItem>) => {
46         this.props.dispatch(actions.SET_FILTERS({ id: PROJECT_EXPLORER_ID, columnName: updatedColumn.name, filters }));
47     }
48
49     executeAction = (action: ContextMenuAction, item: ProjectExplorerItem) => {
50         alert(`Executing ${action.name} on ${item.name}`);
51     }
52
53     search = (searchValue: string) => {
54         this.props.dispatch(actions.SET_SEARCH_VALUE({ id: PROJECT_EXPLORER_ID, searchValue }));
55     }
56
57     changePage = (page: number) => {
58         this.props.dispatch(actions.SET_PAGE({ id: PROJECT_EXPLORER_ID, page }));
59     }
60
61     changeRowsPerPage = (rowsPerPage: number) => {
62         this.props.dispatch(actions.SET_ROWS_PER_PAGE({ id: PROJECT_EXPLORER_ID, rowsPerPage }));
63     }
64 }
65
66 const renderName = (item: ProjectExplorerItem) =>
67     <Grid
68         container
69         alignItems="center"
70         wrap="nowrap"
71         spacing={16}>
72         <Grid item>
73             {renderIcon(item)}
74         </Grid>
75         <Grid item>
76             <Typography color="primary">
77                 {item.name}
78             </Typography>
79         </Grid>
80     </Grid>;
81
82 const renderIcon = (item: ProjectExplorerItem) => {
83     switch (item.type) {
84         case "arvados#group":
85             return <i className="fas fa-folder fa-lg" />;
86         case "arvados#groupList":
87             return <i className="fas fa-th fa-lg" />;
88         default:
89             return <i />;
90     }
91 };
92
93 const renderDate = (date: string) =>
94     <Typography noWrap>
95         {formatDate(date)}
96     </Typography>;
97
98 const renderFileSize = (fileSize?: number) =>
99     <Typography noWrap>
100         {formatFileSize(fileSize)}
101     </Typography>;
102
103 const renderOwner = (owner: string) =>
104     <Typography noWrap color="primary">
105         {owner}
106     </Typography>;
107
108 const renderType = (type: string) =>
109     <Typography noWrap>
110         {type}
111     </Typography>;
112
113 const renderStatus = (item: ProjectExplorerItem) =>
114     <Typography noWrap align="center">
115         {item.status || "-"}
116     </Typography>;
117
118 const columns: DataColumns<ProjectExplorerItem> = [{
119     name: "Name",
120     selected: true,
121     sortDirection: "asc",
122     render: renderName
123 }, {
124     name: "Status",
125     selected: true,
126     filters: [{
127         name: "In progress",
128         selected: true
129     }, {
130         name: "Complete",
131         selected: true
132     }],
133     render: renderStatus
134 }, {
135     name: "Type",
136     selected: true,
137     filters: [{
138         name: "Collection",
139         selected: true
140     }, {
141         name: "Group",
142         selected: true
143     }],
144     render: item => renderType(item.type)
145 }, {
146     name: "Owner",
147     selected: true,
148     render: item => renderOwner(item.owner)
149 }, {
150     name: "File size",
151     selected: true,
152     sortDirection: "none",
153     render: item => renderFileSize(item.fileSize)
154 }, {
155     name: "Last modified",
156     selected: true,
157     render: item => renderDate(item.lastModified)
158 }];
159
160 const contextMenuActions = [[{
161     icon: "fas fa-users fa-fw",
162     name: "Share"
163 }, {
164     icon: "fas fa-sign-out-alt fa-fw",
165     name: "Move to"
166 }, {
167     icon: "fas fa-star fa-fw",
168     name: "Add to favourite"
169 }, {
170     icon: "fas fa-edit fa-fw",
171     name: "Rename"
172 }, {
173     icon: "fas fa-copy fa-fw",
174     name: "Make a copy"
175 }, {
176     icon: "fas fa-download fa-fw",
177     name: "Download"
178 }], [{
179     icon: "fas fa-trash-alt fa-fw",
180     name: "Remove"
181 }
182 ]];
183
184 export default connect()(ProjectExplorer);