038fea2fd44eb4bb3de3d060a3cf163fedd9b6bb
[arvados-workbench2.git] / src / views / collection-content-address-panel / collection-content-address-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 { StyleRulesCallback, WithStyles, withStyles, Grid, Button } from '@material-ui/core';
7 import { CollectionIcon } from '~/components/icon/icon';
8 import { ArvadosTheme } from '~/common/custom-theme';
9 import { BackIcon } from '~/components/icon/icon';
10 import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
11 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
12 import { DataExplorer } from "~/views-components/data-explorer/data-explorer";
13 import { Dispatch } from 'redux';
14 import { getIsAdmin } from '~/store/public-favorites/public-favorites-actions';
15 import { resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions';
16 import { ResourceKind } from '~/models/resource';
17 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
18 import { connect } from 'react-redux';
19 import { navigateTo } from '~/store/navigation/navigation-action';
20 import { DataColumns } from '~/components/data-table/data-table';
21 import { SortDirection } from '~/components/data-table/data-column';
22 import { createTree } from '~/models/tree';
23 import { ResourceName, ResourceOwnerName, ResourceLastModifiedDate, ResourceStatus } from '~/views-components/data-explorer/renderers';
24
25 type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link';
26
27 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
28     backLink: {
29         fontSize: '14px',
30         fontWeight: 600,
31         display: 'flex',
32         alignItems: 'center',
33         padding: theme.spacing.unit,
34         marginBottom: theme.spacing.unit,
35         color: theme.palette.grey["700"],
36     },
37     backIcon: {
38         marginRight: theme.spacing.unit
39     },
40     card: {
41         width: '100%'
42     },
43     title: {
44         color: theme.palette.grey["700"]
45     },
46     iconHeader: {
47         fontSize: '1.875rem',
48         color: theme.customs.colors.green700
49     },
50     link: {
51         fontSize: '0.875rem',
52         color: theme.palette.primary.main,
53         textAlign: 'right',
54         '&:hover': {
55             cursor: 'pointer'
56         }
57     }
58 });
59
60 enum CollectionContentAddressPanelColumnNames {
61     COLLECTION_WITH_THIS_ADDRESS = "Collection with this address",
62     STATUS = "Status",
63     LOCATION = "Location",
64     LAST_MODIFIED = "Last modified"
65 }
66
67 export const collectionContentAddressPanelColumns: DataColumns<string> = [
68     {
69         name: CollectionContentAddressPanelColumnNames.COLLECTION_WITH_THIS_ADDRESS,
70         selected: true,
71         configurable: true,
72         sortDirection: SortDirection.NONE,
73         filters: createTree(),
74         render: uuid => <ResourceName uuid={uuid} />
75     },
76     {
77         name: CollectionContentAddressPanelColumnNames.STATUS,
78         selected: true,
79         configurable: true,
80         filters: createTree(),
81         render: uuid => <ResourceStatus uuid={uuid} />
82     },
83     {
84         name: CollectionContentAddressPanelColumnNames.LOCATION,
85         selected: true,
86         configurable: true,
87         filters: createTree(),
88         render: uuid => <ResourceOwnerName uuid={uuid} />
89     },
90     {
91         name: CollectionContentAddressPanelColumnNames.LAST_MODIFIED,
92         selected: true,
93         configurable: true,
94         sortDirection: SortDirection.DESC,
95         filters: createTree(),
96         render: uuid => <ResourceLastModifiedDate uuid={uuid} />
97     }
98 ];
99
100 export interface CollectionContentAddressPanelActionProps {
101     onContextMenu: (event: React.MouseEvent<any>, uuid: string) => void;
102     onItemClick: (item: string) => void;
103     onItemDoubleClick: (item: string) => void;
104 }
105
106 const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelActionProps => ({
107     onContextMenu: (event, resourceUuid) => {
108         const isAdmin = dispatch<any>(getIsAdmin());
109         const kind = resourceKindToContextMenuKind(resourceUuid, isAdmin);
110         if (kind) {
111             dispatch<any>(openContextMenu(event, {
112                 name: '',
113                 uuid: resourceUuid,
114                 ownerUuid: '',
115                 kind: ResourceKind.NONE,
116                 menuKind: kind
117             }));
118         }
119         dispatch<any>(loadDetailsPanel(resourceUuid));
120     },
121     onItemClick: (uuid: string) => {
122         dispatch<any>(loadDetailsPanel(uuid));
123     },
124     onItemDoubleClick: uuid => {
125         dispatch<any>(navigateTo(uuid));
126     }
127 });
128
129 interface CollectionContentAddressDataProps {
130     match: {
131         params: { id: string }
132     };
133 }
134
135 export const CollectionsContentAddressPanel = withStyles(styles)(
136     connect(null, mapDispatchToProps)(
137         class extends React.Component<CollectionContentAddressPanelActionProps & CollectionContentAddressDataProps & WithStyles<CssRules>> {
138             render() {
139                 return <Grid item xs={12}>
140                     <Button
141                         onClick={() => history.back()}
142                         className={this.props.classes.backLink}>
143                         <BackIcon className={this.props.classes.backIcon} />
144                         Back
145                     </Button>
146                     <DataExplorer
147                         id={COLLECTIONS_CONTENT_ADDRESS_PANEL_ID}
148                         hideSearchInput
149                         onRowClick={this.props.onItemClick}
150                         onRowDoubleClick={this.props.onItemDoubleClick}
151                         onContextMenu={this.props.onContextMenu}
152                         contextMenuColumn={true}
153                         title={`Content address: ${this.props.match.params.id}`}
154                         dataTableDefaultView={
155                             <DataTableDefaultView
156                                 icon={CollectionIcon}
157                                 messages={['Collections with this content address not found.']} />
158                         } />;
159                     </Grid >;
160             }
161         }
162     )
163 );