Skip to content

Commit fa2d4eb

Browse files
committed
ui: make update button stop before start
1 parent 5131129 commit fa2d4eb

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

site/src/api/api.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,7 @@ class ApiMethods {
22372237
* - Update the build parameters and check if there are missed parameters for
22382238
* the newest version
22392239
* - If there are missing parameters raise an error
2240+
* - Stop the workspace with the current template version if it is already running
22402241
* - Create a build with the latest version and updated build parameters
22412242
*/
22422243
updateWorkspace = async (
@@ -2274,6 +2275,19 @@ class ApiMethods {
22742275
throw new MissingBuildParameters(missingParameters, activeVersionId);
22752276
}
22762277

2278+
// Stop the workspace if it is already running.
2279+
if (workspace.latest_build.status === "running") {
2280+
const stopBuild = await this.stopWorkspace(workspace.id);
2281+
const awaitedStopBuild = await this.waitForBuild(stopBuild);
2282+
// If the stop is canceled halfway through, we bail.
2283+
// This is the same behaviour as restartWorkspace.
2284+
if (awaitedStopBuild?.status === "canceled") {
2285+
return Promise.reject(
2286+
new Error("Workspace stop was canceled, not proceeding with update."),
2287+
);
2288+
}
2289+
}
2290+
22772291
return this.postWorkspaceBuild(workspace.id, {
22782292
transition: "start",
22792293
template_version_id: activeVersionId,

site/src/modules/workspaces/actions.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@ import type { Workspace } from "api/typesGenerated";
66
const actionTypes = [
77
"start",
88
"starting",
9-
// Replaces start when an update is required.
9+
// Replaces start when an update is available.
1010
"updateAndStart",
11+
// Replaces start when an update is required.
12+
"updateAndStartRequireActiveVersion",
1113
"stop",
1214
"stopping",
1315
"restart",
1416
"restarting",
15-
// Replaces restart when an update is required.
17+
// Replaces restart when an update is available.
1618
"updateAndRestart",
19+
// Replaces restart when an update is required.
20+
"updateAndRestartRequireActiveVersion",
1721
"deleting",
18-
"update",
1922
"updating",
2023
"activate",
2124
"activating",
@@ -74,10 +77,10 @@ export const abilitiesByWorkspaceStatus = (
7477
const actions: ActionType[] = ["stop"];
7578

7679
if (workspace.template_require_active_version && workspace.outdated) {
77-
actions.push("updateAndRestart");
80+
actions.push("updateAndRestartRequireActiveVersion");
7881
} else {
7982
if (workspace.outdated) {
80-
actions.unshift("update");
83+
actions.unshift("updateAndRestart");
8184
}
8285
actions.push("restart");
8386
}
@@ -99,10 +102,10 @@ export const abilitiesByWorkspaceStatus = (
99102
const actions: ActionType[] = [];
100103

101104
if (workspace.template_require_active_version && workspace.outdated) {
102-
actions.push("updateAndStart");
105+
actions.push("updateAndStartRequireActiveVersion");
103106
} else {
104107
if (workspace.outdated) {
105-
actions.unshift("update");
108+
actions.unshift("updateAndStart");
106109
}
107110
actions.push("start");
108111
}
@@ -128,7 +131,7 @@ export const abilitiesByWorkspaceStatus = (
128131
}
129132

130133
if (workspace.outdated) {
131-
actions.unshift("update");
134+
actions.unshift("updateAndStart");
132135
}
133136

134137
return {

site/src/pages/WorkspacePage/WorkspaceActions/Buttons.tsx

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,39 @@ export interface ActionButtonProps {
2121
tooltipText?: string;
2222
}
2323

24-
export const UpdateButton: FC<ActionButtonProps> = ({
24+
export const UpdateAndStartButton: FC<ActionButtonProps> = ({
2525
handleAction,
2626
loading,
2727
}) => {
2828
return (
29-
<TopbarButton
30-
disabled={loading}
31-
data-testid="workspace-update-button"
32-
onClick={() => handleAction()}
33-
>
34-
<CloudIcon />
35-
{loading ? <>Updating&hellip;</> : <>Update&hellip;</>}
36-
</TopbarButton>
29+
<Tooltip title="Start workspace with the latest template version.">
30+
<TopbarButton
31+
disabled={loading}
32+
data-testid="workspace-update-button"
33+
onClick={() => handleAction()}
34+
>
35+
<CirclePlayIcon />
36+
{loading ? <>Updating&hellip;</> : <>Update&hellip;</>}
37+
</TopbarButton>
38+
</Tooltip>
39+
);
40+
};
41+
42+
export const UpdateAndRestartButton: FC<ActionButtonProps> = ({
43+
handleAction,
44+
loading,
45+
}) => {
46+
return (
47+
<Tooltip title="Stop workspace, if running, and restart it with the latest template version.">
48+
<TopbarButton
49+
disabled={loading}
50+
data-testid="workspace-update-and-restart-button"
51+
onClick={() => handleAction()}
52+
>
53+
<RotateCcwIcon />
54+
{loading ? <>Updating&hellip;</> : <>Update and restart&hellip;</>}
55+
</TopbarButton>
56+
</Tooltip>
3757
);
3858
};
3959

@@ -84,9 +104,9 @@ export const StartButton: FC<ActionButtonPropsWithWorkspace> = ({
84104
);
85105
};
86106

87-
export const UpdateAndStartButton: FC<ActionButtonProps> = ({
88-
handleAction,
89-
}) => {
107+
export const UpdateAndStartButtonRequireActiveVersion: FC<
108+
ActionButtonProps
109+
> = ({ handleAction }) => {
90110
return (
91111
<Tooltip title="This template requires automatic updates on workspace startup. Contact your administrator if you want to preserve the template version.">
92112
<TopbarButton onClick={() => handleAction()}>
@@ -138,9 +158,9 @@ export const RestartButton: FC<ActionButtonPropsWithWorkspace> = ({
138158
);
139159
};
140160

141-
export const UpdateAndRestartButton: FC<ActionButtonProps> = ({
142-
handleAction,
143-
}) => {
161+
export const UpdateAndRestartButtonRequireActiveVersion: FC<
162+
ActionButtonProps
163+
> = ({ handleAction }) => {
144164
return (
145165
<Tooltip title="This template requires automatic updates on workspace startup. Contact your administrator if you want to preserve the template version.">
146166
<TopbarButton onClick={() => handleAction()}>

site/src/pages/WorkspacePage/WorkspaceActions/WorkspaceActions.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ import {
1818
RestartButton,
1919
StartButton,
2020
StopButton,
21+
UpdateAndRestartButtonRequireActiveVersion,
2122
UpdateAndRestartButton,
23+
UpdateAndStartButtonRequireActiveVersion,
2224
UpdateAndStartButton,
23-
UpdateButton,
2425
} from "./Buttons";
2526
import { DebugButton } from "./DebugButton";
2627
import { RetryButton } from "./RetryButton";
@@ -81,10 +82,15 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
8182

8283
// A mapping of button type to the corresponding React component
8384
const buttonMapping: Record<ActionType, ReactNode> = {
84-
update: <UpdateButton handleAction={handleUpdate} />,
8585
updateAndStart: <UpdateAndStartButton handleAction={handleUpdate} />,
86+
updateAndStartRequireActiveVersion: (
87+
<UpdateAndStartButtonRequireActiveVersion handleAction={handleUpdate} />
88+
),
8689
updateAndRestart: <UpdateAndRestartButton handleAction={handleUpdate} />,
87-
updating: <UpdateButton loading handleAction={handleUpdate} />,
90+
updateAndRestartRequireActiveVersion: (
91+
<UpdateAndRestartButtonRequireActiveVersion handleAction={handleUpdate} />
92+
),
93+
updating: <UpdateAndStartButton loading handleAction={handleUpdate} />,
8894
start: (
8995
<StartButton
9096
workspace={workspace}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy