13494: Adds integration test for collection version browsing.
[arvados-workbench2.git] / src / views-components / details-panel / collection-details.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 { CollectionIcon } from '~/components/icon/icon';
7 import { CollectionResource } from '~/models/collection';
8 import { DetailsData } from "./details-data";
9 import { CollectionDetailsAttributes } from '~/views/collection-panel/collection-panel';
10 import { RootState } from '~/store/store';
11 import { filterResources, getResource } from '~/store/resources/resources';
12 import { connect } from 'react-redux';
13 import { Grid, ListItem, StyleRulesCallback, Typography, withStyles, WithStyles } from '@material-ui/core';
14 import { formatDate, formatFileSize } from '~/common/formatters';
15 import { Dispatch } from 'redux';
16 import { navigateTo } from '~/store/navigation/navigation-action';
17
18 export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem';
19
20 const styles: StyleRulesCallback<CssRules> = theme => ({
21     versionBrowserHeader: {
22         textAlign: 'center',
23         fontWeight: 'bold',
24     },
25     versionBrowserItem: {
26         textAlign: 'center',
27     }
28 });
29
30 export class CollectionDetails extends DetailsData<CollectionResource> {
31
32     getIcon(className?: string) {
33         return <CollectionIcon className={className} />;
34     }
35
36     getTabLabels() {
37         return ['Details', 'Versions'];
38     }
39
40     getDetails(tabNumber: number) {
41         switch (tabNumber) {
42             case 0:
43                 return this.getCollectionInfo();
44             case 1:
45                 return this.getVersionBrowser();
46             default:
47                 return <div />;
48         }
49     }
50
51     private getCollectionInfo() {
52         return <CollectionDetailsAttributes twoCol={false} item={this.item} />;
53     }
54
55     private getVersionBrowser() {
56         return <CollectionVersionBrowser />;
57     }
58 }
59
60 interface CollectionVersionBrowserProps {
61     currentCollection: CollectionResource | undefined;
62     versions: CollectionResource[];
63 }
64
65 interface CollectionVersionBrowserDispatchProps {
66     showVersion: (c: CollectionResource) => void;
67 }
68
69 const mapStateToProps = (state: RootState): CollectionVersionBrowserProps => {
70     const currentCollection = getResource<CollectionResource>(state.detailsPanel.resourceUuid)(state.resources);
71     const versions = currentCollection
72         && filterResources(rsc =>
73             (rsc as CollectionResource).currentVersionUuid === currentCollection.currentVersionUuid)(state.resources)
74                 .sort((a: CollectionResource, b: CollectionResource) => b.version - a.version) as CollectionResource[]
75         || [];
76     return { currentCollection, versions };
77 };
78
79 const mapDispatchToProps = () =>
80     (dispatch: Dispatch): CollectionVersionBrowserDispatchProps => ({
81         showVersion: (collection) => dispatch<any>(navigateTo(collection.uuid)),
82     });
83
84 const CollectionVersionBrowser = withStyles(styles)(
85     connect(mapStateToProps, mapDispatchToProps)(
86         ({ currentCollection, versions, showVersion, classes }: CollectionVersionBrowserProps & CollectionVersionBrowserDispatchProps & WithStyles<CssRules>) => {
87             return <div data-cy="collection-version-browser">
88                 <Grid container>
89                     <Grid item xs={2}>
90                         <Typography variant="caption" className={classes.versionBrowserHeader}>
91                             Nr
92                         </Typography>
93                     </Grid>
94                     <Grid item xs={4}>
95                         <Typography variant="caption" className={classes.versionBrowserHeader}>
96                             Size
97                         </Typography>
98                     </Grid>
99                     <Grid item xs={6}>
100                         <Typography variant="caption" className={classes.versionBrowserHeader}>
101                             Date
102                         </Typography>
103                     </Grid>
104                 { versions.map(item => {
105                     const isSelectedVersion = !!(currentCollection && currentCollection.uuid === item.uuid);
106                     return (
107                         <ListItem button style={{padding: '4px'}}
108                             data-cy={`collection-version-browser-select-${item.version}`}
109                             key={item.version}
110                             onClick={e => showVersion(item)}
111                             selected={isSelectedVersion}>
112                             <Grid item xs={2}>
113                                 <Typography variant="caption" className={classes.versionBrowserItem}>
114                                     {item.version}
115                                 </Typography>
116                             </Grid>
117                             <Grid item xs={4}>
118                                 <Typography variant="caption" className={classes.versionBrowserItem}>
119                                     {formatFileSize(item.fileSizeTotal)}
120                                 </Typography>
121                             </Grid>
122                             <Grid item xs={6}>
123                                 <Typography variant="caption" className={classes.versionBrowserItem}>
124                                     {formatDate(item.modifiedAt)}
125                                 </Typography>
126                             </Grid>
127                         </ListItem>
128                     );
129                 })}
130                 </Grid>
131             </div>;
132         }));