merge master
[arvados.git] / src / views / collection-panel / collection-tag-form.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, reset } from 'redux-form';
7 import { compose, Dispatch } from 'redux';
8 import { ArvadosTheme } from '~/common/custom-theme';
9 import { StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress, Grid } from '@material-ui/core';
10 import { TagProperty } from '~/models/tag';
11 import { TextField } from '~/components/text-field/text-field';
12 import { createCollectionTag, COLLECTION_TAG_FORM_NAME } from '~/store/collection-panel/collection-panel-action';
13 import { TAG_VALUE_VALIDATION, TAG_KEY_VALIDATION } from '~/validators/validators';
14
15 type CssRules = 'buttonWrapper' | 'saveButton' | 'circularProgress';
16
17 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
18     buttonWrapper: {
19         position: 'relative',
20         display: 'inline-block'
21     },
22     saveButton: {
23         boxShadow: 'none'
24     },
25     circularProgress: {
26         position: 'absolute',
27         top: 0,
28         bottom: 0,
29         left: 0,
30         right: 0,
31         margin: 'auto'
32     }
33 });
34
35 interface CollectionTagFormDataProps {
36     submitting: boolean;
37     invalid: boolean;
38     pristine: boolean;
39 }
40
41 interface CollectionTagFormActionProps {
42     handleSubmit: any;
43 }
44
45 type CollectionTagFormProps = CollectionTagFormDataProps & CollectionTagFormActionProps & WithStyles<CssRules>;
46
47 export const CollectionTagForm = compose(
48     reduxForm({
49         form: COLLECTION_TAG_FORM_NAME,
50         onSubmit: (data: TagProperty, dispatch: Dispatch) => {
51             dispatch<any>(createCollectionTag(data));
52             dispatch(reset(COLLECTION_TAG_FORM_NAME));
53         }
54     }),
55     withStyles(styles))(
56
57         class CollectionTagForm extends React.Component<CollectionTagFormProps> {
58
59             render() {
60                 const { classes, submitting, pristine, invalid, handleSubmit } = this.props;
61                 return (
62                     <form onSubmit={handleSubmit}>
63                         <Grid container justify="flex-start" alignItems="baseline" spacing={24}>
64                             <Grid item xs={3} component={"span"}>
65                                 <Field name="key"
66                                     disabled={submitting}
67                                     component={TextField}
68                                     validate={TAG_KEY_VALIDATION}
69                                     label="Key" />
70                             </Grid>
71                             <Grid item xs={5} component={"span"}>
72                                 <Field name="value"
73                                     disabled={submitting}
74                                     component={TextField}
75                                     validate={TAG_VALUE_VALIDATION}
76                                     label="Value" />
77                             </Grid>
78                             <Grid item component={"span"} className={classes.buttonWrapper}>
79                                 <Button type="submit" className={classes.saveButton}
80                                     color="primary"
81                                     size='small'
82                                     disabled={invalid || submitting || pristine}
83                                     variant="contained">
84                                     ADD
85                                 </Button>
86                                 {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
87                             </Grid>
88                         </Grid>
89                     </form>
90                 );
91             }
92         }
93
94     );