refactor
[arvados-workbench2.git] / src / views-components / dialog-create / dialog-project-create.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 TextField from '@material-ui/core/TextField';
7 import Dialog from '@material-ui/core/Dialog';
8 import DialogActions from '@material-ui/core/DialogActions';
9 import DialogContent from '@material-ui/core/DialogContent';
10 import DialogTitle from '@material-ui/core/DialogTitle';
11 import { Button, StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core';
12
13 import Validator from '../../utils/dialog-validator';
14
15 interface ProjectCreateProps {
16   open: boolean;
17   handleClose: () => void;
18   onSubmit: (data: { name: string, description: string }) => void;
19 }
20
21 interface DialogState {
22   name: string;
23   description: string;
24   isNameValid: boolean;
25   isDescriptionValid: boolean;
26 }
27
28 class DialogProjectCreate extends React.Component<ProjectCreateProps & WithStyles<CssRules>> {
29   state: DialogState = {
30     name: '',
31     description: '',
32     isNameValid: false,
33     isDescriptionValid: true
34   };
35
36   render() {
37     const { name, description } = this.state;
38     const { classes, open, handleClose } = this.props;
39
40     return (
41       <Dialog
42         open={open}
43         onClose={handleClose}>
44         <div className={classes.dialog}>
45           <DialogTitle id="form-dialog-title" className={classes.dialogTitle}>Create a project</DialogTitle>
46           <DialogContent className={classes.dialogContent}>
47             <Validator
48               value={name}
49               onChange={e => this.isNameValid(e)}
50               isRequired={true}
51               render={hasError =>
52                 <TextField
53                   margin="dense"
54                   className={classes.textField}
55                   id="name"
56                   onChange={e => this.handleProjectName(e)}
57                   label="Project name"
58                   error={hasError}
59                   fullWidth />} />
60             <Validator
61               value={description}
62               onChange={e => this.isDescriptionValid(e)}
63               isRequired={false}
64               render={hasError =>
65                 <TextField
66                   margin="dense"
67                   className={classes.textField}
68                   id="description"
69                   onChange={e => this.handleDescriptionValue(e)}
70                   label="Description - optional"
71                   error={hasError}
72                   fullWidth />} />
73           </DialogContent>
74           <DialogActions>
75             <Button onClick={handleClose} className={classes.button} color="primary">CANCEL</Button>
76             <Button onClick={this.handleSubmit} className={classes.lastButton} color="primary" disabled={!this.state.isNameValid || (!this.state.isDescriptionValid && description.length > 0)} variant="raised">CREATE A PROJECT</Button>
77           </DialogActions>
78         </div>
79       </Dialog>
80     );
81   }
82
83   handleSubmit = () => {
84     this.props.onSubmit({
85       name: this.state.name,
86       description: this.state.description
87     });
88   }
89
90   handleProjectName(e: React.ChangeEvent<HTMLInputElement>) {
91     this.setState({
92       name: e.target.value,
93     });
94   }
95
96   handleDescriptionValue(e: React.ChangeEvent<HTMLInputElement>) {
97     this.setState({
98       description: e.target.value,
99     });
100   }
101
102   isNameValid(value: boolean | string) {
103     this.setState({
104       isNameValid: value,
105     });
106   }
107
108   isDescriptionValid(value: boolean | string) {
109     this.setState({
110       isDescriptionValid: value,
111     });
112   }
113 }
114
115 type CssRules = "button" | "lastButton" | "dialogContent" | "textField" | "dialog" | "dialogTitle";
116
117 const styles: StyleRulesCallback<CssRules> = theme => ({
118   button: {
119     marginLeft: theme.spacing.unit
120   },
121   lastButton: {
122     marginLeft: theme.spacing.unit,
123     marginRight: "20px",
124   },
125   dialogContent: {
126     marginTop: "20px",
127   },
128   dialogTitle: {
129     paddingBottom: "0"
130   },
131   textField: {
132     marginTop: "32px",
133   },
134   dialog: {
135     minWidth: "600px",
136     minHeight: "320px"
137   }
138 });
139
140 export default withStyles(styles)(DialogProjectCreate);