Skip to content

Commit c4d85e5

Browse files
committed
1 parent 276dffc commit c4d85e5

File tree

3 files changed

+118
-26
lines changed

3 files changed

+118
-26
lines changed

site/src/pages/WorkspacePage/WorkspaceScheduleControls.tsx

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -138,26 +138,27 @@ interface AutoStopDisplayProps {
138138
}
139139

140140
const AutoStopDisplay: FC<AutoStopDisplayProps> = ({ workspace, template }) => {
141-
const display = autostopDisplay(workspace, template);
141+
const { message, tooltip } = autostopDisplay(workspace, template);
142+
143+
const display = (
144+
<ScheduleSettingsLink
145+
data-testid="schedule-controls-autostop"
146+
css={
147+
isShutdownSoon(workspace) &&
148+
((theme) => ({
149+
color: `${theme.palette.warning.light} !important`,
150+
}))
151+
}
152+
>
153+
{message}
154+
</ScheduleSettingsLink>
155+
);
142156

143-
if (display.tooltip) {
144-
return (
145-
<Tooltip title={display.tooltip}>
146-
<ScheduleSettingsLink
147-
css={
148-
isShutdownSoon(workspace) &&
149-
((theme) => ({
150-
color: `${theme.palette.warning.light} !important`,
151-
}))
152-
}
153-
>
154-
{display.message}
155-
</ScheduleSettingsLink>
156-
</Tooltip>
157-
);
157+
if (tooltip) {
158+
return <Tooltip title={tooltip}>{display}</Tooltip>;
158159
}
159160

160-
return <ScheduleSettingsLink>{display.message}</ScheduleSettingsLink>;
161+
return display;
161162
};
162163

163164
const ScheduleSettingsLink = forwardRef<HTMLAnchorElement, LinkProps>(

site/src/pages/WorkspacePage/WorkspaceTopbar.stories.tsx

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Meta, StoryObj } from "@storybook/react";
2+
import { expect, userEvent, waitFor, within, screen } from "@storybook/test";
23
import {
34
MockTemplate,
45
MockTemplateVersion,
@@ -42,7 +43,7 @@ export const Example: Story = {};
4243
export const Outdated: Story = {
4344
args: {
4445
workspace: {
45-
...MockWorkspace,
46+
...baseWorkspace,
4647
outdated: true,
4748
},
4849
},
@@ -83,7 +84,7 @@ export const Dormant: Story = {
8384
},
8485
};
8586

86-
export const WithDeadline: Story = {
87+
export const WithExceededDeadline: Story = {
8788
args: {
8889
workspace: {
8990
...MockWorkspace,
@@ -95,6 +96,85 @@ export const WithDeadline: Story = {
9596
},
9697
};
9798

99+
const in30Minutes = new Date();
100+
in30Minutes.setMinutes(in30Minutes.getMinutes() + 30);
101+
export const WithApproachingDeadline: Story = {
102+
args: {
103+
workspace: {
104+
...MockWorkspace,
105+
latest_build: {
106+
...MockWorkspace.latest_build,
107+
deadline: in30Minutes.toISOString(),
108+
},
109+
},
110+
},
111+
play: async ({ canvasElement, step }) => {
112+
const canvas = within(canvasElement);
113+
114+
await step("activate hover trigger", async () => {
115+
await userEvent.hover(canvas.getByTestId("schedule-controls-autostop"));
116+
await waitFor(() =>
117+
expect(screen.getByRole("tooltip")).toHaveTextContent(
118+
/this workspace has enabled autostop/,
119+
),
120+
);
121+
});
122+
},
123+
};
124+
125+
const in8Hours = new Date();
126+
in8Hours.setHours(in8Hours.getHours() + 8);
127+
export const WithFarAwayDeadline: Story = {
128+
args: {
129+
workspace: {
130+
...MockWorkspace,
131+
latest_build: {
132+
...MockWorkspace.latest_build,
133+
deadline: in8Hours.toISOString(),
134+
},
135+
},
136+
},
137+
play: async ({ canvasElement, step }) => {
138+
const canvas = within(canvasElement);
139+
140+
await step("activate hover trigger", async () => {
141+
await userEvent.hover(canvas.getByTestId("schedule-controls-autostop"));
142+
await waitFor(() =>
143+
expect(screen.getByRole("tooltip")).toHaveTextContent(
144+
/this workspace has enabled autostop/,
145+
),
146+
);
147+
});
148+
},
149+
};
150+
export const WithFarAwayDeadlineRequiredByTemplate: Story = {
151+
args: {
152+
workspace: {
153+
...MockWorkspace,
154+
latest_build: {
155+
...MockWorkspace.latest_build,
156+
deadline: in8Hours.toISOString(),
157+
},
158+
},
159+
template: {
160+
...MockTemplate,
161+
allow_user_autostop: false,
162+
},
163+
},
164+
play: async ({ canvasElement, step }) => {
165+
const canvas = within(canvasElement);
166+
167+
await step("activate hover trigger", async () => {
168+
await userEvent.hover(canvas.getByTestId("schedule-controls-autostop"));
169+
await waitFor(() =>
170+
expect(screen.getByRole("tooltip")).toHaveTextContent(
171+
/template has an autostop requirment/,
172+
),
173+
);
174+
});
175+
},
176+
};
177+
98178
export const WithQuota: Story = {
99179
parameters: {
100180
queries: [

site/src/utils/schedule.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import utc from "dayjs/plugin/utc";
99
import { type ReactNode } from "react";
1010
import { Link as RouterLink } from "react-router-dom";
1111
import type { Template, Workspace } from "api/typesGenerated";
12+
import {
13+
HelpTooltipText,
14+
HelpTooltipTitle,
15+
} from "components/HelpTooltip/HelpTooltip";
1216
import { isWorkspaceOn } from "./workspace";
1317

1418
// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
@@ -114,15 +118,19 @@ export const autostopDisplay = (
114118
};
115119
} else {
116120
const deadlineTz = deadline.tz(dayjs.tz.guess());
117-
let reason: ReactNode = ` because the ${template.display_name} template has an autostop requirment`;
121+
let title = (
122+
<HelpTooltipTitle>Template Autostop requirement</HelpTooltipTitle>
123+
);
124+
let reason: ReactNode = ` because the ${template.display_name} template has an autostop requirment.`;
118125
if (template.autostop_requirement && template.allow_user_autostop) {
126+
title = <HelpTooltipTitle>Autostop schedule</HelpTooltipTitle>;
119127
reason = (
120128
<>
121129
{" "}
122-
because this workspace has enabled autostop. You can disable it from
123-
the{" "}
130+
because this workspace has enabled autostop. You can disable
131+
autostop from this workspace's{" "}
124132
<Link component={RouterLink} to="settings/schedule">
125-
Workspace Schedule settings page
133+
schedule settings
126134
</Link>
127135
.
128136
</>
@@ -132,9 +140,12 @@ export const autostopDisplay = (
132140
message: `Stop ${deadlineTz.fromNow()}`,
133141
tooltip: (
134142
<>
135-
This workspace will be stopped on{" "}
136-
{deadlineTz.format("MMMM D, YYYY [at] h:mm A")}
137-
{reason}
143+
{title}
144+
<HelpTooltipText>
145+
This workspace will be stopped on{" "}
146+
{deadlineTz.format("MMMM D [at] h:mm A")}
147+
{reason}
148+
</HelpTooltipText>
138149
</>
139150
),
140151
};

0 commit comments

Comments
 (0)