refs #master Merge branch 'origin/master' into 13986-projects-list-and-default-routing
[arvados-workbench2.git] / src / views-components / dialog-update / dialog-project-update.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 { reduxForm, Field } from 'redux-form';
7 import { compose } from 'redux';
8 import { ArvadosTheme } from '~/common/custom-theme';
9 import { StyleRulesCallback, WithStyles, withStyles, Dialog, DialogTitle, DialogContent, DialogActions, CircularProgress, Button } from '../../../node_modules/@material-ui/core';
10 import { TextField } from '~/components/text-field/text-field';
11 import { PROJECT_FORM_NAME } from '~/store/project/project-action';
12 import { PROJECT_NAME_VALIDATION, PROJECT_DESCRIPTION_VALIDATION } from '~/validators/validators';
13
14 type CssRules = 'content' | 'actions' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
15
16 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
17     content: {
18         display: 'flex',
19         flexDirection: 'column'
20     },
21     actions: {
22         margin: 0,
23         padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3 - theme.spacing.unit / 2}px 
24                 ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`
25     },
26     buttonWrapper: {
27         position: 'relative'
28     },
29     saveButton: {
30         boxShadow: 'none'
31     },
32     circularProgress: {
33         position: 'absolute',
34         top: 0,
35         bottom: 0,
36         left: 0,
37         right: 0,
38         margin: 'auto'
39     }
40 });
41
42 interface DialogProjectDataProps {
43     open: boolean;
44     handleSubmit: any;
45     submitting: boolean;
46     invalid: boolean;
47     pristine: boolean;
48 }
49
50 interface DialogProjectActionProps {
51     handleClose: () => void;
52     onSubmit: (data: { name: string, description: string }) => void;
53 }
54
55 type DialogProjectProps = DialogProjectDataProps & DialogProjectActionProps & WithStyles<CssRules>;
56
57 export const DialogProjectUpdate = compose(
58     reduxForm({ form: PROJECT_FORM_NAME }),
59     withStyles(styles))(
60
61         class DialogProjectUpdate extends React.Component<DialogProjectProps> {
62             render() {
63                 const { handleSubmit, handleClose, onSubmit, open, classes, submitting, invalid, pristine } = this.props;
64                 return <Dialog open={open}
65                     onClose={handleClose}
66                     fullWidth={true}
67                     maxWidth='sm'
68                     disableBackdropClick={true}
69                     disableEscapeKeyDown={true}>
70                     <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
71                         <DialogTitle>Edit Collection</DialogTitle>
72                         <DialogContent className={classes.content}>
73                             <Field name='name' 
74                                 disabled={submitting}
75                                 component={TextField}
76                                 validate={PROJECT_NAME_VALIDATION}
77                                 label="Project Name" />
78                             <Field name='description' 
79                                 disabled={submitting}
80                                 component={TextField} 
81                                 validate={PROJECT_DESCRIPTION_VALIDATION}
82                                 label="Description - optional" />
83                         </DialogContent>
84                         <DialogActions className={classes.actions}>
85                             <Button onClick={handleClose} color="primary"
86                                 disabled={submitting}>CANCEL</Button>
87                             <div className={classes.buttonWrapper}>
88                                 <Button type="submit" className={classes.saveButton}
89                                     color="primary"
90                                     disabled={invalid || submitting || pristine}
91                                     variant="contained">
92                                     SAVE
93                                 </Button>
94                                 {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
95                             </div>
96                         </DialogActions>
97                     </form>
98                 </Dialog>;
99             }
100         }
101     );