Skip to content

Commit 0156cc6

Browse files
greyscaledkylecarbs
authored andcommitted
feat: edit workspace schedule page (#1701)
Resolves: #1455 Resolves: #1456 Summary: Adds a page (accessible from Workspace Schedule section on a workspace) to edit a schedule. Impact: General parity with CLI for autostart/autostop: that is you can update your schedule from the UI
1 parent 6a37ae2 commit 0156cc6

File tree

11 files changed

+877
-112
lines changed

11 files changed

+877
-112
lines changed

site/src/AppRouter.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { CreateUserPage } from "./pages/UsersPage/CreateUserPage/CreateUserPage"
1717
import { UsersPage } from "./pages/UsersPage/UsersPage"
1818
import { WorkspaceBuildPage } from "./pages/WorkspaceBuildPage/WorkspaceBuildPage"
1919
import { WorkspacePage } from "./pages/WorkspacePage/WorkspacePage"
20+
import { WorkspaceSchedulePage } from "./pages/WorkspaceSchedulePage/WorkspaceSchedulePage"
2021
import { WorkspaceSettingsPage } from "./pages/WorkspaceSettingsPage/WorkspaceSettingsPage"
2122

2223
const TerminalPage = React.lazy(() => import("./pages/TerminalPage/TerminalPage"))
@@ -83,6 +84,14 @@ export const AppRouter: React.FC = () => (
8384
</AuthAndFrame>
8485
}
8586
/>
87+
<Route
88+
path="schedule"
89+
element={
90+
<RequireAuth>
91+
<WorkspaceSchedulePage />
92+
</RequireAuth>
93+
}
94+
/>
8695
</Route>
8796
</Route>
8897

site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dayjs from "dayjs"
77
import duration from "dayjs/plugin/duration"
88
import relativeTime from "dayjs/plugin/relativeTime"
99
import React from "react"
10+
import { Link as RouterLink } from "react-router-dom"
1011
import { Workspace } from "../../api/typesGenerated"
1112
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
1213
import { extractTimezone, stripTimezone } from "../../util/schedule"
@@ -78,7 +79,9 @@ export const WorkspaceSchedule: React.FC<WorkspaceScheduleProps> = ({ workspace
7879
<span className={styles.scheduleValue}>{Language.autoStopDisplay(workspace)}</span>
7980
</div>
8081
<div>
81-
<Link className={styles.scheduleAction}>{Language.editScheduleLink}</Link>
82+
<Link className={styles.scheduleAction} component={RouterLink} to={`/workspaces/${workspace.id}/schedule`}>
83+
{Language.editScheduleLink}
84+
</Link>
8285
</div>
8386
</Stack>
8487
</div>

site/src/components/WorkspaceStats/WorkspaceScheduleForm.stories.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,5 @@ const Template: Story<WorkspaceScheduleFormProps> = (args) => <WorkspaceSchedule
1313
export const Example = Template.bind({})
1414
Example.args = {
1515
onCancel: () => action("onCancel"),
16-
onSubmit: () => {
17-
action("onSubmit")
18-
return Promise.resolve()
19-
},
16+
onSubmit: () => action("onSubmit"),
2017
}

site/src/components/WorkspaceStats/WorkspaceScheduleForm.test.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const valid: WorkspaceScheduleFormValues = {
1010
saturday: false,
1111

1212
startTime: "09:30",
13+
timezone: "Canada/Eastern",
1314
ttl: 120,
1415
}
1516

@@ -25,14 +26,15 @@ describe("validationSchema", () => {
2526
saturday: false,
2627

2728
startTime: "",
29+
timezone: "",
2830
ttl: 0,
2931
}
3032
const validate = () => validationSchema.validateSync(values)
3133
expect(validate).not.toThrow()
3234
})
3335

3436
it("disallows ttl to be negative", () => {
35-
const values = {
37+
const values: WorkspaceScheduleFormValues = {
3638
...valid,
3739
ttl: -1,
3840
}
@@ -41,7 +43,7 @@ describe("validationSchema", () => {
4143
})
4244

4345
it("disallows all days-of-week to be false when startTime is set", () => {
44-
const values = {
46+
const values: WorkspaceScheduleFormValues = {
4547
...valid,
4648
sunday: false,
4749
monday: false,
@@ -54,4 +56,58 @@ describe("validationSchema", () => {
5456
const validate = () => validationSchema.validateSync(values)
5557
expect(validate).toThrowError(Language.errorNoDayOfWeek)
5658
})
59+
60+
it("allows startTime 16:20", () => {
61+
const values: WorkspaceScheduleFormValues = {
62+
...valid,
63+
startTime: "16:20",
64+
}
65+
const validate = () => validationSchema.validateSync(values)
66+
expect(validate).not.toThrow()
67+
})
68+
69+
it("disallows startTime to be H:mm", () => {
70+
const values: WorkspaceScheduleFormValues = {
71+
...valid,
72+
startTime: "9:30",
73+
}
74+
const validate = () => validationSchema.validateSync(values)
75+
expect(validate).toThrowError(Language.errorTime)
76+
})
77+
78+
it("disallows startTime to be HH:m", () => {
79+
const values: WorkspaceScheduleFormValues = {
80+
...valid,
81+
startTime: "09:5",
82+
}
83+
const validate = () => validationSchema.validateSync(values)
84+
expect(validate).toThrowError(Language.errorTime)
85+
})
86+
87+
it("disallows an invalid startTime 24:01", () => {
88+
const values: WorkspaceScheduleFormValues = {
89+
...valid,
90+
startTime: "24:01",
91+
}
92+
const validate = () => validationSchema.validateSync(values)
93+
expect(validate).toThrowError(Language.errorTime)
94+
})
95+
96+
it("disallows an invalid startTime 09:60", () => {
97+
const values: WorkspaceScheduleFormValues = {
98+
...valid,
99+
startTime: "09:60",
100+
}
101+
const validate = () => validationSchema.validateSync(values)
102+
expect(validate).toThrowError(Language.errorTime)
103+
})
104+
105+
it("disallows an invalid timezone Canada/North", () => {
106+
const values: WorkspaceScheduleFormValues = {
107+
...valid,
108+
timezone: "Canada/North",
109+
}
110+
const validate = () => validationSchema.validateSync(values)
111+
expect(validate).toThrowError(Language.errorTimezone)
112+
})
57113
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy