1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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';
19 resourceUuidToContextMenuKind
20 } from 'store/context-menu/context-menu-actions';
23 ProcessStatus as ResourceStatus,
25 ResourceOwnerWithNameLink,
26 ResourcePortableDataHash,
30 ResourceContainerUuid,
34 ResourceParentProcess,
35 ResourceModifiedByUserUuid,
37 ResourceCreatedAtDate,
38 ResourceLastModifiedDate,
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 { toggleOne, deselectAllOthers } from 'store/multiselect/multiselect-actions';
45 import { DataColumns } from 'components/data-table/data-table';
46 import { ContainerRequestState } from 'models/container-request';
47 import { ProjectResource } from 'models/project';
48 import { createTree } from 'models/tree';
49 import { SortDirection } from 'components/data-table/data-column';
50 import { getInitialResourceTypeFilters, getInitialProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters';
52 type CssRules = "toolbar" | "button" | "root";
54 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
56 paddingBottom: theme.spacing.unit * 3,
60 marginLeft: theme.spacing.unit
67 export enum SharedWithMePanelColumnNames {
72 PORTABLE_DATA_HASH = 'Portable Data Hash',
73 FILE_SIZE = 'File Size',
74 FILE_COUNT = 'File Count',
76 CONTAINER_UUID = 'Container UUID',
78 OUTPUT_UUID = 'Output UUID',
79 LOG_UUID = 'Log UUID',
80 PARENT_PROCESS = 'Parent Process UUID',
81 MODIFIED_BY_USER_UUID = 'Modified by User UUID',
83 CREATED_AT = 'Date Created',
84 LAST_MODIFIED = 'Last Modified',
85 TRASH_AT = 'Trash at',
86 DELETE_AT = 'Delete at',
89 export interface ProjectPanelFilter extends DataTableFilterItem {
90 type: ResourceKind | ContainerRequestState;
93 export const sharedWithMePanelColumns: DataColumns<string, ProjectResource> = [
95 name: SharedWithMePanelColumnNames.NAME,
98 sort: { direction: SortDirection.NONE, field: 'name' },
99 filters: createTree(),
100 render: (uuid) => <ResourceName uuid={uuid} />,
103 name: SharedWithMePanelColumnNames.STATUS,
106 mutuallyExclusiveFilters: true,
107 filters: getInitialProcessStatusFilters(),
108 render: (uuid) => <ResourceStatus uuid={uuid} />,
111 name: SharedWithMePanelColumnNames.TYPE,
114 filters: getInitialResourceTypeFilters(),
115 render: (uuid) => <ResourceType uuid={uuid} />,
118 name: SharedWithMePanelColumnNames.OWNER,
121 filters: createTree(),
122 render: (uuid) => <ResourceOwnerWithNameLink uuid={uuid} />,
125 name: SharedWithMePanelColumnNames.PORTABLE_DATA_HASH,
128 filters: createTree(),
129 render: (uuid) => <ResourcePortableDataHash uuid={uuid} />,
132 name: SharedWithMePanelColumnNames.FILE_SIZE,
135 filters: createTree(),
136 render: (uuid) => <ResourceFileSize uuid={uuid} />,
139 name: SharedWithMePanelColumnNames.FILE_COUNT,
142 filters: createTree(),
143 render: (uuid) => <ResourceFileCount uuid={uuid} />,
146 name: SharedWithMePanelColumnNames.UUID,
149 filters: createTree(),
150 render: (uuid) => <ResourceUUID uuid={uuid} />,
153 name: SharedWithMePanelColumnNames.CONTAINER_UUID,
156 filters: createTree(),
157 render: (uuid) => <ResourceContainerUuid uuid={uuid} />,
160 name: SharedWithMePanelColumnNames.RUNTIME,
163 filters: createTree(),
164 render: (uuid) => <ContainerRunTime uuid={uuid} />,
167 name: SharedWithMePanelColumnNames.OUTPUT_UUID,
170 filters: createTree(),
171 render: (uuid) => <ResourceOutputUuid uuid={uuid} />,
174 name: SharedWithMePanelColumnNames.LOG_UUID,
177 filters: createTree(),
178 render: (uuid) => <ResourceLogUuid uuid={uuid} />,
181 name: SharedWithMePanelColumnNames.PARENT_PROCESS,
184 filters: createTree(),
185 render: (uuid) => <ResourceParentProcess uuid={uuid} />,
188 name: SharedWithMePanelColumnNames.MODIFIED_BY_USER_UUID,
191 filters: createTree(),
192 render: (uuid) => <ResourceModifiedByUserUuid uuid={uuid} />,
195 name: SharedWithMePanelColumnNames.VERSION,
198 filters: createTree(),
199 render: (uuid) => <ResourceVersion uuid={uuid} />,
202 name: SharedWithMePanelColumnNames.CREATED_AT,
205 sort: { direction: SortDirection.NONE, field: 'createdAt' },
206 filters: createTree(),
207 render: (uuid) => <ResourceCreatedAtDate uuid={uuid} />,
210 name: SharedWithMePanelColumnNames.LAST_MODIFIED,
213 sort: { direction: SortDirection.DESC, field: 'modifiedAt' },
214 filters: createTree(),
215 render: (uuid) => <ResourceLastModifiedDate uuid={uuid} />,
218 name: SharedWithMePanelColumnNames.TRASH_AT,
221 sort: { direction: SortDirection.NONE, field: 'trashAt' },
222 filters: createTree(),
223 render: (uuid) => <ResourceTrashDate uuid={uuid} />,
226 name: SharedWithMePanelColumnNames.DELETE_AT,
229 sort: { direction: SortDirection.NONE, field: 'deleteAt' },
230 filters: createTree(),
231 render: (uuid) => <ResourceDeleteDate uuid={uuid} />,
236 interface SharedWithMePanelDataProps {
237 resources: ResourcesState;
241 type SharedWithMePanelProps = SharedWithMePanelDataProps & DispatchProp & WithStyles<CssRules>;
243 export const SharedWithMePanel = withStyles(styles)(
244 connect((state: RootState) => ({
245 resources: state.resources,
246 userUuid: state.auth.user!.uuid,
248 class extends React.Component<SharedWithMePanelProps> {
250 return <div className={this.props.classes.root}><DataExplorer
251 id={SHARED_WITH_ME_PANEL_ID}
252 onRowClick={this.handleRowClick}
253 onRowDoubleClick={this.handleRowDoubleClick}
254 onContextMenu={this.handleContextMenu}
255 contextMenuColumn={false}
256 defaultViewIcon={ShareMeIcon}
257 defaultViewMessages={['No shared items']} />
261 handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
262 const { resources } = this.props;
263 const resource = getResource<GroupContentsResource>(resourceUuid)(resources);
264 const menuKind = this.props.dispatch<any>(resourceUuidToContextMenuKind(resourceUuid));
265 if (menuKind && resource) {
266 this.props.dispatch<any>(openContextMenu(event, {
269 description: resource.description,
270 ownerUuid: resource.ownerUuid,
271 isTrashed: ('isTrashed' in resource) ? resource.isTrashed: false,
276 this.props.dispatch<any>(loadDetailsPanel(resourceUuid));
279 handleRowDoubleClick = (uuid: string) => {
280 this.props.dispatch<any>(navigateTo(uuid));
283 handleRowClick = (uuid: string) => {
284 this.props.dispatch<any>(toggleOne(uuid))
285 this.props.dispatch<any>(deselectAllOthers(uuid))
286 this.props.dispatch<any>(loadDetailsPanel(uuid));