From cd810e3f8636b480bd52804b72f2585484fdf90b Mon Sep 17 00:00:00 2001 From: G r e y Date: Fri, 3 Jun 2022 16:12:04 +0000 Subject: [PATCH 1/3] feat: ws schedule timezone select Resolves: #1959 Summary: The package tzdata is used to create a meaningful select-list for timezone in the workspace schedule form. Impact: Improved UX. Furthermore, we guess your timezone if the form is being initialized from scratch. --- site/package.json | 1 + .../WorkspaceScheduleForm.test.ts | 10 +++++++++ .../WorkspaceScheduleForm.tsx | 22 +++++++++---------- .../components/WorkspaceScheduleForm/zones.ts | 3 +++ .../WorkspaceSchedulePage.tsx | 11 ++++++---- site/yarn.lock | 5 +++++ 6 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 site/src/components/WorkspaceScheduleForm/zones.ts diff --git a/site/package.json b/site/package.json index 2a3151a2a4b50..f2adb1fafaf4a 100644 --- a/site/package.json +++ b/site/package.json @@ -48,6 +48,7 @@ "react-router-dom": "6.3.0", "sourcemapped-stacktrace": "1.1.11", "swr": "1.2.2", + "tzdata": "1.0.30", "uuid": "8.3.2", "xstate": "4.32.1", "xterm": "4.18.0", diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts index 84764dd42e543..22e1edf232501 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts @@ -1,4 +1,5 @@ import { Language, validationSchema, WorkspaceScheduleFormValues } from "./WorkspaceScheduleForm" +import { zones } from "./zones" const valid: WorkspaceScheduleFormValues = { sunday: false, @@ -127,6 +128,15 @@ describe("validationSchema", () => { expect(validate).toThrowError(Language.errorTimezone) }) + it.each<[string]>(zones.map((zone) => [zone]))(`validation passes from tz=%p`, (zone) => { + const values: WorkspaceScheduleFormValues = { + ...valid, + timezone: zone, + } + const validate = () => validationSchema.validateSync(values) + expect(validate).not.toThrow() + }) + it("allows a ttl of 7 days", () => { const values: WorkspaceScheduleFormValues = { ...valid, diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx index cd5004fbc5658..e4bafbecd1546 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx @@ -4,7 +4,7 @@ import FormControlLabel from "@material-ui/core/FormControlLabel" import FormGroup from "@material-ui/core/FormGroup" import FormHelperText from "@material-ui/core/FormHelperText" import FormLabel from "@material-ui/core/FormLabel" -import Link from "@material-ui/core/Link" +import MenuItem from "@material-ui/core/MenuItem" import makeStyles from "@material-ui/core/styles/makeStyles" import TextField from "@material-ui/core/TextField" import dayjs from "dayjs" @@ -18,6 +18,7 @@ import { getFormHelpers } from "../../util/formUtils" import { FormFooter } from "../FormFooter/FormFooter" import { FullPageForm } from "../FullPageForm/FullPageForm" import { Stack } from "../Stack/Stack" +import { zones } from "./zones" // REMARK: timezone plugin depends on UTC // @@ -203,21 +204,20 @@ export const WorkspaceScheduleForm: FC = ({ /> - Timezone must be a valid name from the{" "} - - timezone database - - , - )} + {...formHelpers("timezone")} disabled={isLoading} InputLabelProps={{ shrink: true, }} label={Language.timezoneLabel} - /> + select + > + {zones.map((zone) => ( + + {zone} + + ))} + diff --git a/site/src/components/WorkspaceScheduleForm/zones.ts b/site/src/components/WorkspaceScheduleForm/zones.ts new file mode 100644 index 0000000000000..e8d91d612dff1 --- /dev/null +++ b/site/src/components/WorkspaceScheduleForm/zones.ts @@ -0,0 +1,3 @@ +import * as tzData from "tzdata" + +export const zones: string[] = Object.keys(tzData.zones) diff --git a/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.tsx b/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.tsx index 4cc2593fd662c..0aef9da61c823 100644 --- a/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.tsx +++ b/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.tsx @@ -92,7 +92,10 @@ export const formValuesToTTLRequest = (values: WorkspaceScheduleFormValues): Typ } } -export const workspaceToInitialValues = (workspace: TypesGen.Workspace): WorkspaceScheduleFormValues => { +export const workspaceToInitialValues = ( + workspace: TypesGen.Workspace, + defaultTimeZone = "", +): WorkspaceScheduleFormValues => { const schedule = workspace.autostart_schedule const ttlHours = workspace.ttl_ms ? Math.round(workspace.ttl_ms / (1000 * 60 * 60)) : 0 @@ -106,12 +109,12 @@ export const workspaceToInitialValues = (workspace: TypesGen.Workspace): Workspa friday: false, saturday: false, startTime: "", - timezone: "", + timezone: defaultTimeZone, ttl: ttlHours, } } - const timezone = extractTimezone(schedule, dayjs.tz.guess()) + const timezone = extractTimezone(schedule, defaultTimeZone) const expression = cronParser.parseExpression(stripTimezone(schedule)) @@ -162,7 +165,7 @@ export const WorkspaceSchedulePage: React.FC = () => { return ( { navigate(`/workspaces/${workspaceId}`) diff --git a/site/yarn.lock b/site/yarn.lock index 0c4082e7af9d1..76bbd151e9aad 100644 --- a/site/yarn.lock +++ b/site/yarn.lock @@ -13270,6 +13270,11 @@ typescript@4.6.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== +tzdata@1.0.30: + version "1.0.30" + resolved "https://registry.yarnpkg.com/tzdata/-/tzdata-1.0.30.tgz#d9d5a4b4b5e1ed95f6255f98c0564c4256316f52" + integrity sha512-/0yogZsIRUVhGIEGZahL+Nnl9gpMD6jtQ9MlVtPVofFwhaqa+cFTgRy1desTAKqdmIJjS6CL+i6F/mnetrLaxw== + uglify-js@^3.1.4: version "3.15.1" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.1.tgz#9403dc6fa5695a6172a91bc983ea39f0f7c9086d" From 0ca41b5307f452938e8ffb1d3bc7ea6b1a221df6 Mon Sep 17 00:00:00 2001 From: G r e y Date: Fri, 3 Jun 2022 12:17:06 -0400 Subject: [PATCH 2/3] fix: from->for typo --- .../WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts index 22e1edf232501..fae1fa4ff0546 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts @@ -128,7 +128,7 @@ describe("validationSchema", () => { expect(validate).toThrowError(Language.errorTimezone) }) - it.each<[string]>(zones.map((zone) => [zone]))(`validation passes from tz=%p`, (zone) => { + it.each<[string]>(zones.map((zone) => [zone]))(`validation passes for tz=%p`, (zone) => { const values: WorkspaceScheduleFormValues = { ...valid, timezone: zone, From d46e231b8fa903b821d2d3495fcd3c4628d359f2 Mon Sep 17 00:00:00 2001 From: G r e y Date: Fri, 3 Jun 2022 16:27:10 +0000 Subject: [PATCH 3/3] fixup! feat: ws schedule timezone select --- site/src/components/WorkspaceScheduleForm/zones.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/WorkspaceScheduleForm/zones.ts b/site/src/components/WorkspaceScheduleForm/zones.ts index e8d91d612dff1..1a63f357336d7 100644 --- a/site/src/components/WorkspaceScheduleForm/zones.ts +++ b/site/src/components/WorkspaceScheduleForm/zones.ts @@ -1,3 +1,3 @@ -import * as tzData from "tzdata" +import tzData from "tzdata" export const zones: string[] = Object.keys(tzData.zones)