19675: Merge branch '19675-instance-types-panel' from arvados-workbench2.git
[arvados.git] / services / workbench2 / src / views / shared-with-me-panel / shared-with-me-panel.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
7 import { DataExplorer } from "views-components/data-explorer/data-explorer";
8 import { connect, DispatchProp } from 'react-redux';
9 import { RootState } from 'store/store';
10 import { ArvadosTheme } from 'common/custom-theme';
11 import { ShareMeIcon } from 'components/icon/icon';
12 import { ResourcesState, getResource } from 'store/resources/resources';
13 import { ResourceKind } from 'models/resource';
14 import { navigateTo } from "store/navigation/navigation-action";
15 import { loadDetailsPanel } from "store/details-panel/details-panel-action";
16 import { SHARED_WITH_ME_PANEL_ID } from 'store/shared-with-me-panel/shared-with-me-panel-actions';
17 import {
18     openContextMenu,
19     resourceUuidToContextMenuKind
20 } from 'store/context-menu/context-menu-actions';
21 import {
22     ResourceName,
23     ProcessStatus as ResourceStatus,
24     ResourceType,
25     ResourceOwnerWithNameLink,
26     ResourcePortableDataHash,
27     ResourceFileSize,
28     ResourceFileCount,
29     ResourceUUID,
30     ResourceContainerUuid,
31     ContainerRunTime,
32     ResourceOutputUuid,
33     ResourceLogUuid,
34     ResourceParentProcess,
35     ResourceModifiedByUserUuid,
36     ResourceVersion,
37     ResourceCreatedAtDate,
38     ResourceLastModifiedDate,
39     ResourceTrashDate,
40     ResourceDeleteDate,
41 } from 'views-components/data-explorer/renderers';
42 import { DataTableFilterItem } from 'components/data-table-filters/data-table-filters';
43 import { GroupContentsResource } from 'services/groups-service/groups-service';
44 import { DataColumns } from 'components/data-table/data-table';
45 import { ContainerRequestState } from 'models/container-request';
46 import { ProjectResource } from 'models/project';
47 import { createTree } from 'models/tree';
48 import { SortDirection } from 'components/data-table/data-column';
49 import { getInitialResourceTypeFilters, getInitialProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters';
50
51 type CssRules = "toolbar" | "button" | "root";
52
53 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
54     toolbar: {
55         paddingBottom: theme.spacing.unit * 3,
56         textAlign: "right"
57     },
58     button: {
59         marginLeft: theme.spacing.unit
60     },
61     root: {
62         width: '100%',
63     },
64 });
65
66 export enum SharedWithMePanelColumnNames {
67     NAME = 'Name',
68     STATUS = 'Status',
69     TYPE = 'Type',
70     OWNER = 'Owner',
71     PORTABLE_DATA_HASH = 'Portable Data Hash',
72     FILE_SIZE = 'File Size',
73     FILE_COUNT = 'File Count',
74     UUID = 'UUID',
75     CONTAINER_UUID = 'Container UUID',
76     RUNTIME = 'Runtime',
77     OUTPUT_UUID = 'Output UUID',
78     LOG_UUID = 'Log UUID',
79     PARENT_PROCESS = 'Parent Process UUID',
80     MODIFIED_BY_USER_UUID = 'Modified by User UUID',
81     VERSION = 'Version',
82     CREATED_AT = 'Date Created',
83     LAST_MODIFIED = 'Last Modified',
84     TRASH_AT = 'Trash at',
85     DELETE_AT = 'Delete at',
86 }
87
88 export interface ProjectPanelFilter extends DataTableFilterItem {
89     type: ResourceKind | ContainerRequestState;
90 }
91
92 export const sharedWithMePanelColumns: DataColumns<string, ProjectResource> = [
93     {
94         name: SharedWithMePanelColumnNames.NAME,
95         selected: true,
96         configurable: true,
97         sort: { direction: SortDirection.NONE, field: 'name' },
98         filters: createTree(),
99         render: (uuid) => <ResourceName uuid={uuid} />,
100     },
101     {
102         name: SharedWithMePanelColumnNames.STATUS,
103         selected: true,
104         configurable: true,
105         mutuallyExclusiveFilters: true,
106         filters: getInitialProcessStatusFilters(),
107         render: (uuid) => <ResourceStatus uuid={uuid} />,
108     },
109     {
110         name: SharedWithMePanelColumnNames.TYPE,
111         selected: true,
112         configurable: true,
113         filters: getInitialResourceTypeFilters(),
114         render: (uuid) => <ResourceType uuid={uuid} />,
115     },
116     {
117         name: SharedWithMePanelColumnNames.OWNER,
118         selected: true,
119         configurable: true,
120         filters: createTree(),
121         render: (uuid) => <ResourceOwnerWithNameLink uuid={uuid} />,
122     },
123     {
124         name: SharedWithMePanelColumnNames.PORTABLE_DATA_HASH,
125         selected: false,
126         configurable: true,
127         filters: createTree(),
128         render: (uuid) => <ResourcePortableDataHash uuid={uuid} />,
129     },
130     {
131         name: SharedWithMePanelColumnNames.FILE_SIZE,
132         selected: true,
133         configurable: true,
134         filters: createTree(),
135         render: (uuid) => <ResourceFileSize uuid={uuid} />,
136     },
137     {
138         name: SharedWithMePanelColumnNames.FILE_COUNT,
139         selected: false,
140         configurable: true,
141         filters: createTree(),
142         render: (uuid) => <ResourceFileCount uuid={uuid} />,
143     },
144     {
145         name: SharedWithMePanelColumnNames.UUID,
146         selected: false,
147         configurable: true,
148         filters: createTree(),
149         render: (uuid) => <ResourceUUID uuid={uuid} />,
150     },
151     {
152         name: SharedWithMePanelColumnNames.CONTAINER_UUID,
153         selected: false,
154         configurable: true,
155         filters: createTree(),
156         render: (uuid) => <ResourceContainerUuid uuid={uuid} />,
157     },
158     {
159         name: SharedWithMePanelColumnNames.RUNTIME,
160         selected: false,
161         configurable: true,
162         filters: createTree(),
163         render: (uuid) => <ContainerRunTime uuid={uuid} />,
164     },
165     {
166         name: SharedWithMePanelColumnNames.OUTPUT_UUID,
167         selected: false,
168         configurable: true,
169         filters: createTree(),
170         render: (uuid) => <ResourceOutputUuid uuid={uuid} />,
171     },
172     {
173         name: SharedWithMePanelColumnNames.LOG_UUID,
174         selected: false,
175         configurable: true,
176         filters: createTree(),
177         render: (uuid) => <ResourceLogUuid uuid={uuid} />,
178     },
179     {
180         name: SharedWithMePanelColumnNames.PARENT_PROCESS,
181         selected: false,
182         configurable: true,
183         filters: createTree(),
184         render: (uuid) => <ResourceParentProcess uuid={uuid} />,
185     },
186     {
187         name: SharedWithMePanelColumnNames.MODIFIED_BY_USER_UUID,
188         selected: false,
189         configurable: true,
190         filters: createTree(),
191         render: (uuid) => <ResourceModifiedByUserUuid uuid={uuid} />,
192     },
193     {
194         name: SharedWithMePanelColumnNames.VERSION,
195         selected: false,
196         configurable: true,
197         filters: createTree(),
198         render: (uuid) => <ResourceVersion uuid={uuid} />,
199     },
200     {
201         name: SharedWithMePanelColumnNames.CREATED_AT,
202         selected: false,
203         configurable: true,
204         sort: { direction: SortDirection.NONE, field: 'createdAt' },
205         filters: createTree(),
206         render: (uuid) => <ResourceCreatedAtDate uuid={uuid} />,
207     },
208     {
209         name: SharedWithMePanelColumnNames.LAST_MODIFIED,
210         selected: true,
211         configurable: true,
212         sort: { direction: SortDirection.DESC, field: 'modifiedAt' },
213         filters: createTree(),
214         render: (uuid) => <ResourceLastModifiedDate uuid={uuid} />,
215     },
216     {
217         name: SharedWithMePanelColumnNames.TRASH_AT,
218         selected: false,
219         configurable: true,
220         sort: { direction: SortDirection.NONE, field: 'trashAt' },
221         filters: createTree(),
222         render: (uuid) => <ResourceTrashDate uuid={uuid} />,
223     },
224     {
225         name: SharedWithMePanelColumnNames.DELETE_AT,
226         selected: false,
227         configurable: true,
228         sort: { direction: SortDirection.NONE, field: 'deleteAt' },
229         filters: createTree(),
230         render: (uuid) => <ResourceDeleteDate uuid={uuid} />,
231     },
232 ];
233
234
235 interface SharedWithMePanelDataProps {
236     resources: ResourcesState;
237     userUuid: string;
238 }
239
240 type SharedWithMePanelProps = SharedWithMePanelDataProps & DispatchProp & WithStyles<CssRules>;
241
242 export const SharedWithMePanel = withStyles(styles)(
243     connect((state: RootState) => ({
244         resources: state.resources,
245         userUuid: state.auth.user!.uuid,
246     }))(
247         class extends React.Component<SharedWithMePanelProps> {
248             render() {
249                 return <div className={this.props.classes.root}><DataExplorer
250                     id={SHARED_WITH_ME_PANEL_ID}
251                     onRowClick={this.handleRowClick}
252                     onRowDoubleClick={this.handleRowDoubleClick}
253                     onContextMenu={this.handleContextMenu}
254                     contextMenuColumn={false}
255                     defaultViewIcon={ShareMeIcon}
256                     defaultViewMessages={['No shared items']} />
257                 </div>;
258             }
259
260             handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
261                 const { resources } = this.props;
262                 const resource = getResource<GroupContentsResource>(resourceUuid)(resources);
263                 const menuKind = this.props.dispatch<any>(resourceUuidToContextMenuKind(resourceUuid));
264                 if (menuKind && resource) {
265                     this.props.dispatch<any>(openContextMenu(event, {
266                         name: resource.name,
267                         uuid: resource.uuid,
268                         description: resource.description,
269                         ownerUuid: resource.ownerUuid,
270                         isTrashed: ('isTrashed' in resource) ? resource.isTrashed: false,
271                         kind: resource.kind,
272                         menuKind
273                     }));
274                 }
275                 this.props.dispatch<any>(loadDetailsPanel(resourceUuid));
276             }
277
278             handleRowDoubleClick = (uuid: string) => {
279                 this.props.dispatch<any>(navigateTo(uuid));
280             }
281
282             handleRowClick = (uuid: string) => {
283                 this.props.dispatch<any>(loadDetailsPanel(uuid));
284             }
285         }
286     )
287 );