Skip to content

Commit 956a578

Browse files
committed
feat: add advanced schedule settings
1 parent 531fd23 commit 956a578

File tree

3 files changed

+143
-25
lines changed

3 files changed

+143
-25
lines changed

site/src/pages/CreateTemplatePage/CreateTemplateForm.tsx

+51
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ const defaultInitialValues: CreateTemplateData = {
105105
// you are not licensed. We hide the form value based on entitlements.
106106
max_ttl_hours: 24 * 7,
107107
allow_user_cancel_workspace_jobs: false,
108+
allow_user_autostart: false,
109+
allow_user_autostop: false,
108110
}
109111

110112
type GetInitialValuesParams = {
@@ -341,6 +343,55 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
341343
type="number"
342344
/>
343345
</Stack>
346+
<Stack direction="column">
347+
<Stack direction="row" alignItems="center">
348+
<Checkbox
349+
id="allow_user_autostart"
350+
size="small"
351+
color="primary"
352+
disabled={isSubmitting || !canSetMaxTTL}
353+
onChange={async () => {
354+
await form.setFieldValue(
355+
"allow_user_autostart",
356+
!form.values.allow_user_autostart,
357+
)
358+
}}
359+
name="allow_user_autostart"
360+
checked={form.values.allow_user_autostart}
361+
/>
362+
<Stack spacing={0.5}>
363+
<strong>
364+
Allow users to auto-start workspaces on a schedule.
365+
</strong>
366+
</Stack>
367+
</Stack>
368+
<Stack direction="row" alignItems="center">
369+
<Checkbox
370+
id="allow-user-autostop"
371+
size="small"
372+
color="primary"
373+
disabled={isSubmitting || !canSetMaxTTL}
374+
onChange={async () => {
375+
await form.setFieldValue(
376+
"allow_user_autostop",
377+
!form.values.allow_user_autostop,
378+
)
379+
}}
380+
name="allow-user-autostop"
381+
checked={form.values.allow_user_autostop}
382+
/>
383+
<Stack spacing={0.5}>
384+
<strong>
385+
Allow users to customize auto-stop duration for workspaces.
386+
</strong>
387+
<span className={styles.optionText}>
388+
Workspaces will always use the default TTL if this is set.
389+
Regardless of this setting, workspaces can only stay on for
390+
the max lifetime.
391+
</span>
392+
</Stack>
393+
</Stack>
394+
</Stack>
344395
</FormFields>
345396
</FormSection>
346397

site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx

+90-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import TextField from "@material-ui/core/TextField"
22
import { Template, UpdateTemplateMeta } from "api/typesGenerated"
3-
import { FormikContextType, FormikTouched, useFormik } from "formik"
3+
import { FormikTouched, useFormik } from "formik"
44
import { FC } from "react"
55
import { getFormHelpers } from "util/formUtils"
66
import * as Yup from "yup"
@@ -11,6 +11,7 @@ import { FormSection, HorizontalForm, FormFooter } from "components/Form/Form"
1111
import { Stack } from "components/Stack/Stack"
1212
import { makeStyles } from "@material-ui/core/styles"
1313
import Link from "@material-ui/core/Link"
14+
import Checkbox from "@material-ui/core/Checkbox"
1415

1516
const TTLHelperText = ({
1617
ttl,
@@ -48,6 +49,8 @@ export const getValidationSchema = (): Yup.AnyObjectSchema =>
4849
24 * MAX_TTL_DAYS /* 7 days in hours */,
4950
i18next.t("maxTTLMaxError", { ns: "templateSettingsPage" }),
5051
),
52+
allow_user_autostart: Yup.boolean(),
53+
allow_user_autostop: Yup.boolean(),
5154
})
5255

