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