8000 frontend · coder/coder@badcfec · GitHub
[go: up one dir, main page]

Skip to content

Commit badcfec

Browse files
committed
frontend
1 parent d7e6cd2 commit badcfec

File tree

4 files changed

+103
-34
lines changed

4 files changed

+103
-34
lines changed

site/src/components/Workspace/Workspace.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const Workspace: React.FC<WorkspaceProps> = ({
5050
<WorkspaceSection title="Applications">
5151
<Placeholder />
5252
</WorkspaceSection>
53-
<WorkspaceSchedule autostart={workspace.autostart_schedule} autostop={workspace.autostop_schedule} />
53+
<WorkspaceSchedule workspace={workspace} />
5454
<WorkspaceSection title="Dev URLs">
5555
<Placeholder />
5656
</WorkspaceSection>
Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Story } from "@storybook/react"
2+
import dayjs from "dayjs"
23
import React from "react"
3-
import { MockWorkspaceAutostartEnabled } from "../../testHelpers/renderHelpers"
4+
import * as Mocks from "../../testHelpers/renderHelpers"
45
import { WorkspaceSchedule, WorkspaceScheduleProps } from "./WorkspaceSchedule"
56

67
export default {
@@ -10,8 +11,66 @@ export default {
1011

1112
const Template: Story<WorkspaceScheduleProps> = (args) => <WorkspaceSchedule {...args} />
1213

13-
export const Example = Template.bind({})
14-
Example.args = {
15-
autostart: MockWorkspaceAutostartEnabled.schedule,
16-
autostop: "",
14+
export const NoTTL = Template.bind({})
15+
NoTTL.args = {
16+
workspace: {
17+
...Mocks.MockWorkspace,
18+
ttl: undefined,
19+
},
20+
}
21+
22+
export const ShutdownSoon = Template.bind({})
23+
ShutdownSoon.args = {
24+
workspace: {
25+
...Mocks.MockWorkspace,
26+
27+
latest_build: {
28+
...Mocks.MockWorkspaceBuild,
29+
transition: "start",
30+
updated_at: dayjs().subtract(1, "hour").toString(), // 1 hour ago
31+
},
32+
ttl: 2 * 60 * 60 * 1000 * 1_000_000, // 2 hours
33+
},
34+
}
35+
36+
export const ShutdownLong = Template.bind({})
37+
ShutdownLong.args = {
38+
workspace: {
39+
...Mocks.MockWorkspace,
40+
41+
latest_build: {
42+
...Mocks.MockWorkspaceBuild,
43+
transition: "start",
44+
updated_at: dayjs().toString(),
45+
},
46+
ttl: 7 * 24 * 60 * 60 * 1000 * 1_000_000, // 7 days
47+
},
48+
}
49+
50+
export const WorkspaceOffShort = Template.bind({})
51+
WorkspaceOffShort.args = {
52+
workspace: {
53+
...Mocks.MockWorkspace,
54+
55+
latest_build: {
56+
...Mocks.MockWorkspaceBuild,
57+
transition: "stop",
58+
updated_at: dayjs().subtract(2, "days").toString(),
59+
},
60+
ttl: 2 * 60 * 60 * 1000 * 1_000_000, // 2 hours
61+
},
62+
}
63+
64+
export const WorkspaceOffLong = Template.bind({})
65+
WorkspaceOffLong.args = {
66+
workspace: {
67+
...Mocks.MockWorkspace,
68+
69+
latest_build: {
70+
...Mocks.MockWorkspaceBuild,
71+
transition: "stop",
72+
updated_at: dayjs().subtract(2, "days").toString(),
73+
},
74+
ttl: 2 * 365 * 24 * 60 * 60 * 1000 * 1_000_000, // 2 years
75+
},
1776
}

site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,77 @@
11
import Box from "@material-ui/core/Box"
22
import Typography from "@material-ui/core/Typography"
33
import cronstrue from "cronstrue"
4+
import dayjs from "dayjs"
5+
import duration from "dayjs/plugin/duration"
6+
import relativeTime from "dayjs/plugin/relativeTime"
47
import React from "react"
8+
import * as TypesGen from "../../api/typesGenerated"
59
import { extractTimezone, stripTimezone } from "../../util/schedule"
610
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
711

12+
dayjs.extend(duration)
13+
dayjs.extend(relativeTime)
14+
815
const Language = {
916
autoStartLabel: (schedule: string): string => {
10-
const prefix = "Workspace start"
11-
12-
if (schedule) {
13-
return `${prefix} (${extractTimezone(schedule)})`
14-
} else {
15-
return prefix
16-
}
17-
},
18-
autoStopLabel: (schedule: string): string => {
19-
const prefix = "Workspace shutdown"
17+
const prefix = "Start"
2018

2119
if (schedule) {
2220
return `${prefix} (${extractTimezone(schedule)})`
2321
} else {
2422
return prefix
2523
}
2624
},
27-
cronHumanDisplay: (schedule: string): string => {
25+
autoStartDisplay: (schedule: string): string => {
2826
if (schedule) {
2927
return cronstrue.toString(stripTimezone(schedule), { throwExceptionOnParseError: false })
3028
}
3129
return "Manual"
3230
},
31+
autoStopLabel: "Shutdown",
32+
autoStopDisplay: (workspace: TypesGen.Workspace): string => {
33+
const latest = workspace.latest_build
34+
35+
if (!workspace.ttl || workspace.ttl < 1) {
36+
return "Manual"
37+
}
38+
39+
if (latest.transition === "start") {
40+
const now = dayjs()
41+
const updatedAt = dayjs(latest.updated_at)
42+
const deadline = updatedAt.add(workspace.ttl / 1_000_000, "ms")
43+
if (now.isAfter(deadline)) {
44+
return "WORKING ON THIS"
45+
} else {
46+
return now.to(deadline)
47+
}
48+
}
49+
50+
const duration = dayjs.duration(workspace.ttl / 1_000_000, "milliseconds")
51+
return `${duration.humanize()} after start`
52+
},
3353
}
3454

3555
export interface WorkspaceScheduleProps {
36-
autostart: string
37-
autostop: string
56+
workspace: TypesGen.Workspace
3857
}
3958

4059
/**
4160
* WorkspaceSchedule displays a workspace schedule in a human-readable format
4261
*
4362
* @remarks Visual Component
4463
*/
45-
export const WorkspaceSchedule: React.FC<WorkspaceScheduleProps> = ({ autostart, autostop }) => {
64+
export const WorkspaceSchedule: React.FC<WorkspaceScheduleProps> = ({ workspace }) => {
4665
return (
4766
<WorkspaceSection title="Workspace schedule">
4867
<Box mt={2}>
49-
<Typography variant="h6">{Language.autoStartLabel(autostart)}</Typography>
50-
<Typography>{Language.cronHumanDisplay(autostart)}</Typography>
68+
<Typography variant="h6">{Language.autoStartLabel(workspace.autostart_schedule)}</Typography>
69+
<Typography>{Language.autoStartDisplay(workspace.autostart_schedule)}</Typography>
5170
</Box>
5271

5372
<Box mt={2}>
54-
<Typography variant="h6">{Language.autoStopLabel(autostop)}</Typography>
55-
<Typography>{Language.cronHumanDisplay(autostop)}</Typography>
73+
<Typography variant="h6">{Language.autoStopLabel}</Typography>
74+
<Typography data-chromatic="ignore">{Language.autoStopDisplay(workspace)}</Typography>
5675
</Box>
5776
</WorkspaceSection>
5877
)

site/src/testHelpers/entities.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,6 @@ export const MockWorkspaceAutostartEnabled: TypesGen.UpdateWorkspaceAutostartReq
100100
schedule: "CRON_TZ=Canada/Eastern 30 9 * * 1-5",
101101
}
102102

103-
export const MockWorkspaceAutostopDisabled: TypesGen.UpdateWorkspaceAutostartRequest = {
104-
schedule: "",
105-
}
106-
107-
export const MockWorkspaceAutostopEnabled: TypesGen.UpdateWorkspaceAutostartRequest = {
108-
// Runs at 9:30pm Monday through Friday using America/Toronto
109-
schedule: "CRON_TZ=America/Toronto 30 21 * * 1-5",
110-
}
111-
112103
export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = {
113104
build_number: 1,
114105
created_at: "2022-05-17T17:39:01.382927298Z",
@@ -147,7 +138,7 @@ export const MockWorkspace: TypesGen.Workspace = {
147138
owner_id: MockUser.id,
148139
owner_name: MockUser.username,
149140
autostart_schedule: MockWorkspaceAutostartEnabled.schedule,
150-
autostop_schedule: MockWorkspaceAutostopEnabled.schedule,
141+
ttl: 2 * 60 * 1000 * 1_000_000, // 2 hours as nanoseconds
151142
latest_build: MockWorkspaceBuild,
152143
}
153144

0 commit comments

Comments
 (0)
0