1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
11 } from '@material-ui/core';
12 import { CollectionIcon } from 'components/icon/icon';
13 import { ArvadosTheme } from 'common/custom-theme';
14 import { BackIcon } from 'components/icon/icon';
15 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
16 import { DataExplorer } from "views-components/data-explorer/data-explorer";
17 import { Dispatch } from 'redux';
19 resourceUuidToContextMenuKind,
21 } from 'store/context-menu/context-menu-actions';
22 import { ResourceKind } from 'models/resource';
23 import { loadDetailsPanel } from 'store/details-panel/details-panel-action';
24 import { connect } from 'react-redux';
25 import { navigateTo } from 'store/navigation/navigation-action';
26 import { DataColumns } from 'components/data-table/data-table';
27 import { SortDirection } from 'components/data-table/data-column';
28 import { createTree } from 'models/tree';
32 ResourceLastModifiedDate,
34 } from 'views-components/data-explorer/renderers';
35 import { getResource, ResourcesState } from 'store/resources/resources';
36 import { RootState } from 'store/store';
37 import { CollectionResource } from 'models/collection';
39 type CssRules = 'backLink' | 'backIcon' | 'root' | 'content';
41 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
47 padding: theme.spacing.unit,
48 marginBottom: theme.spacing.unit,
49 color: theme.palette.grey["500"],
52 marginRight: theme.spacing.unit
58 // reserve space for the content address bar
59 height: `calc(100% - ${theme.spacing.unit * 7}px)`,
63 enum CollectionContentAddressPanelColumnNames {
64 COLLECTION_WITH_THIS_ADDRESS = "Collection with this address",
66 LOCATION = "Location",
67 LAST_MODIFIED = "Last modified"
70 export const collectionContentAddressPanelColumns: DataColumns<string, CollectionResource> = [
72 name: CollectionContentAddressPanelColumnNames.COLLECTION_WITH_THIS_ADDRESS,
75 sort: {direction: SortDirection.NONE, field: "uuid"},
76 filters: createTree(),
77 render: uuid => <ResourceName uuid={uuid} />
80 name: CollectionContentAddressPanelColumnNames.STATUS,
83 filters: createTree(),
84 render: uuid => <ResourceStatus uuid={uuid} />
87 name: CollectionContentAddressPanelColumnNames.LOCATION,
90 filters: createTree(),
91 render: uuid => <ResourceOwnerName uuid={uuid} />
94 name: CollectionContentAddressPanelColumnNames.LAST_MODIFIED,
97 sort: {direction: SortDirection.DESC, field: "modifiedAt"},
98 filters: createTree(),
99 render: uuid => <ResourceLastModifiedDate uuid={uuid} />
103 interface CollectionContentAddressPanelActionProps {
104 onContextMenu: (resources: ResourcesState) => (event: React.MouseEvent<any>, uuid: string) => void;
105 onItemClick: (item: string) => void;
106 onItemDoubleClick: (item: string) => void;
109 interface CollectionContentAddressPanelDataProps {
110 resources: ResourcesState;
113 const mapStateToProps = ({ resources }: RootState): CollectionContentAddressPanelDataProps => ({
117 const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelActionProps => ({
118 onContextMenu: (resources: ResourcesState) => (event, resourceUuid) => {
119 const resource = getResource<CollectionResource>(resourceUuid)(resources);
120 const kind = dispatch<any>(resourceUuidToContextMenuKind(resourceUuid));
122 dispatch<any>(openContextMenu(event, {
123 name: resource ? resource.name : '',
124 description: resource ? resource.description : '',
125 storageClassesDesired: resource ? resource.storageClassesDesired : [],
128 kind: ResourceKind.NONE,
132 dispatch<any>(loadDetailsPanel(resourceUuid));
134 onItemClick: (uuid: string) => {
135 dispatch<any>(loadDetailsPanel(uuid));
137 onItemDoubleClick: uuid => {
138 dispatch<any>(navigateTo(uuid));
142 interface CollectionContentAddressDataProps {
144 params: { id: string }
148 export const CollectionsContentAddressPanel = withStyles(styles)(
149 connect(mapStateToProps, mapDispatchToProps)(
150 class extends React.Component<CollectionContentAddressPanelActionProps & CollectionContentAddressPanelDataProps & CollectionContentAddressDataProps & WithStyles<CssRules>> {
152 return <div className={this.props.classes.root}>
154 onClick={() => window.history.back()}
155 className={this.props.classes.backLink}>
156 <BackIcon className={this.props.classes.backIcon} />
159 <div className={this.props.classes.content}><DataExplorer
160 id={COLLECTIONS_CONTENT_ADDRESS_PANEL_ID}
162 onRowClick={this.props.onItemClick}
163 onRowDoubleClick={this.props.onItemDoubleClick}
164 onContextMenu={this.props.onContextMenu(this.props.resources)}
165 contextMenuColumn={true}
166 title={`Content address: ${this.props.match.params.id}`}
167 defaultViewIcon={CollectionIcon}
168 defaultViewMessages={['Collections with this content address not found.']}
169 forceMultiSelectMode />