Merge remote-tracking branch 'origin/main' into 18207-Workbench2-is-not-clearing...
[arvados-workbench2.git] / src / views-components / project-properties-dialog / project-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 { ProjectResource } from 'models/project';
11 import { PROJECT_PROPERTIES_DIALOG_NAME, deleteProjectProperty } from 'store/details-panel/details-panel-action';
12 import { Dialog, DialogTitle, DialogContent, DialogActions, Button, withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core';
13 import { ArvadosTheme } from 'common/custom-theme';
14 import { ProjectPropertiesForm } from 'views-components/project-properties-dialog/project-properties-form';
15 import { getResource } from 'store/resources/resources';
16 import { getPropertyChip } from "../resource-properties-form/property-chip";
17
18 type CssRules = 'tag';
19
20 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
21     tag: {
22         marginRight: theme.spacing.unit,
23         marginBottom: theme.spacing.unit
24     }
25 });
26
27 interface ProjectPropertiesDialogDataProps {
28     project: ProjectResource;
29 }
30
31 interface ProjectPropertiesDialogActionProps {
32     handleDelete: (key: string, value: string) => void;
33 }
34
35 const mapStateToProps = ({ detailsPanel, resources, properties }: RootState): ProjectPropertiesDialogDataProps => ({
36     project: getResource(detailsPanel.resourceUuid)(resources) as ProjectResource,
37 });
38
39 const mapDispatchToProps = (dispatch: Dispatch): ProjectPropertiesDialogActionProps => ({
40     handleDelete: (key: string, value: string) => () => dispatch<any>(deleteProjectProperty(key, value)),
41 });
42
43 type ProjectPropertiesDialogProps = ProjectPropertiesDialogDataProps & ProjectPropertiesDialogActionProps & WithDialogProps<{}> & WithStyles<CssRules>;
44
45 export const ProjectPropertiesDialog = connect(mapStateToProps, mapDispatchToProps)(
46     withStyles(styles)(
47         withDialog(PROJECT_PROPERTIES_DIALOG_NAME)(
48             ({ classes, open, closeDialog, handleDelete, project }: ProjectPropertiesDialogProps) =>
49                 <Dialog open={open}
50                     onClose={closeDialog}
51                     fullWidth
52                     maxWidth='sm'>
53                     <DialogTitle>Properties</DialogTitle>
54                     <DialogContent>
55                         <ProjectPropertiesForm />
56                         {project && project.properties &&
57                             Object.keys(project.properties).map(k =>
58                                 Array.isArray(project.properties[k])
59                                     ? project.properties[k].map((v: string) =>
60                                         getPropertyChip(
61                                             k, v,
62                                             handleDelete(k, v),
63                                             classes.tag))
64                                     : getPropertyChip(
65                                         k, project.properties[k],
66                                         handleDelete(k, project.properties[k]),
67                                         classes.tag)
68                             )
69                         }
70                     </DialogContent>
71                     <DialogActions>
72                         <Button
73                             variant='text'
74                             color='primary'
75                             onClick={closeDialog}>
76                             Close
77                     </Button>
78                     </DialogActions>
79                 </Dialog>
80         )
81     ));