add form for create tag, modify service and action
[arvados-workbench2.git] / src / views / collection-panel / collection-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 { 
7     StyleRulesCallback, WithStyles, withStyles, Card, 
8     CardHeader, IconButton, CardContent, Grid, Chip, TextField, Button
9 } from '@material-ui/core';
10 import { connect, DispatchProp } from "react-redux";
11 import { RouteComponentProps } from 'react-router';
12 import { ArvadosTheme } from '../../common/custom-theme';
13 import { RootState } from '../../store/store';
14 import { MoreOptionsIcon, CollectionIcon, CopyIcon } from '../../components/icon/icon';
15 import { DetailsAttribute } from '../../components/details-attribute/details-attribute';
16 import { CollectionResource } from '../../models/collection';
17 import * as CopyToClipboard from 'react-copy-to-clipboard';
18 import { TagResource } from '../../models/tag';
19 import { CollectionTagForm } from './collection-tag-form';
20
21 type CssRules = 'card' | 'iconHeader' | 'tag' | 'copyIcon';
22
23 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
24     card: {
25         marginBottom: '20px'
26     },
27     iconHeader: {
28         fontSize: '1.875rem',
29         color: theme.customs.colors.yellow700
30     },
31     tag: {
32         marginRight: theme.spacing.unit,
33         marginBottom: theme.spacing.unit
34     },
35     copyIcon: {
36         marginLeft: theme.spacing.unit,
37         fontSize: '1.125rem',
38         color: theme.palette.grey["500"],
39         cursor: 'pointer'
40     }
41 });
42
43 interface CollectionPanelDataProps {
44     item: CollectionResource;
45     tags: TagResource[];
46 }
47
48 interface CollectionPanelActionProps {
49     onItemRouteChange: (collectionId: string) => void;
50     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: CollectionResource) => void;
51 }
52
53 type CollectionPanelProps = CollectionPanelDataProps & CollectionPanelActionProps & DispatchProp
54                             & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
55
56
57 export const CollectionPanel = withStyles(styles)(
58     connect((state: RootState) => ({ 
59         item: state.collectionPanel.item, 
60         tags: state.collectionPanel.tags 
61     }))(
62         class extends React.Component<CollectionPanelProps> { 
63
64             render() {
65                 const { classes, item, tags, onContextMenu } = this.props;
66                 return <div>
67                         <Card className={classes.card}>
68                             <CardHeader 
69                                 avatar={ <CollectionIcon className={classes.iconHeader} /> }
70                                 action={ 
71                                     <IconButton
72                                         aria-label="More options"
73                                         onClick={event => onContextMenu(event, item)}>
74                                         <MoreOptionsIcon />
75                                     </IconButton> 
76                                 }
77                                 title={item && item.name } 
78                                 subheader={item && item.description} />
79                             <CardContent>
80                                 <Grid container direction="column">
81                                     <Grid item xs={6}>
82                                     <DetailsAttribute label='Collection UUID' value={item && item.uuid}>
83                                         <CopyToClipboard text={item && item.uuid}>
84                                             <CopyIcon className={classes.copyIcon} />
85                                         </CopyToClipboard>
86                                     </DetailsAttribute>
87                                     <DetailsAttribute label='Content size' value='54 MB' />
88                                     <DetailsAttribute label='Owner' value={item && item.ownerUuid} />
89                                     </Grid>
90                                 </Grid>
91                             </CardContent>
92                         </Card>
93
94                         <Card className={classes.card}>
95                             <CardHeader title="Tags" />
96                             <CardContent>
97                                 <Grid container direction="column">
98                                     <Grid item xs={12}><CollectionTagForm /></Grid>
99                                     <Grid item xs={12}>
100                                         {
101                                             tags.map(tag => {
102                                                 return <Chip key={tag.etag} className={classes.tag}
103                                                     onDelete={handleDelete}
104                                                     label={renderTagLabel(tag)}  />;
105                                             })
106                                         }
107                                     </Grid>
108                                 </Grid>
109                             </CardContent>
110                         </Card>
111
112                         <Card className={classes.card}>
113                             <CardHeader title="Files" />
114                             <CardContent>
115                                 <Grid container direction="column">
116                                     <Grid item xs={4}>
117                                         Files
118                                     </Grid>
119                                 </Grid>
120                             </CardContent>
121                         </Card>
122                     </div>;
123             }
124
125             componentWillReceiveProps({ match, item, onItemRouteChange }: CollectionPanelProps) {
126                 if (!item || match.params.id !== item.uuid) {
127                     onItemRouteChange(match.params.id);
128                 }
129             }
130
131         }
132     )
133 );
134
135 const renderTagLabel = (tag: TagResource) => {
136     const { properties } = tag;
137     return `${properties.key}: ${properties.value}`;
138 };
139
140 const handleDelete = () => {
141     alert('tag has been deleted');
142 };