Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit284ec84

Browse files
greyscaledkylecarbs
authored andcommitted
feat: form for editing ws schedule (#1634)
* feat: ui for editing ws scheduleSummary:This presents a form component and storybook. The UI will be a routedpage and added into the dashboard in a separate PR. It is likely aXService will be used at the page level to supply errors and actions tothis form.Impact of Change:Further progress on#1455Squashed Commits:* refactor: add className prop to Stackcombine classes with internal classes and an optional external classNameto better control the Stack.* fix: getFormHelpers helperTextthe helperText logic was incorrect, the helperText would only show if not touched.
1 parentfef8cf3 commit284ec84

File tree

5 files changed

+318
-5
lines changed

5 files changed

+318
-5
lines changed

‎site/src/components/Stack/Stack.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import{makeStyles}from"@material-ui/core/styles"
22
importReactfrom"react"
3+
import{combineClasses}from"../../util/combineClasses"
34

45
typeDirection="column"|"row"
56

67
interfaceStyleProps{
7-
spacing:number
88
direction:Direction
9+
spacing:number
910
}
1011

1112
constuseStyles=makeStyles((theme)=>({
@@ -17,11 +18,13 @@ const useStyles = makeStyles((theme) => ({
1718
}))
1819

1920
exportinterfaceStackProps{
20-
spacing?:number
21+
className?:string
2122
direction?:Direction
23+
spacing?:number
2224
}
2325

24-
exportconstStack:React.FC<StackProps>=({ children,spacing=2, direction="column"})=>{
26+
exportconstStack:React.FC<StackProps>=({ children,className, direction="column", spacing=2})=>{
2527
conststyles=useStyles({ spacing, direction})
26-
return<divclassName={styles.stack}>{children}</div>
28+
29+
return<divclassName={combineClasses([styles.stack,className])}>{children}</div>
2730
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import{action}from"@storybook/addon-actions"
2+
import{Story}from"@storybook/react"
3+
importReactfrom"react"
4+
import{WorkspaceScheduleForm,WorkspaceScheduleFormProps}from"./WorkspaceScheduleForm"
5+
6+
exportdefault{
7+
title:"components/WorkspaceScheduleForm",
8+
component:WorkspaceScheduleForm,
9+
}
10+
11+
constTemplate:Story<WorkspaceScheduleFormProps>=(args)=><WorkspaceScheduleForm{...args}/>
12+
13+
exportconstExample=Template.bind({})
14+
Example.args={
15+
onCancel:()=>action("onCancel"),
16+
onSubmit:()=>{
17+
action("onSubmit")
18+
returnPromise.resolve()
19+
},
20+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import{Language,validationSchema,WorkspaceScheduleFormValues}from"./WorkspaceScheduleForm"
2+
3+
constvalid:WorkspaceScheduleFormValues={
4+
sunday:false,
5+
monday:true,
6+
tuesday:true,
7+
wednesday:true,
8+
thursday:true,
9+
friday:true,
10+
saturday:false,
11+
12+
startTime:"09:30",
13+
ttl:120,
14+
}
15+
16+
describe("validationSchema",()=>{
17+
it("allows everything to be falsy",()=>{
18+
constvalues:WorkspaceScheduleFormValues={
19+
sunday:false,
20+
monday:false,
21+
tuesday:false,
22+
wednesday:false,
23+
thursday:false,
24+
friday:false,
25+
saturday:false,
26+
27+
startTime:"",
28+
ttl:0,
29+
}
30+
constvalidate=()=>validationSchema.validateSync(values)
31+
expect(validate).not.toThrow()
32+
})
33+
34+
it("disallows ttl to be negative",()=>{
35+
constvalues={
36+
...valid,
37+
ttl:-1,
38+
}
39+
constvalidate=()=>validationSchema.validateSync(values)
40+
expect(validate).toThrow()
41+
})
42+
43+
it("disallows all days-of-week to be false when startTime is set",()=>{
44+
constvalues={
45+
...valid,
46+
sunday:false,
47+
monday:false,
48+
tuesday:false,
49+
wednesday:false,
50+
thursday:false,
51+
friday:false,
52+
saturday:false,
53+
}
54+
constvalidate=()=>validationSchema.validateSync(values)
55+
expect(validate).toThrowError(Language.errorNoDayOfWeek)
56+
})
57+
})
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
importCheckboxfrom"@material-ui/core/Checkbox"
2+
importFormControlfrom"@material-ui/core/FormControl"
3+
importFormControlLabelfrom"@material-ui/core/FormControlLabel"
4+
importFormGroupfrom"@material-ui/core/FormGroup"
5+
importFormHelperTextfrom"@material-ui/core/FormHelperText"
6+
importFormLabelfrom"@material-ui/core/FormLabel"
7+
importmakeStylesfrom"@material-ui/core/styles/makeStyles"
8+
importTextFieldfrom"@material-ui/core/TextField"
9+
import{useFormik}from"formik"
10+
importReactfrom"react"
11+
import*asYupfrom"yup"
12+
import{getFormHelpers}from"../../util/formUtils"
13+
import{FormFooter}from"../FormFooter/FormFooter"
14+
import{FullPageForm}from"../FullPageForm/FullPageForm"
15+
import{Stack}from"../Stack/Stack"
16+
17+
exportconstLanguage={
18+
errorNoDayOfWeek:"Must set at least one day of week",
19+
daysOfWeekLabel:"Days of Week",
20+
daySundayLabel:"Sunday",
21+
dayMondayLabel:"Monday",
22+
dayTuesdayLabel:"Tuesday",
23+
dayWednesdayLabel:"Wednesday",
24+
dayThursdayLabel:"Thursday",
25+
dayFridayLabel:"Friday",
26+
daySaturdayLabel:"Saturday",
27+
startTimeLabel:"Start time",
28+
startTimeHelperText:"Your workspace will automatically start at this time.",
29+
ttlLabel:"Runtime (minutes)",
30+
ttlHelperText:"Your workspace will automatically shutdown after the runtime.",
31+
}
32+
33+
exportinterfaceWorkspaceScheduleFormProps{
34+
onCancel:()=>void
35+
onSubmit:(values:WorkspaceScheduleFormValues)=>Promise<void>
36+
}
37+
38+
exportinterfaceWorkspaceScheduleFormValues{
39+
sunday:boolean
40+
monday:boolean
41+
tuesday:boolean
42+
wednesday:boolean
43+
thursday:boolean
44+
friday:boolean
45+
saturday:boolean
46+
47+
startTime:string
48+
ttl:number
49+
}
50+
51+
exportconstvalidationSchema=Yup.object({
52+
sunday:Yup.boolean(),
53+
monday:Yup.boolean().test("at-least-one-day",Language.errorNoDayOfWeek,function(value){
54+
constparent=this.parentasWorkspaceScheduleFormValues
55+
56+
if(!parent.startTime){
57+
returntrue
58+
}else{
59+
return![
60+
parent.sunday,
61+
value,
62+
parent.tuesday,
63+
parent.wednesday,
64+
parent.thursday,
65+
parent.friday,
66+
parent.saturday,
67+
].every((day)=>day===false)
68+
}
69+
}),
70+
tuesday:Yup.boolean(),
71+
wednesday:Yup.boolean(),
72+
thursday:Yup.boolean(),
73+
friday:Yup.boolean(),
74+
saturday:Yup.boolean(),
75+
76+
startTime:Yup.string(),
77+
ttl:Yup.number().min(0).integer(),
78+
})
79+
80+
exportconstWorkspaceScheduleForm:React.FC<WorkspaceScheduleFormProps>=({ onCancel, onSubmit})=>{
81+
conststyles=useStyles()
82+
83+
constform=useFormik<WorkspaceScheduleFormValues>({
84+
initialValues:{
85+
sunday:false,
86+
monday:true,
87+
tuesday:true,
88+
wednesday:true,
89+
thursday:true,
90+
friday:true,
91+
saturday:false,
92+
93+
startTime:"09:30",
94+
ttl:120,
95+
},
96+
onSubmit,
97+
validationSchema,
98+
})
99+
constformHelpers=getFormHelpers<WorkspaceScheduleFormValues>(form)
100+
101+
return(
102+
<FullPageFormonCancel={onCancel}title="Workspace Schedule">
103+
<formclassName={styles.form}onSubmit={form.handleSubmit}>
104+
<StackclassName={styles.stack}>
105+
<TextField
106+
{...formHelpers("startTime",Language.startTimeHelperText)}
107+
InputLabelProps={{
108+
shrink:true,
109+
}}
110+
label={Language.startTimeLabel}
111+
type="time"
112+
variant="standard"
113+
/>
114+
115+
<FormControlcomponent="fieldset"error={Boolean(form.errors.monday)}>
116+
<FormLabelclassName={styles.daysOfWeekLabel}component="legend">
117+
{Language.daysOfWeekLabel}
118+
</FormLabel>
119+
120+
<FormGroup>
121+
<FormControlLabel
122+
control={
123+
<Checkbox
124+
checked={form.values.sunday}
125+
disabled={!form.values.startTime}
126+
onChange={form.handleChange}
127+
name="sunday"
128+
/>
129+
}
130+
label={Language.daySundayLabel}
131+
/>
132+
<FormControlLabel
133+
control={
134+
<Checkbox
135+
checked={form.values.monday}
136+
disabled={!form.values.startTime}
137+
onChange={form.handleChange}
138+
name="monday"
139+
/>
140+
}
141+
label={Language.dayMondayLabel}
142+
/>
143+
<FormControlLabel
144+
control={
145+
<Checkbox
146+
checked={form.values.tuesday}
147+
disabled={!form.values.startTime}
148+
onChange={form.handleChange}
149+
name="tuesday"
150+
/>
151+
}
152+
label={Language.dayTuesdayLabel}
153+
/>
154+
<FormControlLabel
155+
control={
156+
<Checkbox
157+
checked={form.values.wednesday}
158+
disabled={!form.values.startTime}
159+
onChange={form.handleChange}
160+
name="wednesday"
161+
/>
162+
}
163+
label={Language.dayWednesdayLabel}
164+
/>
165+
<FormControlLabel
166+
control={
167+
<Checkbox
168+
checked={form.values.thursday}
169+
disabled={!form.values.startTime}
170+
onChange={form.handleChange}
171+
name="thursday"
172+
/>
173+
}
174+
label={Language.dayThursdayLabel}
175+
/>
176+
<FormControlLabel
177+
control={
178+
<Checkbox
179+
checked={form.values.friday}
180+
disabled={!form.values.startTime}
181+
onChange={form.handleChange}
182+
name="friday"
183+
/>
184+
}
185+
label={Language.dayFridayLabel}
186+
/>
187+
<FormControlLabel
188+
control={
189+
<Checkbox
190+
checked={form.values.saturday}
191+
disabled={!form.values.startTime}
192+
onChange={form.handleChange}
193+
name="saturday"
194+
/>
195+
}
196+
label={Language.daySaturdayLabel}
197+
/>
198+
</FormGroup>
199+
{form.errors.monday&&<FormHelperText>{Language.errorNoDayOfWeek}</FormHelperText>}
200+
</FormControl>
201+
202+
<TextField
203+
{...formHelpers("ttl",Language.ttlHelperText)}
204+
inputProps={{min:0,step:30}}
205+
label={Language.ttlLabel}
206+
type="number"
207+
variant="standard"
208+
/>
209+
210+
<FormFooteronCancel={onCancel}isLoading={form.isSubmitting}/>
211+
</Stack>
212+
</form>
213+
</FullPageForm>
214+
)
215+
}
216+
217+
constuseStyles=makeStyles({
218+
form:{
219+
display:"flex",
220+
justifyContent:"center",
221+
},
222+
stack:{
223+
// REMARK: 360 is 'arbitrary' in that it gives the helper text enough room
224+
// to render on one line. If we change the text, we might want to
225+
// adjust these. Without constraining the width, the date picker
226+
// and number inputs aren't visually appealing or maximally usable.
227+
maxWidth:360,
228+
minWidth:360,
229+
},
230+
daysOfWeekLabel:{
231+
fontSize:12,
232+
},
233+
})

‎site/src/util/formUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const getFormHelpers =
2828
...form.getFieldProps(name),
2929
id:name,
3030
error:touched&&Boolean(error),
31-
helperText:touched ?error :helperText,
31+
helperText:touched ?error||helperText:helperText,
3232
}
3333
}
3434

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp