init edit project feature, refactor forms - add textField component
[arvados-workbench2.git] / src / views-components / dialog-update / dialog-project-update.tsx
diff --git a/src/views-components/dialog-update/dialog-project-update.tsx b/src/views-components/dialog-update/dialog-project-update.tsx
new file mode 100644 (file)
index 0000000..5dde00a
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { reduxForm, Field } from 'redux-form';
+import { compose } from 'redux';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { StyleRulesCallback, WithStyles, withStyles, Dialog, DialogTitle, DialogContent, DialogActions, CircularProgress, Button } from '../../../node_modules/@material-ui/core';
+import { TextField } from '~/components/text-field/text-field';
+import { PROJECT_FORM_NAME } from '~/store/project/project-action';
+import { PROJECT_NAME_VALIDATION, PROJECT_DESCRIPTION_VALIDATION } from '~/validators/validators';
+
+type CssRules = 'content' | 'actions' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+    content: {
+        display: 'flex',
+        flexDirection: 'column'
+    },
+    actions: {
+        margin: 0,
+        padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3 - theme.spacing.unit / 2}px 
+                ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`
+    },
+    buttonWrapper: {
+        position: 'relative'
+    },
+    saveButton: {
+        boxShadow: 'none'
+    },
+    circularProgress: {
+        position: 'absolute',
+        top: 0,
+        bottom: 0,
+        left: 0,
+        right: 0,
+        margin: 'auto'
+    }
+});
+
+interface DialogProjectDataProps {
+    open: boolean;
+    handleSubmit: any;
+    submitting: boolean;
+    invalid: boolean;
+    pristine: boolean;
+}
+
+interface DialogProjectActionProps {
+    handleClose: () => void;
+    onSubmit: (data: { name: string, description: string }) => void;
+}
+
+type DialogProjectProps = DialogProjectDataProps & DialogProjectActionProps & WithStyles<CssRules>;
+
+export const DialogProjectUpdate = compose(
+    reduxForm({ form: PROJECT_FORM_NAME }),
+    withStyles(styles))(
+
+        class DialogProjectUpdate extends React.Component<DialogProjectProps> {
+            render() {
+                const { handleSubmit, handleClose, onSubmit, open, classes, submitting, invalid, pristine } = this.props;
+                return <Dialog open={open}
+                    onClose={handleClose}
+                    fullWidth={true}
+                    maxWidth='sm'
+                    disableBackdropClick={true}
+                    disableEscapeKeyDown={true}>
+                    <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
+                        <DialogTitle>Edit Collection</DialogTitle>
+                        <DialogContent className={classes.content}>
+                            <Field name='name' 
+                                disabled={submitting}
+                                component={TextField}
+                                validate={PROJECT_NAME_VALIDATION}
+                                label="Project Name" />
+                            <Field name='description' 
+                                disabled={submitting}
+                                component={TextField} 
+                                validate={PROJECT_DESCRIPTION_VALIDATION}
+                                label="Description - optional" />
+                        </DialogContent>
+                        <DialogActions className={classes.actions}>
+                            <Button onClick={handleClose} color="primary"
+                                disabled={submitting}>CANCEL</Button>
+                            <div className={classes.buttonWrapper}>
+                                <Button type="submit" className={classes.saveButton}
+                                    color="primary"
+                                    disabled={invalid || submitting || pristine}
+                                    variant="contained">
+                                    SAVE
+                                </Button>
+                                {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
+                            </div>
+                        </DialogActions>
+                    </form>
+                </Dialog>;
+            }
+        }
+    );