5356
export interface TemplateScheduleForm {
@@ -72,29 +75,32 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
7275
}) => {
7376
const { t: commonT } = useTranslation("common")
7477
const validationSchema = getValidationSchema()
75-
const form: FormikContextType<UpdateTemplateMeta> =
76-
useFormik<UpdateTemplateMeta>({
77-
initialValues: {
78-
// on display, convert from ms => hours
79-
default_ttl_ms: template.default_ttl_ms / MS_HOUR_CONVERSION,
80-
// the API ignores this value, but to avoid tripping up validation set
81-
// it to zero if the user can't set the field.
82-
max_ttl_ms: canSetMaxTTL ? template.max_ttl_ms / MS_HOUR_CONVERSION : 0,
83-
},
84-
validationSchema,
85-
onSubmit: (formData) => {
86-
// on submit, convert from hours => ms
87-
onSubmit({
88-
default_ttl_ms: formData.default_ttl_ms
89-
? formData.default_ttl_ms * MS_HOUR_CONVERSION
90-
: undefined,
91-
max_ttl_ms: formData.max_ttl_ms
92-
? formData.max_ttl_ms * MS_HOUR_CONVERSION
93-
: undefined,
94-
})
95-
},
96-
initialTouched,
97-
})
78+
const form = useFormik<UpdateTemplateMeta>({
79+
initialValues: {
80+
// on display, convert from ms => hours
81+
default_ttl_ms: template.default_ttl_ms / MS_HOUR_CONVERSION,
82+
// the API ignores this value, but to avoid tripping up validation set
83+
// it to zero if the user can't set the field.
84+
max_ttl_ms: canSetMaxTTL ? template.max_ttl_ms / MS_HOUR_CONVERSION : 0,
85+
allow_user_autostart: template.allow_user_autostart,
86+
allow_user_autostop: template.allow_user_autostop,
87+
},
88+
validationSchema,
89+
onSubmit: (formData) => {
90+
// on submit, convert from hours => ms
91+
onSubmit({
92+
default_ttl_ms: formData.default_ttl_ms
93+
? formData.default_ttl_ms * MS_HOUR_CONVERSION
94+
: undefined,
95+
max_ttl_ms: formData.max_ttl_ms
96+
? formData.max_ttl_ms * MS_HOUR_CONVERSION
97+
: undefined,
98+
allow_user_autostart: formData.allow_user_autostart,
99+
allow_user_autostop: formData.allow_user_autostop,
100+
})
101+
},
102+
initialTouched,
103+
})
98104
const getFieldHelpers = getFormHelpers<UpdateTemplateMeta>(form, error)
99105
const { t } = useTranslation("templateSettingsPage")
100106
const styles = useStyles()
@@ -153,13 +159,72 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
153159
</Stack>
154160
</FormSection>
155161

162+
<FormSection
163+
title="Allow users scheduling"
164+
description="Allow users to set custom auto-start and auto-stop scheduling options for workspaces created from this template."
165+
>
166+
<Stack direction="column">
167+
<Stack direction="row" alignItems="center">
168+
<Checkbox
169+
id="allow_user_autostart"
170+
size="small"
171+
color="primary"
172+
disabled={isSubmitting || !canSetMaxTTL}
173+
onChange={async () => {
174+
await form.setFieldValue(
175+
"allow_user_autostart",
176+
!form.values.allow_user_autostart,
177+
)
178+
}}
179+
name="allow_user_autostart"
180+
checked={form.values.allow_user_autostart}
181+
/>
182+
<Stack spacing={0.5}>
183+
<strong>
184+
Allow users to auto-start workspaces on a schedule.
185+
</strong>
186+
</Stack>
187+
</Stack>
188+
<Stack direction="row" alignItems="center">
189+
<Checkbox
190+
id="allow-user-autostop"
191+
size="small"
192+
color="primary"
193+
disabled={isSubmitting || !canSetMaxTTL}
194+
onChange={async () => {
195+
await form.setFieldValue(
196+
"allow_user_autostop",
197+
!form.values.allow_user_autostop,
198+
)
199+
}}
200+
name="allow_user_autostop"
201+
checked={form.values.allow_user_autostop}
202+
/>
203+
<Stack spacing={0.5}>
204+
<strong>
205+
Allow users to customize auto-stop duration for workspaces.
206+
</strong>
207+
<span className={styles.optionDescription}>
208+
Workspaces will always use the default TTL if this is set.
209+
Regardless of this setting, workspaces can only stay on for the
210+
max lifetime.
211+
</span>
212+
</Stack>
213+
</Stack>
214+
</Stack>
215+
</FormSection>
216+
156217
<FormFooter onCancel={onCancel} isLoading={isSubmitting} />
157218
</HorizontalForm>
158219
)
159220
}
160221

161-
const useStyles = makeStyles(() => ({
222+
const useStyles = makeStyles((theme) => ({
162223
ttlFields: {
163224
width: "100%",
164225
},
226+
optionDescription: {
227+
fontSize: 12,
228+
color: theme.palette.text.secondary,
229+
},
165230
}))

site/src/xServices/createTemplate/createTemplateXService.ts

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export interface CreateTemplateData {
4444
icon: string
4545
default_ttl_hours: number
4646
max_ttl_hours: number
47+
allow_user_autostart: boolean
48+
allow_user_autostop: boolean
4749
allow_user_cancel_workspace_jobs: boolean
4850
parameter_values_by_name?: Record<string, string>
4951
user_variable_values?: VariableValue[]

0 commit comments

Comments
 (0)