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 { NAME, DESCRIPTION } from '../../validators/create-project/create-project-validator';
16 import { isUniqName } from '../../validators/is-uniq-name';
18 interface ProjectCreateProps {
21 handleClose: () => void;
22 onSubmit: (data: { name: string, description: string }) => void;
26 interface TextFieldProps {
28 floatinglabeltext: string;
34 class DialogProjectCreate extends React.Component<ProjectCreateProps & WithStyles<CssRules>> {
35 /*componentWillReceiveProps(nextProps: ProjectCreateProps) {
36 const { error } = nextProps;
38 TODO: Validation for other errors
39 if (this.props.error !== error && error && error.includes("UniqueViolation")) {
40 this.setState({ isUniqName: error });
45 const { classes, open, handleClose, pending, handleSubmit, onSubmit } = this.props;
50 onClose={handleClose}>
51 <div className={classes.dialog}>
52 <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
53 <DialogTitle id="form-dialog-title" className={classes.dialogTitle}>Create a project</DialogTitle>
54 <DialogContent className={classes.formContainer}>
56 component={this.renderTextField}
57 floatinglabeltext="Project Name"
59 className={classes.textField}
60 label="Project Name" />
61 <Field name="description"
62 component={this.renderTextField}
63 floatinglabeltext="Description"
64 validate={DESCRIPTION}
65 className={classes.textField}
66 label="Description" />
69 <Button onClick={handleClose} className={classes.button} color="primary" disabled={pending}>CANCEL</Button>
71 className={classes.lastButton}
77 {pending && <CircularProgress size={20} className={classes.createProgress} />}
85 // TODO Make it separate file
86 renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => (
88 helperText={touched && error ? error : void 0}
90 className={this.props.classes.textField}
91 error={touched && !!error}
99 type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "dialog" | "dialogTitle" | "createProgress";
101 const styles: StyleRulesCallback<CssRules> = theme => ({
103 marginLeft: theme.spacing.unit
106 marginLeft: theme.spacing.unit,
111 flexDirection: "column",
125 position: "absolute",
131 export default compose(
132 reduxForm({ form: 'projectCreateDialog',/* asyncValidate: isUniqName, asyncBlurFields: ["name"] */}),
134 )(DialogProjectCreate);