18219: Adds property editor to groups create dialog.
[arvados-workbench2.git] / src / views-components / resource-properties-dialog / resource-properties-dialog.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from "react";
6 import { Dispatch } from "redux";
7 import { connect } from "react-redux";
8 import { RootState } from 'store/store';
9 import { withDialog, WithDialogProps } from "store/dialog/with-dialog";
10 import { RESOURCE_PROPERTIES_DIALOG_NAME } from 'store/details-panel/details-panel-action';
11 import {
12     Dialog,
13     DialogTitle,
14     DialogContent,
15     DialogActions,
16     Button,
17     withStyles,
18     StyleRulesCallback,
19     WithStyles
20 } from '@material-ui/core';
21 import { ArvadosTheme } from 'common/custom-theme';
22 import { ResourcePropertiesDialogForm } from 'views-components/resource-properties-dialog/resource-properties-dialog-form';
23 import { getResource } from 'store/resources/resources';
24 import { getPropertyChip } from "../resource-properties-form/property-chip";
25 import { deleteResourceProperty } from "store/resources/resources-actions";
26 import { ResourceWithProperties } from "models/resource";
27
28 type CssRules = 'tag';
29
30 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
31     tag: {
32         marginRight: theme.spacing.unit,
33         marginBottom: theme.spacing.unit
34     }
35 });
36
37 interface ResourcePropertiesDialogDataProps {
38     resource: ResourceWithProperties;
39 }
40
41 interface ResourcePropertiesDialogActionProps {
42     handleDelete: (uuid: string, key: string, value: string) => void;
43 }
44
45 const mapStateToProps = ({ detailsPanel, resources, properties }: RootState): ResourcePropertiesDialogDataProps => ({
46     resource: getResource(detailsPanel.resourceUuid)(resources) as ResourceWithProperties,
47 });
48
49 const mapDispatchToProps = (dispatch: Dispatch): ResourcePropertiesDialogActionProps => ({
50     handleDelete: (uuid: string, key: string, value: string) => () => dispatch<any>(deleteResourceProperty(uuid, key, value)),
51 });
52
53 type ResourcePropertiesDialogProps = ResourcePropertiesDialogDataProps & ResourcePropertiesDialogActionProps & WithDialogProps<{}> & WithStyles<CssRules>;
54
55 export const ResourcePropertiesDialog = connect(mapStateToProps, mapDispatchToProps)(
56     withStyles(styles)(
57         withDialog(RESOURCE_PROPERTIES_DIALOG_NAME)(
58             ({ classes, open, closeDialog, handleDelete, resource }: ResourcePropertiesDialogProps) =>
59                 <Dialog open={open}
60                     onClose={closeDialog}
61                     fullWidth
62                     maxWidth='sm'>
63                     <div data-cy='resource-properties-dialog'>
64                     <DialogTitle>Edit properties</DialogTitle>
65                     <DialogContent>
66                         <ResourcePropertiesDialogForm uuid={resource ? resource.uuid : ''} />
67                         {resource && resource.properties &&
68                             Object.keys(resource.properties).map(k =>
69                                 Array.isArray(resource.properties[k])
70                                     ? resource.properties[k].map((v: string) =>
71                                         getPropertyChip(
72                                             k, v,
73                                             handleDelete(resource.uuid, k, v),
74                                             classes.tag))
75                                     : getPropertyChip(
76                                         k, resource.properties[k],
77                                         handleDelete(resource.uuid, k, resource.properties[k]),
78                                         classes.tag)
79                             )
80                         }
81                     </DialogContent>
82                     <DialogActions>
83                         <Button
84                             data-cy='close-dialog-btn'
85                             variant='text'
86                             color='primary'
87                             onClick={closeDialog}>
88                             Close
89                     </Button>
90                     </DialogActions>
91                     </div>
92                 </Dialog>
93             )
94     ));