1
1
import Button from "@material-ui/core/Button"
2
2
import { makeStyles } from "@material-ui/core/styles"
3
- import { FormikContextType , useFormik } from "formik"
3
+ import TextField from "@material-ui/core/TextField"
4
+ import { useFormik } from "formik"
4
5
import React from "react"
5
6
import * as Yup from "yup"
6
7
import * as TypesGen from "../api/typesGenerated"
7
8
import { FormCloseButton } from "../components/FormCloseButton/FormCloseButton"
8
9
import { FormSection } from "../components/FormSection/FormSection"
9
- import { FormTextField } from "../components/FormTextField/FormTextField"
10
10
import { FormTitle } from "../components/FormTitle/FormTitle"
11
11
import { LoadingButton } from "../components/LoadingButton/LoadingButton"
12
12
import { maxWidth } from "../theme/constants"
13
+ import { getFormHelpers , onChangeTrimmed } from "../util/formUtils"
13
14
15
+ export const Language = {
16
+ nameHelperText : "A unique name describing your workspace" ,
17
+ nameLabel : "Workspace Name" ,
18
+ nameMatches : "Name must start with a-Z or 0-9 and can contain a-Z, 0-9 or -" ,
19
+ nameMax : "Name cannot be longer than 32 characters" ,
20
+ namePlaceholder : "my-workspace" ,
21
+ nameRequired : "Name is required" ,
22
+ }
14
23
export interface CreateWorkspaceForm {
15
24
template : TypesGen . Template
16
25
onSubmit : ( organizationId : string , request : TypesGen . CreateWorkspaceRequest ) => Promise < TypesGen . Workspace >
17
26
onCancel : ( ) => void
18
27
organizationId : string
19
28
}
20
29
21
- const validationSchema = Yup . object ( {
22
- name : Yup . string ( ) . required ( "Name is required" ) ,
30
+ export interface CreateWorkspaceFormValues {
31
+ name : string
32
+ }
33
+
34
+ // REMARK: Keep in sync with coderd/httpapi/httpapi.go#L40
35
+ const maxLenName = 32
36
+
37
+ // REMARK: Keep in sync with coderd/httpapi/httpapi.go#L18
38
+ const usernameRE = / ^ [ a - z A - Z 0 - 9 ] + (?: - [ a - z A - Z 0 - 9 ] + ) * $ /
39
+
40
+ export const validationSchema = Yup . object ( {
41
+ name : Yup . string ( )
42
+ . matches ( usernameRE , Language . nameMatches )
43
+ . max ( maxLenName , Language . nameMax )
44
+ . required ( Language . nameRequired ) ,
23
45
} )
24
46
25
47
export const CreateWorkspaceForm : React . FC < CreateWorkspaceForm > = ( {
@@ -30,19 +52,19 @@ export const CreateWorkspaceForm: React.FC<CreateWorkspaceForm> = ({
30
52
} ) => {
31
53
const styles = useStyles ( )
32
54
33
- const form : FormikContextType < { name : string } > = useFormik < { name : string } > ( {
55
+ const form = useFormik < CreateWorkspaceFormValues > ( {
34
56
initialValues : {
35
57
name : "" ,
36
58
} ,
37
- enableReinitialize : true ,
38
- validationSchema : validationSchema ,
39
59
onSubmit : ( { name } ) => {
40
60
return onSubmit ( organizationId , {
41
61
template_id : template . id ,
42
62
name : name ,
43
63
} )
44
64
} ,
65
+ validationSchema : validationSchema ,
45
66
} )
67
+ const getFieldHelpers = getFormHelpers < CreateWorkspaceFormValues > ( form )
46
68
47
69
return (
48
70
< div className = { styles . root } >
@@ -57,14 +79,13 @@ export const CreateWorkspaceForm: React.FC<CreateWorkspaceForm> = ({
57
79
< FormCloseButton onClose = { onCancel } />
58
80
59
81
< FormSection title = "Name" >
60
- < FormTextField
61
- form = { form }
62
- formFieldName = "name"
82
+ < TextField
83
+ { ...getFieldHelpers ( "name" , Language . nameHelperText ) }
84
+ onChange = { onChangeTrimmed ( form ) }
85
+ autoFocus
63
86
fullWidth
64
- helperText = "A unique name describing your workspace."
65
- label = "Workspace Name"
66
- placeholder = "my-workspace"
67
- required
87
+ label = { Language . nameLabel }
88
+ placeholder = { Language . namePlaceholder }
68
89
/>
69
90
</ FormSection >
70
91
0 commit comments