Skip to content

Commit be86750

Browse files
committed
Add update
1 parent 5dcec61 commit be86750

File tree

7 files changed

+74
-29
lines changed

7 files changed

+74
-29
lines changed

site/src/components/Workspace/Workspace.stories.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { action } from "@storybook/addon-actions"
22
import { Story } from "@storybook/react"
33
import React from "react"
4-
import { MockOrganization, MockTemplate, MockWorkspace } from "../../testHelpers"
4+
import { MockOrganization, MockOutdatedWorkspace, MockTemplate, MockWorkspace } from "../../testHelpers"
55
import { Workspace, WorkspaceProps } from "./Workspace"
66

77
export default {
@@ -37,3 +37,6 @@ Error.args = { ...Started.args, workspaceStatus: "error" }
3737

3838
export const NoBreadcrumb = Template.bind({})
3939
NoBreadcrumb.args = { ...Started.args, template: undefined }
40+
41+
export const Outdated = Template.bind({})
42+
Outdated.args = { ...Started.args, workspace: MockOutdatedWorkspace }

site/src/components/Workspace/Workspace.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface WorkspaceProps {
1414
handleStart: () => void
1515
handleStop: () => void
1616
handleRetry: () => void
17+
handleUpdate: () => void
1718
workspaceStatus: WorkspaceStatus
1819
}
1920

@@ -27,6 +28,7 @@ export const Workspace: React.FC<WorkspaceProps> = ({
2728
handleStart,
2829
handleStop,
2930
handleRetry,
31+
handleUpdate,
3032
workspaceStatus,
3133
}) => {
3234
const styles = useStyles()
@@ -41,6 +43,7 @@ export const Workspace: React.FC<WorkspaceProps> = ({
4143
handleStart={handleStart}
4244
handleStop={handleStop}
4345
handleRetry={handleRetry}
46+
handleUpdate={handleUpdate}
4447
workspaceStatus={workspaceStatus}
4548
/>
4649
<div className={styles.horizontal}>

site/src/components/WorkspaceStatusBar/WorkspaceStatusBar.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface WorkspaceStatusBarProps {
3232
handleStart: () => void
3333
handleStop: () => void
3434
handleRetry: () => void
35+
handleUpdate: () => void
3536
workspaceStatus: WorkspaceStatus
3637
}
3738

@@ -45,6 +46,7 @@ export const WorkspaceStatusBar: React.FC<WorkspaceStatusBarProps> = ({
4546
handleStart,
4647
handleStop,
4748
handleRetry,
49+
handleUpdate,
4850
workspaceStatus,
4951
}) => {
5052
const styles = useStyles()
@@ -102,7 +104,12 @@ export const WorkspaceStatusBar: React.FC<WorkspaceStatusBarProps> = ({
102104
</Button>
103105
)}
104106

105-
{workspace.outdated && <Button color="primary">{Language.update}</Button>}
107+
{/* Workspace will not update while another job is in progress so hide the button until it's usable */}
108+
{workspace.outdated && ["started", "stopped", "error"].includes(workspaceStatus) && (
109+
<Button onClick={handleUpdate} color="primary">
110+
{Language.update}
111+
</Button>
112+
)}
106113
</div>
107114
</div>
108115
</Stack>

site/src/pages/WorkspacePage/WorkspacePage.test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { rest } from "msw"
33
import React from "react"
44
import {
55
MockFailedWorkspace,
6+
MockOutdatedWorkspace,
67
MockStoppedWorkspace,
78
MockTemplate,
89
MockWorkspace,
@@ -62,4 +63,16 @@ describe("Workspace Page", () => {
6263
const laterStatus = await screen.findByText("Building")
6364
expect(laterStatus).toBeDefined()
6465
})
66+
it("restarts the workspace when the user presses Update", async () => {
67+
renderWithAuth(<WorkspacePage />, { route: `/workspaces/${MockWorkspace.id}`, path: "/workspaces/:workspace" })
68+
server.use(
69+
rest.get(`/api/v2/workspaces/${MockWorkspace.id}`, (req, res, ctx) => {
70+
return res(ctx.status(200), ctx.json(MockOutdatedWorkspace))
71+
}),
72+
)
73+
const updateButton = await screen.findByText("Update")
74+
updateButton.click()
75+
const status = await screen.findByText("Building")
76+
expect(status).toBeDefined()
77+
})
6578
})

site/src/pages/WorkspacePage/WorkspacePage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export const WorkspacePage: React.FC = () => {
5454
handleStart={() => workspaceSend("START")}
5555
handleStop={() => workspaceSend("STOP")}
5656
handleRetry={() => workspaceSend("RETRY")}
57+
handleUpdate={() => workspaceSend("UPDATE")}
5758
workspaceStatus={workspaceStatus}
5859
/>
5960
</Stack>

site/src/testHelpers/entities.ts

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -167,31 +167,11 @@ export const MockWorkspace: Workspace = {
167167
latest_build: MockWorkspaceBuild,
168168
}
169169

170-
export const MockStoppedWorkspace: Workspace = {
171-
id: "test-workspace",
172-
name: "Test-Workspace",
173-
created_at: "",
174-
updated_at: "",
175-
template_id: MockTemplate.id,
176-
outdated: false,
177-
owner_id: MockUser.id,
178-
autostart_schedule: MockWorkspaceAutostartEnabled.schedule,
179-
autostop_schedule: MockWorkspaceAutostopEnabled.schedule,
180-
latest_build: MockWorkspaceBuildStop,
181-
}
170+
export const MockStoppedWorkspace: Workspace = { ...MockWorkspace, latest_build: MockWorkspaceBuildStop }
182171

183-
export const MockFailedWorkspace: Workspace = {
184-
id: "test-workspace",
185-
name: "Test-Workspace",
186-
created_at: "",
187-
updated_at: "",
188-
template_id: MockTemplate.id,
189-
outdated: false,
190-
owner_id: MockUser.id,
191-
autostart_schedule: MockWorkspaceAutostartEnabled.schedule,
192-
autostop_schedule: MockWorkspaceAutostopEnabled.schedule,
193-
latest_build: MockFailedWorkspaceBuild,
194-
}
172+
export const MockFailedWorkspace: Workspace = { ...MockWorkspace, latest_build: MockFailedWorkspaceBuild }
173+
174+
export const MockOutdatedWorkspace: Workspace = { ...MockWorkspace, outdated: true }
195175

196176
export const MockWorkspaceAgent: WorkspaceAgent = {
197177
id: "test-workspace-agent",

site/src/xServices/workspace/workspaceXService.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,25 @@ interface WorkspaceContext {
77
workspace?: Types.Workspace
88
template?: Types.Template
99
organization?: Types.Organization
10+
build?: TypesGen.WorkspaceBuild
1011
getWorkspaceError?: Error | unknown
1112
getTemplateError?: Error | unknown
1213
getOrganizationError?: Error | unknown
1314
// error enqueuing a ProvisionerJob to create a new WorkspaceBuild
1415
jobError?: Error | unknown
1516
// error creating a new WorkspaceBuild
1617
buildError?: Error | unknown
18+
// these are separate from get X errors because they don't make the page unusable
19+
refreshWorkspaceError: Error | unknown
20+
refreshTemplateError: Error | unknown
1721
}
1822

1923
type WorkspaceEvent =
2024
| { type: "GET_WORKSPACE"; workspaceId: string }
2125
| { type: "START" }
2226
| { type: "STOP" }
2327
| { type: "RETRY" }
28+
| { type: "UPDATE" }
2429
| { type: "REFRESH_WORKSPACE" }
2530

2631
export const workspaceMachine = createMachine(
@@ -60,12 +65,13 @@ export const workspaceMachine = createMachine(
6065
tags: "loading",
6166
},
6267
gettingWorkspace: {
68+
entry: ["clearGetWorkspaceError", "clearContext"],
6369
invoke: {
6470
src: "getWorkspace",
6571
id: "getWorkspace",
6672
onDone: {
6773
target: "ready",
68-
actions: ["assignWorkspace", "clearGetWorkspaceError"],
74+
actions: ["assignWorkspace"],
6975
},
7076
onError: {
7177
target: "error",
@@ -116,6 +122,9 @@ export const workspaceMachine = createMachine(
116122
},
117123
build: {
118124
initial: "dispatch",
125+
on: {
126+
UPDATE: "#workspaceState.ready.build.refreshingTemplate",
127+
},
119128
states: {
120129
dispatch: {
121130
always: [
@@ -156,7 +165,7 @@ export const workspaceMachine = createMachine(
156165
src: "startWorkspace",
157166
onDone: {
158167
target: "buildingStart",
159-
actions: "clearJobError",
168+
actions: ["assignBuild", "clearJobError"],
160169
},
161170
onError: {
162171
target: "error",
@@ -169,7 +178,7 @@ export const workspaceMachine = createMachine(
169178
invoke: {
170179
id: "stopWorkspace",
171180
src: "stopWorkspace",
172-
onDone: { target: "buildingStop", actions: "clearJobError" },
181+
onDone: { target: "buildingStop", actions: ["assignBuild", "clearJobError"] },
173182
onError: {
174183
target: "error",
175184
actions: "assignJobError",
@@ -239,6 +248,15 @@ export const workspaceMachine = createMachine(
239248
},
240249
tags: ["buildLoading", "stopping"],
241250
},
251+
refreshingTemplate: {
252+
entry: "clearRefreshTemplateError",
253+
invoke: {
254+
id: "refreshTemplate",
255+
src: "getTemplate",
256+
onDone: { target: "#workspaceState.ready.build.requestingStart", actions: "assignTemplate" },
257+
onError: { target: "error", actions: "assignRefreshTemplateError" },
258+
},
259+
},
242260
error: {
243261
on: {
244262
RETRY: [
@@ -266,6 +284,14 @@ export const workspaceMachine = createMachine(
266284
},
267285
{
268286
actions: {
287+
// Clear data about an old workspace when looking at a new one
288+
clearContext: () =>
289+
assign({
290+
workspace: undefined,
291+
template: undefined,
292+
organization: undefined,
293+
build: undefined,
294+
}),
269295
assignWorkspace: assign({
270296
workspace: (_, event) => event.data,
271297
}),
@@ -287,6 +313,10 @@ export const workspaceMachine = createMachine(
287313
getOrganizationError: (_, event) => event.data,
288314
}),
289315
clearGetOrganizationError: (context) => assign({ ...context, getOrganizationError: undefined }),
316+
assignBuild: (_, event) =>
317+
assign({
318+
build: event.data,
319+
}),
290320
assignJobError: (_, event) =>
291321
assign({
292322
jobError: event.data,
@@ -311,6 +341,14 @@ export const workspaceMachine = createMachine(
311341
assign({
312342
refreshWorkspaceError: undefined,
313343
}),
344+
assignRefreshTemplateError: (_, event) =>
345+
assign({
346+
refreshTemplateError: event.data,
347+
}),
348+
clearRefreshTemplateError: (_) =>
349+
assign({
350+
refreshTemplateError: undefined,
351+
}),
314352
},
315353
guards: {
316354
workspaceIsStarted: (context) =>

0 commit comments

Comments
 (0)