Skip to content

Commit 7eb45e5

Browse files
committed
cleaned up form
1 parent e48b3cc commit 7eb45e5

File tree

7 files changed

+164
-129
lines changed

7 files changed

+164
-129
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"
2+
import { useWorkspacesData } from "./useWorkspacesData"
3+
import { TemplateScheduleFormValues } from "./formHelpers"
4+
5+
export const InactivityDialog = ({
6+
formValues,
7+
submitValues,
8+
isInactivityDialogOpen,
9+
setIsInactivityDialogOpen,
10+
}: {
11+
formValues: TemplateScheduleFormValues
12+
submitValues: (arg0: TemplateScheduleFormValues) => void
13+
isInactivityDialogOpen: boolean
14+
setIsInactivityDialogOpen: (arg0: boolean) => void
15+
}) => {
16+
const workspacesToBeDeletedToday = useWorkspacesData(formValues)
17+
18+
return (
19+
<ConfirmDialog
20+
type="delete"
21+
open={isInactivityDialogOpen}
22+
onConfirm={() => {
23+
submitValues(formValues)
24+
setIsInactivityDialogOpen(false)
25+
}}
26+
onClose={() => setIsInactivityDialogOpen(false)}
27+
title="Delete inactive workspaces"
28+
confirmText="Delete Workspaces"
29+
description={`There are ${
30+
workspacesToBeDeletedToday?.length ?? ""
31+
} workspaces that already match this filter and will be deleted upon form submission. Are you sure you want to proceed?`}
32+
/>
33+
)
34+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Maybe } from "components/Conditionals/Maybe"
2+
import { useTranslation } from "react-i18next"
3+
4+
export const TTLHelperText = ({
5+
ttl,
6+
translationName,
7+
}: {
8+
ttl?: number
9+
translationName: string
10+
}) => {
11+
const { t } = useTranslation("templateSettingsPage")
12+
const count = typeof ttl !== "number" ? 0 : ttl
13+
return (
14+
// no helper text if ttl is negative - error will show once field is considered touched
15+
<Maybe condition={count >= 0}>
16+
<span>{t(translationName, { count })}</span>
17+
</Maybe>
18+
)
19+
}

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

Lines changed: 14 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
import TextField from "@mui/material/TextField"
2-
import {
3-
Template,
4-
UpdateTemplateMeta,
5-
WorkspaceStatus,
6-
Workspace,
7-
} from "api/typesGenerated"
2+
import { Template, UpdateTemplateMeta } from "api/typesGenerated"
83
import { FormikTouched, useFormik } from "formik"
94
import { FC, ChangeEvent, useState } from "react"
105
import { getFormHelpers } from "utils/formUtils"
11-
import * as Yup from "yup"
12-
import i18next from "i18next"
136
import { useTranslation } from "react-i18next"
14-
import { Maybe } from "components/Conditionals/Maybe"
157
import {
168
FormSection,
179
HorizontalForm,
@@ -24,87 +16,16 @@ import Link from "@mui/material/Link"
2416
import Checkbox from "@mui/material/Checkbox"
2517
import FormControlLabel from "@mui/material/FormControlLabel"
2618
import Switch from "@mui/material/Switch"
27-
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"
28-
import { useQuery } from "@tanstack/react-query"
29-
import { getWorkspaces } from "api/api"
30-
import { compareAsc, add, endOfToday } from "date-fns"
31-
32-
const TTLHelperText = ({
33-
ttl,
34-
translationName,
35-
}: {
36-
ttl?: number
37-
translationName: string
38-
}) => {
39-
const { t } = useTranslation("templateSettingsPage")
40-
const count = typeof ttl !== "number" ? 0 : ttl
41-
return (
42-
// no helper text if ttl is negative - error will show once field is considered touched
43-
<Maybe condition={count >= 0}>
44-
<span>{t(translationName, { count })}</span>
45-
</Maybe>
46-
)
47-
}
19+
import { InactivityDialog } from "./InactivityDialog"
20+
import { useWorkspacesData } from "./useWorkspacesData"
21+
import { TemplateScheduleFormValues, getValidationSchema } from "./formHelpers"
22+
import { TTLHelperText } from "./TTLHelperText"
4823

49-
const MAX_TTL_DAYS = 7
5024
const MS_HOUR_CONVERSION = 3600000
5125
const MS_DAY_CONVERSION = 86400000
5226
const FAILURE_CLEANUP_DEFAULT = 7
5327
const INACTIVITY_CLEANUP_DEFAULT = 180
5428

55-
export interface TemplateScheduleFormValues extends UpdateTemplateMeta {
56-
failure_cleanup_enabled: boolean
57-
inactivity_cleanup_enabled: boolean
58-
}
59-
60-
export const getValidationSchema = (): Yup.AnyObjectSchema =>
61-
Yup.object({
62-
default_ttl_ms: Yup.number()
63-
.integer()
64-
.min(0, i18next.t("defaultTTLMinError", { ns: "templateSettingsPage" }))
65-
.max(
66-
24 * MAX_TTL_DAYS /* 7 days in hours */,
67-
i18next.t("defaultTTLMaxError", { ns: "templateSettingsPage" }),
68-
),
69-
max_ttl_ms: Yup.number()
70-
.integer()
71-
.min(0, i18next.t("maxTTLMinError", { ns: "templateSettingsPage" }))
72-
.max(
73-
24 * MAX_TTL_DAYS /* 7 days in hours */,
74-
i18next.t("maxTTLMaxError", { ns: "templateSettingsPage" }),
75-
),
76-
failure_ttl_ms: Yup.number()
77-
.min(0, "Failure cleanup days must not be less than 0.")
78-
.test(
79-
"positive-if-enabled",
80-
"Failure cleanup days must be greater than zero when enabled.",
81-
function (value) {
82-
const parent = this.parent as TemplateScheduleFormValues
83-
if (parent.failure_cleanup_enabled) {
84-
return Boolean(value)
85-
} else {
86-
return true
87-
}
88-
},
89-
),
90-
inactivity_ttl_ms: Yup.number()
91-
.min(0, "Inactivity cleanup days must not be less than 0.")
92-
.test(
93-
"positive-if-enabled",
94-
"Inactivity cleanup days must be greater than zero when enabled.",
95-
function (value) {
96-
const parent = this.parent as TemplateScheduleFormValues
97-
if (parent.inactivity_cleanup_enabled) {
98-
return Boolean(value)
99-
} else {
100-
return true
101-
}
102-
},
103-
),
104-
allow_user_autostart: Yup.boolean(),
105-
allow_user_autostop: Yup.boolean(),
106-
})
107-
10829
export interface TemplateScheduleForm {
10930
template: Template
11031
onSubmit: (data: UpdateTemplateMeta) => void
@@ -172,6 +93,9 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
17293
)
17394
const { t } = useTranslation("templateSettingsPage")
17495
const styles = useStyles()
96+
97+
const workspacesToBeDeletedToday = useWorkspacesData(form.values)
98+
17599
const [isInactivityDialogOpen, setIsInactivityDialogOpen] =
176100
useState<boolean>(false)
177101

@@ -196,35 +120,6 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
196120
})
197121
}
198122

