Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d0ea00

Browse files
refactor: Move schedule to the header (coder#2775)
1 parent 22febc7 commit 2d0ea00

File tree

8 files changed

+444
-157
lines changed

8 files changed

+444
-157
lines changed

site/src/components/Workspace/Workspace.tsx

+17-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { makeStyles } from "@material-ui/core/styles"
2-
import { FC } from "react"
2+
import React, { FC } from "react"
33
import { useNavigate } from "react-router-dom"
44
import * as TypesGen from "../../api/typesGenerated"
55
import { BuildsTable } from "../BuildsTable/BuildsTable"
@@ -9,8 +9,8 @@ import { Resources } from "../Resources/Resources"
99
import { Stack } from "../Stack/Stack"
1010
import { WorkspaceActions } from "../WorkspaceActions/WorkspaceActions"
1111
import { WorkspaceDeletedBanner } from "../WorkspaceDeletedBanner/WorkspaceDeletedBanner"
12-
import { WorkspaceSchedule } from "../WorkspaceSchedule/WorkspaceSchedule"
1312
import { WorkspaceScheduleBanner } from "../WorkspaceScheduleBanner/WorkspaceScheduleBanner"
13+
import { WorkspaceScheduleButton } from "../WorkspaceScheduleButton/WorkspaceScheduleButton"
1414
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
1515
import { WorkspaceStats } from "../WorkspaceStats/WorkspaceStats"
1616

@@ -58,16 +58,22 @@ export const Workspace: FC<WorkspaceProps> = ({
5858
return (
5959
<Margins>
6060
<PageHeader
61-
className={styles.header}
6261
actions={
63-
<WorkspaceActions
64-
workspace={workspace}
65-
handleStart={handleStart}
66-
handleStop={handleStop}
67-
handleDelete={handleDelete}
68-
handleUpdate={handleUpdate}
69-
handleCancel={handleCancel}
70-
/>
62+
<Stack direction="row" spacing={1}>
63+
<WorkspaceScheduleButton
64+
workspace={workspace}
65+
onDeadlineMinus={scheduleProps.onDeadlineMinus}
66+
onDeadlinePlus={scheduleProps.onDeadlinePlus}
67+
/>
68+
<WorkspaceActions
69+
workspace={workspace}
70+
handleStart={handleStart}
71+
handleStop={handleStop}
72+
handleDelete={handleDelete}
73+
handleUpdate={handleUpdate}
74+
handleCancel={handleCancel}
75+
/>
76+
</Stack>
7177
}
7278
>
7379
<PageHeaderTitle>{workspace.name}</PageHeaderTitle>
@@ -102,14 +108,6 @@ export const Workspace: FC<WorkspaceProps> = ({
102108
<BuildsTable builds={builds} className={styles.timelineTable} />
103109
</WorkspaceSection>
104110
</Stack>
105-
106-
<Stack direction="column" className={styles.secondColumnSpacer} spacing={3}>
107-
<WorkspaceSchedule
108-
workspace={workspace}
109-
onDeadlineMinus={scheduleProps.onDeadlineMinus}
110-
onDeadlinePlus={scheduleProps.onDeadlinePlus}
111-
/>
112-
</Stack>
113111
</Stack>
114112
</Margins>
115113
)
@@ -125,10 +123,6 @@ export const useStyles = makeStyles((theme) => {
125123
secondColumnSpacer: {
126124
flex: `0 0 ${spacerWidth}px`,
127125
},
128-
header: {
129-
// 100% - (the size of sidebar + the space between both )
130-
maxWidth: `calc(100% - (${spacerWidth}px + ${theme.spacing(3)}px))`,
131-
},
132126
layout: {
133127
alignItems: "flex-start",
134128
},
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
import IconButton from "@material-ui/core/IconButton"
21
import Link from "@material-ui/core/Link"
32
import { makeStyles } from "@material-ui/core/styles"
4-
import Tooltip from "@material-ui/core/Tooltip"
5-
import Typography from "@material-ui/core/Typography"
6-
import AddBoxIcon from "@material-ui/icons/AddBox"
7-
import IndeterminateCheckBoxIcon from "@material-ui/icons/IndeterminateCheckBox"
8-
import ScheduleIcon from "@material-ui/icons/Schedule"
9-
import cronstrue from "cronstrue"
103
import dayjs from "dayjs"
114
import advancedFormat from "dayjs/plugin/advancedFormat"
125
import duration from "dayjs/plugin/duration"
@@ -17,8 +10,12 @@ import { FC } from "react"
1710
import { Link as RouterLink } from "react-router-dom"
1811
import { Workspace } from "../../api/typesGenerated"
1912
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
20-
import { extractTimezone, stripTimezone } from "../../util/schedule"
21-
import { isWorkspaceOn } from "../../util/workspace"
13+
import {
14+
autoStartDisplay,
15+
autoStopDisplay,
16+
extractTimezone,
17+
Language as ScheduleLanguage,
18+
} from "../../util/schedule"
2219
import { Stack } from "../Stack/Stack"
2320

2421
// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
@@ -30,133 +27,39 @@ dayjs.extend(relativeTime)
3027
dayjs.extend(timezone)
3128

3229
export const Language = {
33-
autoStartDisplay: (schedule: string | undefined): string => {
34-
if (schedule) {
35-
return cronstrue.toString(stripTimezone(schedule), { throwExceptionOnParseError: false })
36-
} else {
37-
return "Manual"
38-
}
39-
},
40-
autoStartLabel: "START",
41-
autoStopLabel: "SHUTDOWN",
42-
autoStopDisplay: (workspace: Workspace): string => {
43-
const deadline = dayjs(workspace.latest_build.deadline).utc()
44-
// a manual shutdown has a deadline of '"0001-01-01T00:00:00Z"'
45-
// SEE: #1834
46-
const hasDeadline = deadline.year() > 1
47-
const ttl = workspace.ttl_ms
48-
49-
if (isWorkspaceOn(workspace) && hasDeadline) {
50-
// Workspace is on --> derive from latest_build.deadline. Note that the
51-
// user may modify their workspace object (ttl) while the workspace is
52-
// running and depending on system semantics, the deadline may still
53-
// represent the previously defined ttl. Thus, we always derive from the
54-
// deadline as the source of truth.
55-
const now = dayjs().utc()
56-
if (now.isAfter(deadline)) {
57-
return "Workspace is shutting down"
58-
} else {
59-
return deadline.tz(dayjs.tz.guess()).format("MMM D, YYYY h:mm A")
60-
}
61-
} else if (!ttl || ttl < 1) {
62-
// If the workspace is not on, and the ttl is 0 or undefined, then the
63-
// workspace is set to manually shutdown.
64-
return "Manual"
65-
} else {
66-
// The workspace has a ttl set, but is either in an unknown state or is
67-
// not running. Therefore, we derive from workspace.ttl.
68-
const duration = dayjs.duration(ttl, "milliseconds")
69-
return `${duration.humanize()} after start`
70-
}
71-
},
7230
editScheduleLink: "Edit schedule",
73-
editDeadlineMinus: "Subtract one hour",
74-
editDeadlinePlus: "Add one hour",
75-
scheduleHeader: (workspace: Workspace): string => {
76-
const tz = workspace.autostart_schedule
77-
? extractTimezone(workspace.autostart_schedule)
78-
: dayjs.tz.guess()
79-
return `Schedule (${tz})`
80-
},
31+
timezoneLabel: "Timezone",
8132
}
8233

8334
export interface WorkspaceScheduleProps {
84-
now?: dayjs.Dayjs
8535
workspace: Workspace
86-
onDeadlinePlus: () => void
87-
onDeadlineMinus: () => void
88-
}
89-
90-
export const shouldDisplayPlusMinus = (workspace: Workspace): boolean => {
91-
if (!isWorkspaceOn(workspace)) {
92-
return false
93-
}
94-
const deadline = dayjs(workspace.latest_build.deadline).utc()
95-
return deadline.year() > 1
96-
}
97-
98-
export const deadlineMinusDisabled = (workspace: Workspace, now: dayjs.Dayjs): boolean => {
99-
const delta = dayjs(workspace.latest_build.deadline).diff(now)
100-
return delta <= 30 * 60 * 1000 // 30 minutes
101-
}
102-
103-
export const deadlinePlusDisabled = (workspace: Workspace, now: dayjs.Dayjs): boolean => {
104-
const delta = dayjs(workspace.latest_build.deadline).diff(now)
105-
return delta >= 24 * 60 * 60 * 1000 // 24 hours
10636
}
10737

108-
export const WorkspaceSchedule: FC<WorkspaceScheduleProps> = ({
109-
now,
110-
workspace,
111-
onDeadlineMinus,
112-
onDeadlinePlus,
113-
}) => {
38+
export const WorkspaceSchedule: FC<WorkspaceScheduleProps> = ({ workspace }) => {
11439
const styles = useStyles()
115-
const editDeadlineButtons = shouldDisplayPlusMinus(workspace) ? (
116-
<Stack direction="row" spacing={0}>
117-
<IconButton
118-
size="small"
119-
disabled={deadlineMinusDisabled(workspace, now ?? dayjs())}
120-
className={styles.editDeadline}
121-
onClick={onDeadlineMinus}
122-
>
123-
<Tooltip title={Language.editDeadlineMinus}>
124-
<IndeterminateCheckBoxIcon />
125-
</Tooltip>
126-
</IconButton>
127-
<IconButton
128-
size="small"
129-
disabled={deadlinePlusDisabled(workspace, now ?? dayjs())}
130-
className={styles.editDeadline}
131-
onClick={onDeadlinePlus}
132-
>
133-
<Tooltip title={Language.editDeadlinePlus}>
134-
<AddBoxIcon />
135-
</Tooltip>
136-
</IconButton>
137-
</Stack>
138-
) : null
40+
const timezone = workspace.autostart_schedule
41+
? extractTimezone(workspace.autostart_schedule)
42+
: dayjs.tz.guess()
13943

14044
return (
14145
<div className={styles.schedule}>
14246
<Stack spacing={2}>
143-
<Typography variant="body1" className={styles.title}>
144-
<ScheduleIcon className={styles.scheduleIcon} />
145-
{Language.scheduleHeader(workspace)}
146-
</Typography>
14747
<div>
148-
<span className={styles.scheduleLabel}>{Language.autoStartLabel}</span>
48+
<span className={styles.scheduleLabel}>{Language.timezoneLabel}</span>
49+
<span className={styles.scheduleValue}>{timezone}</span>
50+
</div>
51+
<div>
52+
<span className={styles.scheduleLabel}>{ScheduleLanguage.autoStartLabel}</span>
14953
<span className={[styles.scheduleValue, "chromatic-ignore"].join(" ")}>
150-
{Language.autoStartDisplay(workspace.autostart_schedule)}
54+
{autoStartDisplay(workspace.autostart_schedule)}
15155
</span>
15256
</div>
15357
<div>
154-
<span className={styles.scheduleLabel}>{Language.autoStopLabel}</span>
58+
<span className={styles.scheduleLabel}>{ScheduleLanguage.autoStopLabel}</span>
15559
<Stack direction="row">
15660
<span className={[styles.scheduleValue, "chromatic-ignore"].join(" ")}>
157-
{Language.autoStopDisplay(workspace)}
61+
{autoStopDisplay(workspace)}
15862
</span>
159-
{editDeadlineButtons}
16063
</Stack>
16164
</div>
16265
<div>
@@ -177,18 +80,6 @@ const useStyles = makeStyles((theme) => ({
17780
schedule: {
17881
fontFamily: MONOSPACE_FONT_FAMILY,
17982
},
180-
title: {
181-
fontWeight: 600,
182-
183-
fontFamily: "inherit",
184-
display: "flex",
185-
alignItems: "center",
186-
},
187-
scheduleIcon: {
188-
width: 16,
189-
height: 16,
190-
marginRight: theme.spacing(1),
191-
},
19283
scheduleLabel: {
19384
fontSize: 12,
19485
textTransform: "uppercase",
@@ -198,14 +89,11 @@ const useStyles = makeStyles((theme) => ({
19889
},
19990
scheduleValue: {
20091
fontSize: 14,
201-
marginTop: theme.spacing(0.75),
92+
marginTop: theme.spacing(0.5),
20293
display: "inline-block",
20394
color: theme.palette.text.secondary,
20495
},
20596
scheduleAction: {
20697
cursor: "pointer",
20798
},
208-
editDeadline: {
209-
color: theme.palette.text.secondary,
210-
},
21199
}))

0 commit comments

Comments
 (0)