Handle data explorer actions in data explorer container
[arvados-workbench2.git] / src / views / project-panel / project-panel.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 { ProjectPanelItem } from './project-panel-item';
7 import { Grid, Typography, Button, Toolbar, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
8 import { formatDate, formatFileSize } from '../../common/formatters';
9 import DataExplorer from "../../views-components/data-explorer/data-explorer";
10 import { ContextMenuAction } from '../../components/context-menu/context-menu';
11 import { DispatchProp, connect } from 'react-redux';
12 import actions from "../../store/data-explorer/data-explorer-action";
13 import { DataColumns } from '../../components/data-table/data-table';
14 import { ResourceKind } from "../../models/resource";
15 import { RouteComponentProps } from 'react-router';
16 import { RootState } from '../../store/store';
17
18 export const PROJECT_PANEL_ID = "projectPanel";
19
20 type ProjectPanelProps = {
21     currentItemId: string,
22     onItemClick: (item: ProjectPanelItem) => void,
23     onItemRouteChange: (itemId: string) => void
24 }
25     & DispatchProp
26     & WithStyles<CssRules>
27     & RouteComponentProps<{ id: string }>;
28 class ProjectPanel extends React.Component<ProjectPanelProps> {
29     render() {
30         return <div>
31             <div className={this.props.classes.toolbar}>
32                 <Button color="primary" variant="raised" className={this.props.classes.button}>
33                     Create a collection
34                 </Button>
35                 <Button color="primary" variant="raised" className={this.props.classes.button}>
36                     Run a process
37                 </Button>
38                 <Button color="primary" variant="raised" className={this.props.classes.button}>
39                     Create a project
40                 </Button>
41             </div>
42             <DataExplorer
43                 id={PROJECT_PANEL_ID}
44                 contextActions={contextMenuActions}
45                 onRowClick={this.props.onItemClick}
46                 onContextAction={this.executeAction} />;
47         </div>;
48     }
49
50     componentWillReceiveProps({ match, currentItemId }: ProjectPanelProps) {
51         if (match.params.id !== currentItemId) {
52             this.props.onItemRouteChange(match.params.id);
53         }
54     }
55
56     executeAction = (action: ContextMenuAction, item: ProjectPanelItem) => {
57         alert(`Executing ${action.name} on ${item.name}`);
58     }
59
60 }
61
62 type CssRules = "toolbar" | "button";
63
64 const styles: StyleRulesCallback<CssRules> = theme => ({
65     toolbar: {
66         paddingBottom: theme.spacing.unit * 3,
67         textAlign: "right"
68     },
69     button: {
70         marginLeft: theme.spacing.unit
71     }
72 });
73
74 const renderName = (item: ProjectPanelItem) =>
75     <Grid
76         container
77         alignItems="center"
78         wrap="nowrap"
79         spacing={16}>
80         <Grid item>
81             {renderIcon(item)}
82         </Grid>
83         <Grid item>
84             <Typography color="primary">
85                 {item.name}
86             </Typography>
87         </Grid>
88     </Grid>;
89
90
91 const renderIcon = (item: ProjectPanelItem) => {
92     switch (item.kind) {
93         case ResourceKind.PROJECT:
94             return <i className="fas fa-folder fa-lg" />;
95         case ResourceKind.COLLECTION:
96             return <i className="fas fa-th fa-lg" />;
97         default:
98             return <i />;
99     }
100 };
101
102 const renderDate = (date: string) =>
103     <Typography noWrap>
104         {formatDate(date)}
105     </Typography>;
106
107 const renderFileSize = (fileSize?: number) =>
108     <Typography noWrap>
109         {formatFileSize(fileSize)}
110     </Typography>;
111
112 const renderOwner = (owner: string) =>
113     <Typography noWrap color="primary">
114         {owner}
115     </Typography>;
116
117 const renderType = (type: string) =>
118     <Typography noWrap>
119         {type}
120     </Typography>;
121
122 const renderStatus = (item: ProjectPanelItem) =>
123     <Typography noWrap align="center">
124         {item.status || "-"}
125     </Typography>;
126
127 export const columns: DataColumns<ProjectPanelItem> = [{
128     name: "Name",
129     selected: true,
130     sortDirection: "desc",
131     render: renderName,
132     width: "450px"
133 }, {
134     name: "Status",
135     selected: true,
136     render: renderStatus,
137     width: "75px"
138 }, {
139     name: "Type",
140     selected: true,
141     filters: [{
142         name: "Collection",
143         selected: true
144     }, {
145         name: "Project",
146         selected: true
147     }],
148     render: item => renderType(item.kind),
149     width: "125px"
150 }, {
151     name: "Owner",
152     selected: true,
153     render: item => renderOwner(item.owner),
154     width: "200px"
155 }, {
156     name: "File size",
157     selected: true,
158     render: item => renderFileSize(item.fileSize),
159     width: "50px"
160 }, {
161     name: "Last modified",
162     selected: true,
163     sortDirection: "none",
164     render: item => renderDate(item.lastModified),
165     width: "150px"
166 }];
167
168 const contextMenuActions = [[{
169     icon: "fas fa-users fa-fw",
170     name: "Share"
171 }, {
172     icon: "fas fa-sign-out-alt fa-fw",
173     name: "Move to"
174 }, {
175     icon: "fas fa-star fa-fw",
176     name: "Add to favourite"
177 }, {
178     icon: "fas fa-edit fa-fw",
179     name: "Rename"
180 }, {
181     icon: "fas fa-copy fa-fw",
182     name: "Make a copy"
183 }, {
184     icon: "fas fa-download fa-fw",
185     name: "Download"
186 }], [{
187     icon: "fas fa-trash-alt fa-fw",
188     name: "Remove"
189 }
190 ]];
191
192 export default withStyles(styles)(
193     connect((state: RootState) => ({ currentItemId: state.projects.currentItemId }))(
194         ProjectPanel));