Skip to content

Commit adeb0ff

Browse files
committed
feat: ui for editing ws schedule
Summary: This presents a form component and storybook. The UI will be a routed page and added into the dashboard in a separate PR. It is likely a XService will be used at the page level to supply errors and actions to this form. Impact of Change: Further progress on #1455 Squashed Commits: * refactor: add className prop to Stack combine classes with internal classes and an optional external className to better control the Stack.
1 parent e40c683 commit adeb0ff

File tree

3 files changed

+176
-4
lines changed

3 files changed

+176
-4
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
import React from "react"
3+
import { combineClasses } from "../../util/combineClasses"
34

45
type Direction = "column" | "row"
56

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

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

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

24-
export const Stack: React.FC<StackProps> = ({ children, spacing = 2, direction = "column" }) => {
26+
export const Stack: React.FC<StackProps> = ({ children, className, direction = "column", spacing = 2 }) => {
2527
const styles = useStyles({ spacing, direction })
26-
return <div className={styles.stack}>{children}</div>
28+
29+
return <div className={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+
import React from "react"
4+
import { WorkspaceScheduleForm, WorkspaceScheduleFormProps } from "./WorkspaceScheduleForm"
5+
6+
export default {
7+
title: "components/WorkspaceScheduleForm",
8+
component: WorkspaceScheduleForm,
9+
}
10+
11+
const Template: Story<WorkspaceScheduleFormProps> = (args) => <WorkspaceScheduleForm {...args} />
12+
13+
export const Example = Template.bind({})
14+
Example.args = {
15+
onCancel: () => action("onCancel"),
16+
onSubmit: () => {
17+
action("onSubmit")
18+
return Promise.resolve()
19+
},
20+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import Checkbox from "@material-ui/core/Checkbox"
2+
import FormControl from "@material-ui/core/FormControl"
3+
import FormControlLabel from "@material-ui/core/FormControlLabel"
4+
import FormGroup from "@material-ui/core/FormGroup"
5+
import FormLabel from "@material-ui/core/FormLabel"
6+
import makeStyles from "@material-ui/core/styles/makeStyles"
7+
import TextField from "@material-ui/core/TextField"
8+
import { useFormik } from "formik"
9+
import React from "react"
10+
import { getFormHelpers } from "../../util/formUtils"
11+
import { FormFooter } from "../FormFooter/FormFooter"
12+
import { FullPageForm } from "../FullPageForm/FullPageForm"
13+
import { Stack } from "../Stack/Stack"
14+
15+
export const Language = {
16+
daysOfWeekLabel: "Days of Week",
17+
daySundayLabel: "Sunday",
18+
dayMondayLabel: "Monday",
19+
dayTuesdayLabel: "Tuesday",
20+
dayWednesdayLabel: "Wednesday",
21+
dayThursdayLabel: "Thursday",
22+
dayFridayLabel: "Friday",
23+
daySaturdayLabel: "Saturday",
24+
startTimeLabel: "Start time",
25+
ttlLabel: "Runtime (minutes)",
26+
ttlHelperText: "Your workspace will automatically shutdown after the runtime.",
27+
}
28+
29+
export interface WorkspaceScheduleFormProps {
30+
onCancel: () => void
31+
onSubmit: (values: WorkspaceScheduleFormValues) => Promise<void>
32+
}
33+
34+
export interface WorkspaceScheduleFormValues {
35+
sunday: boolean
36+
monday: boolean
37+
tuesday: boolean
38+
wednesday: boolean
39+
thursday: boolean
40+
friday: boolean
41+
saturday: boolean
42+
43+
startTime: string
44+
ttl: number
45+
}
46+
47+
export const WorkspaceScheduleForm: React.FC<WorkspaceScheduleFormProps> = ({ onCancel, onSubmit }) => {
48+
const styles = useStyles()
49+
50+
const form = useFormik<WorkspaceScheduleFormValues>({
51+
initialValues: {
52+
sunday: false,
53+
monday: true,
54+
tuesday: true,
55+
wednesday: true,
56+
thursday: true,
57+
friday: true,
58+
saturday: false,
59+
60+
startTime: "",
61+
ttl: 0,
62+
},
63+
onSubmit,
64+
})
65+
const formHelpers = getFormHelpers<WorkspaceScheduleFormValues>(form)
66+
67+
return (
68+
<FullPageForm onCancel={onCancel} title="Workspace Schedule">
69+
<form className={styles.form} onSubmit={form.handleSubmit}>
70+
<Stack className={styles.stack}>
71+
<TextField
72+
{...formHelpers("startTime")}
73+
InputLabelProps={{
74+
shrink: true,
75+
}}
76+
label={Language.startTimeLabel}
77+
type="time"
78+
variant="standard"
79+
/>
80+
81+
<FormControl component="fieldset">
82+
<FormLabel className={styles.daysOfWeekLabel} component="legend">
83+
{Language.daysOfWeekLabel}
84+
</FormLabel>
85+
86+
<FormGroup>
87+
<FormControlLabel
88+
control={<Checkbox checked={form.values.sunday} onChange={form.handleChange} name="sunday" />}
89+
label={Language.daySundayLabel}
90+
/>
91+
<FormControlLabel
92+
control={<Checkbox checked={form.values.monday} onChange={form.handleChange} name="monday" />}
93+
label={Language.dayMondayLabel}
94+
/>
95+
<FormControlLabel
96+
control={<Checkbox checked={form.values.tuesday} onChange={form.handleChange} name="tuesday" />}
97+
label={Language.dayTuesdayLabel}
98+
/>
99+
<FormControlLabel
100+
control={<Checkbox checked={form.values.wednesday} onChange={form.handleChange} name="wednesday" />}
101+
label={Language.dayWednesdayLabel}
102+
/>
103+
<FormControlLabel
104+
control={<Checkbox checked={form.values.thursday} onChange={form.handleChange} name="thursday" />}
105+
label={Language.dayThursdayLabel}
106+
/>
107+
<FormControlLabel
108+
control={<Checkbox checked={form.values.friday} onChange={form.handleChange} name="friday" />}
109+
label={Language.dayFridayLabel}
110+
/>
111+
<FormControlLabel
112+
control={<Checkbox checked={form.values.saturday} onChange={form.handleChange} name="saturday" />}
113+
label={Language.daySaturdayLabel}
114+
/>
115+
</FormGroup>
116+
</FormControl>
117+
118+
<TextField
119+
{...formHelpers("ttl", Language.ttlHelperText)}
120+
inputProps={{ min: 0, step: 30 }}
121+
label={Language.ttlLabel}
122+
type="number"
123+
variant="standard"
124+
/>
125+
126+
<FormFooter onCancel={onCancel} isLoading={form.isSubmitting} />
127+
</Stack>
128+
</form>
129+
</FullPageForm>
130+
)
131+
}
132+
133+
const useStyles = makeStyles({
134+
form: {
135+
display: "flex",
136+
justifyContent: "center",
137+
},
138+
stack: {
139+
// REMARK: 360 is 'arbitrary' in that it gives the helper text enough room
140+
// to render on one line. If we change the text, we might want to
141+
// adjust these. Without constraining the width, the date picker
142+
// and number inputs aren't visually appealing or maximally usable.
143+
maxWidth: 360,
144+
minWidth: 360,
145+
},
146+
daysOfWeekLabel: {
147+
fontSize: 12,
148+
},
149+
})

0 commit comments

Comments
 (0)