Skip to content

fix: workspace schedule time displays #2249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import { stripTimezone } from "../../util/schedule"
import { isWorkspaceOn } from "../../util/workspace"
import { Stack } from "../Stack/Stack"

dayjs.extend(advancedFormat)
// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
// sorted alphabetically.
dayjs.extend(utc)
dayjs.extend(advancedFormat)
dayjs.extend(duration)
dayjs.extend(relativeTime)
dayjs.extend(timezone)
Expand Down Expand Up @@ -50,7 +52,7 @@ export const Language = {
if (now.isAfter(deadline)) {
return "Workspace is shutting down"
} else {
return deadline.tz(dayjs.tz.guess()).format("hh:mm A")
return deadline.tz(dayjs.tz.guess()).format("MMM D, YYYY h:mm A")
}
} else if (!ttl || ttl < 1) {
// If the workspace is not on, and the ttl is 0 or undefined, then the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,31 +160,99 @@ describe("validationSchema", () => {
})

describe("ttlShutdownAt", () => {
it.each<[dayjs.Dayjs, Workspace, string, number, string]>([
[dayjs("2022-05-17T18:09:00Z"), Mocks.MockStoppedWorkspace, "America/Chicago", 1, Language.ttlHelperText],
[dayjs("2022-05-17T18:09:00Z"), Mocks.MockWorkspace, "America/Chicago", 0, Language.ttlCausesNoShutdownHelperText],
it.each<[string, dayjs.Dayjs, Workspace, string, number, string]>([
[
"Workspace is stopped --> helper text",
dayjs("2022-05-17T18:09:00Z"),
Mocks.MockWorkspace,
Mocks.MockStoppedWorkspace,
"America/Chicago",
1,
`${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} 01:39 PM CDT.`,
Language.ttlHelperText,
],
[
dayjs("2022-05-17T18:10:00Z"),
"TTL is not modified --> helper text",
dayjs("2022-05-17T16:09:00Z"),
{
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
deadline: "2022-05-17T18:09:00Z",
},
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
"America/Chicago",
2,
Language.ttlHelperText,
],
[
"TTL becomes 0 --> manual helper text",
dayjs("2022-05-17T18:09:00Z"),
Mocks.MockWorkspace,
"America/Chicago",
0,
Language.ttlCausesNoShutdownHelperText,
],
[
"Deadline of 18:09 becomes 17:09 at 17:09 --> immediate shutdown",
dayjs("2022-05-17T17:09:00Z"),
{
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
deadline: "2022-05-17T18:09:00Z",
},
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
"America/Chicago",
1,
`⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`,
],
[
"Deadline of 18:09 becomes 17:09 at 16:39 --> display shutdown soon",
dayjs("2022-05-17T16:39:00Z"),
{
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
deadline: "2022-05-17T18:09:00Z",
},
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
"America/Chicago",
1,
`⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`,
],
[
dayjs("2022-05-17T18:40:00Z"),
Mocks.MockWorkspace,
"Deadline of 18:09 becomes 17:09 at 16:09 --> display 12:09 CDT",
dayjs("2022-05-17T16:09:00Z"),
{
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
deadline: "2022-05-17T18:09:00Z",
},
ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
"America/Chicago",
1,
`⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`,
`${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} May 17, 2022 12:09 PM.`,
],
[
"Manual workspace gets new deadline of 18:09 at 17:09 --> display 1:09 CDT",
dayjs("2022-05-17T17:09:00Z"),
{
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
deadline: "0001-01-01T00:00:00Z",
},
ttl_ms: 0,
},
"America/Chicago",
1,
`${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} May 17, 2022 1:09 PM.`,
],
])("ttlShutdownAt(%p, %p, %p, %p) returns %p", (now, workspace, timezone, ttlHours, expected) => {
])("%p", (_, now, workspace, timezone, ttlHours, expected) => {
expect(ttlShutdownAt(now, workspace, timezone, ttlHours)).toEqual(expected)
})
})
41 changes: 27 additions & 14 deletions site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import makeStyles from "@material-ui/core/styles/makeStyles"
import TextField from "@material-ui/core/TextField"
import dayjs from "dayjs"
import advancedFormat from "dayjs/plugin/advancedFormat"
import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
import timezone from "dayjs/plugin/timezone"
import utc from "dayjs/plugin/utc"
import { useFormik } from "formik"
Expand All @@ -23,11 +24,11 @@ import { FullPageForm } from "../FullPageForm/FullPageForm"
import { Stack } from "../Stack/Stack"
import { zones } from "./zones"

// REMARK: timezone plugin depends on UTC
//
// SEE: https://day.js.org/docs/en/timezone/timezone
dayjs.extend(advancedFormat)
// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
// sorted alphabetically.
dayjs.extend(utc)
dayjs.extend(advancedFormat)
dayjs.extend(isSameOrBefore)
dayjs.extend(timezone)

export const Language = {
Expand Down Expand Up @@ -282,19 +283,31 @@ export const WorkspaceScheduleForm: FC<WorkspaceScheduleFormProps> = ({
)
}

export const ttlShutdownAt = (now: dayjs.Dayjs, workspace: Workspace, tz: string, newTTL: number): string => {
const newDeadline = dayjs(workspace.latest_build.updated_at).add(newTTL, "hour")
if (!isWorkspaceOn(workspace)) {
export const ttlShutdownAt = (now: dayjs.Dayjs, workspace: Workspace, tz: string, formTTL: number): string => {
// a manual shutdown has a deadline of '"0001-01-01T00:00:00Z"'
// SEE: #1834
const deadline = dayjs(workspace.latest_build.deadline).utc()
const hasDeadline = deadline.year() > 1
const ttl = workspace.ttl_ms ? workspace.ttl_ms / (1000 * 60 * 60) : 0
const delta = formTTL - ttl

console.info("delta :: ", delta)

if (delta === 0 || !isWorkspaceOn(workspace)) {
return Language.ttlHelperText
} else if (newTTL === 0) {
} else if (formTTL === 0) {
return Language.ttlCausesNoShutdownHelperText
} else if (newDeadline.isBefore(now)) {
return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`
} else if (newDeadline.isBefore(now.add(30, "minute"))) {
return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`
} else {
const newDeadlineString = newDeadline.tz(tz).format("hh:mm A z")
return `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} ${newDeadlineString}.`
const newDeadline = dayjs(hasDeadline ? deadline : now).add(delta, "hour")
if (newDeadline.isSameOrBefore(now)) {
return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`
} else if (newDeadline.isSameOrBefore(now.add(30, "minute"))) {
return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`
} else {
return `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} ${newDeadline
.tz(tz)
.format("MMM D, YYYY h:mm A")}.`
}
}
}

Expand Down