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