1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { Button } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { CollectionIcon } from 'components/icon/icon';
11 import { ArvadosTheme } from 'common/custom-theme';
12 import { BackIcon } from 'components/icon/icon';
13 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
14 import { DataExplorer } from "views-components/data-explorer/data-explorer";
15 import { Dispatch } from 'redux';
17 resourceUuidToContextMenuKind,
19 } from 'store/context-menu/context-menu-actions';
20 import { ResourceKind } from 'models/resource';
21 import { loadDetailsPanel } from 'store/details-panel/details-panel-action';
22 import { connect } from 'react-redux';
23 import { navigateTo } from 'store/navigation/navigation-action';
24 import { DataColumns, SortDirection } from 'components/data-table/data-column';
25 import { createTree } from 'models/tree';
29 ResourceLastModifiedDate,
31 } from 'views-components/data-explorer/renderers';
32 import { getResource, ResourcesState } from 'store/resources/resources';
33 import { RootState } from 'store/store';
34 import { CollectionResource } from 'models/collection';
36 type CssRules = 'backLink' | 'backIcon' | 'root' | 'content';
38 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
44 padding: theme.spacing(1),
45 marginBottom: theme.spacing(1),
46 color: theme.palette.grey["500"],
49 marginRight: theme.spacing(1),
55 // reserve space for the content address bar
56 height: `calc(100% - ${theme.spacing(7)})`,
60 enum CollectionContentAddressPanelColumnNames {
61 COLLECTION_WITH_THIS_ADDRESS = "Collection with this address",
63 LOCATION = "Location",
64 LAST_MODIFIED = "Last modified"
67 export const collectionContentAddressPanelColumns: DataColumns<string, CollectionResource> = [
69 name: CollectionContentAddressPanelColumnNames.COLLECTION_WITH_THIS_ADDRESS,
72 sort: {direction: SortDirection.NONE, field: "uuid"},
73 filters: createTree(),
74 render: uuid => <ResourceName uuid={uuid} />
77 name: CollectionContentAddressPanelColumnNames.STATUS,
80 filters: createTree(),
81 render: uuid => <ResourceStatus uuid={uuid} />
84 name: CollectionContentAddressPanelColumnNames.LOCATION,
87 filters: createTree(),
88 render: uuid => <ResourceOwnerName uuid={uuid} />
91 name: CollectionContentAddressPanelColumnNames.LAST_MODIFIED,
94 sort: {direction: SortDirection.DESC, field: "modifiedAt"},
95 filters: createTree(),
96 render: uuid => <ResourceLastModifiedDate uuid={uuid} />
100 interface CollectionContentAddressPanelActionProps {
101 onContextMenu: (resources: ResourcesState) => (event: React.MouseEvent<any>, uuid: string) => void;
102 onItemClick: (item: string) => void;
103 onItemDoubleClick: (item: string) => void;
106 interface CollectionContentAddressPanelDataProps {
107 resources: ResourcesState;
110 const mapStateToProps = ({ resources }: RootState): CollectionContentAddressPanelDataProps => ({
114 const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelActionProps => ({
115 onContextMenu: (resources: ResourcesState) => (event, resourceUuid) => {
116 const resource = getResource<CollectionResource>(resourceUuid)(resources);
117 const kind = dispatch<any>(resourceUuidToContextMenuKind(resourceUuid));
119 dispatch<any>(openContextMenu(event, {
120 name: resource ? resource.name : '',
121 description: resource ? resource.description : '',
122 storageClassesDesired: resource ? resource.storageClassesDesired : [],
125 kind: ResourceKind.NONE,
129 dispatch<any>(loadDetailsPanel(resourceUuid));
131 onItemClick: (uuid: string) => {
132 dispatch<any>(loadDetailsPanel(uuid));
134 onItemDoubleClick: uuid => {
135 dispatch<any>(navigateTo(uuid));
139 interface CollectionContentAddressDataProps {
141 params: { id: string }
145 export const CollectionsContentAddressPanel = withStyles(styles)(
146 connect(mapStateToProps, mapDispatchToProps)(
147 class extends React.Component<CollectionContentAddressPanelActionProps & CollectionContentAddressPanelDataProps & CollectionContentAddressDataProps & WithStyles<CssRules>> {
149 return <div className={this.props.classes.root}>
151 onClick={() => window.history.back()}
152 className={this.props.classes.backLink}>
153 <BackIcon className={this.props.classes.backIcon} />
156 <div className={this.props.classes.content}><DataExplorer
157 id={COLLECTIONS_CONTENT_ADDRESS_PANEL_ID}
159 onRowClick={this.props.onItemClick}
160 onRowDoubleClick={this.props.onItemDoubleClick}
161 onContextMenu={this.props.onContextMenu(this.props.resources)}
162 contextMenuColumn={true}
163 title={`Content address: ${this.props.match.params.id}`}
164 defaultViewIcon={CollectionIcon}
165 defaultViewMessages={['Collections with this content address not found.']}
166 forceMultiSelectMode />