init edit project feature, refactor forms - add textField component
[arvados-workbench2.git] / src / views-components / dialog-update / dialog-collection-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 { Dialog, DialogActions, DialogContent, DialogTitle, StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress } from '@material-ui/core';
10 import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '~/validators/validators';
11 import { COLLECTION_FORM_NAME } from '~/store/collections/updater/collection-updater-action';
12 import { TextField } from '~/components/text-field/text-field';
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 DialogCollectionDataProps {
43     open: boolean;
44     handleSubmit: any;
45     submitting: boolean;
46     invalid: boolean;
47     pristine: boolean;
48 }
49
50 interface DialogCollectionAction {
51     handleClose: () => void;
52     onSubmit: (data: { name: string, description: string }) => void;
53 }
54
55 type DialogCollectionProps = DialogCollectionDataProps & DialogCollectionAction & WithStyles<CssRules>;
56
57 export const DialogCollectionUpdate = compose(
58     reduxForm({ form: COLLECTION_FORM_NAME }),
59     withStyles(styles))(
60
61         class DialogCollectionUpdate extends React.Component<DialogCollectionProps> {
62
63             render() {
64                 const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine } = this.props;
65                 return (
66                     <Dialog open={open}
67                         onClose={handleClose}
68                         fullWidth={true}
69                         maxWidth='sm'
70                         disableBackdropClick={true}
71                         disableEscapeKeyDown={true}>
72
73                         <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
74                             <DialogTitle>Edit Collection</DialogTitle>
75                             <DialogContent className={classes.content}>
76                                 <Field name='name'
77                                     disabled={submitting}
78                                     component={TextField}
79                                     validate={COLLECTION_NAME_VALIDATION}
80                                     label="Collection Name" />
81                                 <Field name='description'
82                                     disabled={submitting}
83                                     component={TextField}
84                                     validate={COLLECTION_DESCRIPTION_VALIDATION}
85                                     label="Description - optional" />
86                             </DialogContent>
87                             <DialogActions className={classes.actions}>
88                                 <Button onClick={handleClose} color="primary"
89                                     disabled={submitting}>CANCEL</Button>
90                                 <div className={classes.buttonWrapper}>
91                                     <Button type="submit" className={classes.saveButton}
92                                         color="primary"
93                                         disabled={invalid || submitting || pristine}
94                                         variant="contained">
95                                         SAVE
96                                     </Button>
97                                     {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
98                                 </div>
99                             </DialogActions>
100                         </form>
101                     </Dialog>
102                 );
103             }
104         }
105     );