1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { reduxForm, Field } from 'redux-form';
7 import { compose } from 'redux';
8 import TextField from '@material-ui/core/TextField';
9 import Dialog from '@material-ui/core/Dialog';
10 import DialogActions from '@material-ui/core/DialogActions';
11 import DialogContent from '@material-ui/core/DialogContent';
12 import DialogTitle from '@material-ui/core/DialogTitle';
13 import { Button, StyleRulesCallback, WithStyles, withStyles, CircularProgress } from '@material-ui/core';
15 import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
16 import { FileUpload } from "../../components/file-upload/file-upload";
17 import { connect, DispatchProp } from "react-redux";
18 import { RootState } from "../../store/store";
19 import { collectionUploaderActions } from "../../store/collections/uploader/collection-uploader-actions";
21 type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "createProgress" | "dialogActions";
23 const styles: StyleRulesCallback<CssRules> = theme => ({
25 marginLeft: theme.spacing.unit
28 marginLeft: theme.spacing.unit,
33 flexDirection: "column",
36 marginBottom: theme.spacing.unit * 3
44 marginBottom: theme.spacing.unit * 3
48 interface DialogCollectionCreateProps {
50 handleClose: () => void;
51 onSubmit: (data: { name: string, description: string, files: File[] }) => void;
59 interface TextFieldProps {
61 floatinglabeltext: string;
67 export const DialogCollectionCreate = compose(
68 connect((state: RootState) => ({
69 files: state.collections.uploader.files
71 reduxForm({ form: 'collectionCreateDialog' }),
73 class DialogCollectionCreate extends React.Component<DialogCollectionCreateProps & DispatchProp & WithStyles<CssRules>> {
75 const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine } = this.props;
83 disableBackdropClick={true}
84 disableEscapeKeyDown={true}>
85 <form onSubmit={handleSubmit((data: any) => onSubmit({ ...data, files: this.props.files }))}>
86 <DialogTitle id="form-dialog-title">Create a collection</DialogTitle>
87 <DialogContent className={classes.formContainer}>
90 component={this.renderTextField}
91 floatinglabeltext="Collection Name"
92 validate={COLLECTION_NAME_VALIDATION}
93 className={classes.textField}
94 label="Collection Name"/>
95 <Field name="description"
97 component={this.renderTextField}
98 floatinglabeltext="Description - optional"
99 validate={COLLECTION_DESCRIPTION_VALIDATION}
100 className={classes.textField}
101 label="Description - optional"/>
103 files={this.props.files}
104 onDrop={files => this.props.dispatch(collectionUploaderActions.SET_UPLOAD_FILES(files))}/>
106 <DialogActions className={classes.dialogActions}>
107 <Button onClick={handleClose} className={classes.button} color="primary"
108 disabled={submitting}>CANCEL</Button>
109 <Button type="submit"
110 className={classes.lastButton}
112 disabled={invalid || submitting || pristine}
116 {submitting && <CircularProgress size={20} className={classes.createProgress}/>}
123 renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => (
125 helperText={touched && error}
127 className={this.props.classes.textField}
128 error={touched && !!error}