199-
const { data: workspacesData } = useQuery({
200-
queryKey: ["workspaces"],
201-
queryFn: () => getWorkspaces({}),
202-
enabled: form.values.inactivity_cleanup_enabled,
203-
})
204-
205-
const inactiveStatuses: WorkspaceStatus[] = [
206-
"stopped",
207-
"canceled",
208-
"failed",
209-
"deleted",
210-
]
211-
212-
const workspacesToBeDeletedToday = workspacesData?.workspaces?.filter(
213-
(workspace: Workspace) => {
214-
const isInactive = inactiveStatuses.includes(
215-
workspace.latest_build.status,
216-
)
217-
218-
const proposedDeletion = add(new Date(workspace.last_used_at), {
219-
days: form.values.inactivity_ttl_ms,
220-
})
221-
222-
if (isInactive && compareAsc(proposedDeletion, endOfToday()) < 1) {
223-
return workspace
224-
}
225-
},
226-
)
227-
228123
const handleToggleFailureCleanup = async (e: ChangeEvent) => {
229124
form.handleChange(e)
230125
if (!form.values.failure_cleanup_enabled) {
@@ -437,25 +332,17 @@ export const TemplateScheduleForm: FC<TemplateScheduleForm> = ({
437332
</FormSection>
438333
</>
439334
)}
335+
<InactivityDialog
336+
formValues={form.values}
337+
submitValues={submitValues}
338+
isInactivityDialogOpen={isInactivityDialogOpen}
339+
setIsInactivityDialogOpen={setIsInactivityDialogOpen}
340+
/>
440341
<FormFooter
441342
onCancel={onCancel}
442343
isLoading={isSubmitting}
443344
submitDisabled={!form.isValid || !form.dirty}
444345
/>
445-
<ConfirmDialog
446-
type="delete"
447-
open={isInactivityDialogOpen}
448-
onConfirm={() => {
449-
submitValues(form.values)
450-
setIsInactivityDialogOpen(false)
451-
}}
452-
onClose={() => setIsInactivityDialogOpen(false)}
453-
title="Delete inactive workspaces"
454-
confirmText="Delete Workspaces"
455-
description={`There are ${
456-
workspacesToBeDeletedToday?.length ?? ""
457-
} workspaces that already match this filter and will be deleted upon form submission. Are you sure you want to proceed?`}
458-
/>
459346
</HorizontalForm>
460347
)
461348
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { UpdateTemplateMeta } from "api/typesGenerated"
2+
import * as Yup from "yup"
3+
import i18next from "i18next"
4+
5+
export interface TemplateScheduleFormValues extends UpdateTemplateMeta {
6+
failure_cleanup_enabled: boolean
7+
inactivity_cleanup_enabled: boolean
8+
}
9+
10+
const MAX_TTL_DAYS = 7
11+
12+
export const getValidationSchema = (): Yup.AnyObjectSchema =>
13+
Yup.object({
14+
default_ttl_ms: Yup.number()
15+
.integer()
16+
.min(0, i18next.t("defaultTTLMinError", { ns: "templateSettingsPage" }))
17+
.max(
18+
24 * MAX_TTL_DAYS /* 7 days in hours */,
19+
i18next.t("defaultTTLMaxError", { ns: "templateSettingsPage" }),
20+
),
21+
max_ttl_ms: Yup.number()
22+
.integer()
23+
.min(0, i18next.t("maxTTLMinError", { ns: "templateSettingsPage" }))
24+
.max(
25+
24 * MAX_TTL_DAYS /* 7 days in hours */,
26+
i18next.t("maxTTLMaxError", { ns: "templateSettingsPage" }),
27+
),
28+
failure_ttl_ms: Yup.number()
29+
.min(0, "Failure cleanup days must not be less than 0.")
30+
.test(
31+
"positive-if-enabled",
32+
"Failure cleanup days must be greater than zero when enabled.",
33+
function (value) {
34+
const parent = this.parent as TemplateScheduleFormValues
35+
if (parent.failure_cleanup_enabled) {
36+
return Boolean(value)
37+
} else {
38+
return true
39+
}
40+
},
41+
),
42+
inactivity_ttl_ms: Yup.number()
43+
.min(0, "Inactivity cleanup days must not be less than 0.")
44+
.test(
45+
"positive-if-enabled",
46+
"Inactivity cleanup days must be greater than zero when enabled.",
47+
function (value) {
48+
const parent = this.parent as TemplateScheduleFormValues
49+
if (parent.inactivity_cleanup_enabled) {
50+
return Boolean(value)
51+
} else {
52+
return true
53+
}
54+
},
55+
),
56+
allow_user_autostart: Yup.boolean(),
57+
allow_user_autostop: Yup.boolean(),
58+
})
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useQuery } from "@tanstack/react-query"
2+
import { getWorkspaces } from "api/api"
3+
import { compareAsc, add, endOfToday } from "date-fns"
4+
import { WorkspaceStatus, Workspace } from "api/typesGenerated"
5+
import { TemplateScheduleFormValues } from "./formHelpers"
6+
7+
const inactiveStatuses: WorkspaceStatus[] = [
8+
"stopped",
9+
"canceled",
10+
"failed",
11+
"deleted",
12+
]
13+
14+
export const useWorkspacesData = (formValues: TemplateScheduleFormValues) => {
15+
const { data: workspacesData } = useQuery({
16+
queryKey: ["workspaces"],
17+
queryFn: () => getWorkspaces({}),
18+
enabled: formValues.inactivity_cleanup_enabled,
19+
})
20+
const workspacesToBeDeletedToday = workspacesData?.workspaces?.filter(
21+
(workspace: Workspace) => {
22+
const isInactive = inactiveStatuses.includes(
23+
workspace.latest_build.status,
24+
)
25+
26+
const proposedDeletion = add(new Date(workspace.last_used_at), {
27+
days: formValues.inactivity_ttl_ms,
28+
})
29+
30+
if (isInactive && compareAsc(proposedDeletion, endOfToday()) < 1) {
31+
return workspace
32+
}
33+
},
34+
)
35+
36+
return workspacesToBeDeletedToday
37+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
renderWithTemplateSettingsLayout,
1212
waitForLoaderToBeRemoved,
1313
} from "testHelpers/renderHelpers"
14-
import { getValidationSchema } from "./TemplateScheduleForm"
14+
import { getValidationSchema } from "./TemplateScheduleForm/formHelpers"
1515
import TemplateSchedulePage from "./TemplateSchedulePage"
1616
import i18next from "i18next"
1717

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Template, UpdateTemplateMeta } from "api/typesGenerated"
22
import { ComponentProps, FC } from "react"
3-
import { TemplateScheduleForm } from "./TemplateScheduleForm"
3+
import { TemplateScheduleForm } from "./TemplateScheduleForm/TemplateScheduleForm"
44
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"
55
import { makeStyles } from "@mui/styles"
66

0 commit comments

Comments
 (0)