Skip to content

Commit a6cbf34

Browse files
committed
added restart hook
1 parent 4079fc5 commit a6cbf34

File tree

5 files changed

+82
-9
lines changed

5 files changed

+82
-9
lines changed

site/src/components/Workspace/Workspace.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface WorkspaceProps {
4141
}
4242
handleStart: () => void
4343
handleStop: () => void
44-
handleRestart: () => void
44+
handleRestart: any
4545
handleDelete: () => void
4646
handleUpdate: () => void
4747
handleCancel: () => void

site/src/components/WorkspaceActions/Buttons.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { LoadingButton } from "components/LoadingButton/LoadingButton"
88
import { FC, PropsWithChildren } from "react"
99
import { useTranslation } from "react-i18next"
1010
import { makeStyles } from "@material-ui/core/styles"
11+
// import { UseMutateFunction } from "@tanstack/react-query"
12+
// import { WorkspaceBuild } from "api/typesGenerated"
1113

1214
interface WorkspaceAction {
1315
handleAction: () => void
@@ -67,9 +69,7 @@ export const StopButton: FC<PropsWithChildren<WorkspaceAction>> = ({
6769
)
6870
}
6971

70-
export const RestartButton: FC<PropsWithChildren<WorkspaceAction>> = ({
71-
handleAction,
72-
}) => {
72+
export const RestartButton: FC<PropsWithChildren<any>> = ({ handleAction }) => {
7373
const { t } = useTranslation("workspacePage")
7474
const styles = useStyles()
7575

site/src/components/WorkspaceActions/WorkspaceActions.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { makeStyles } from "@material-ui/core/styles"
55
import MoreVertOutlined from "@material-ui/icons/MoreVertOutlined"
66
import { FC, ReactNode, useRef, useState } from "react"
77
import { useTranslation } from "react-i18next"
8-
import { WorkspaceStatus } from "../../api/typesGenerated"
8+
import { WorkspaceStatus } from "api/typesGenerated"
99
import {
1010
ActionLoadingButton,
1111
CancelButton,
@@ -29,7 +29,7 @@ export interface WorkspaceActionsProps {
2929
isOutdated: boolean
3030
handleStart: () => void
3131
handleStop: () => void
32-
handleRestart: () => void
32+
handleRestart: any
3333
handleDelete: () => void
3434
handleUpdate: () => void
3535
handleCancel: () => void
@@ -133,7 +133,9 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
133133
(isUpdating
134134
? buttonMapping[ButtonTypesEnum.updating]
135135
: buttonMapping[ButtonTypesEnum.update])}
136-
{actionsByStatus.map((action) => buttonMapping[action])}
136+
{actionsByStatus.map((action) => (
137+
<span key={action}>{buttonMapping[action]}</span>
138+
))}
137139
{canCancel && <CancelButton handleAction={handleCancel} />}
138140
<div>
139141
<Button

site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { UpdateBuildParametersDialog } from "./UpdateBuildParametersDialog"
3030
import { ChangeVersionDialog } from "./ChangeVersionDialog"
3131
import { useQuery } from "@tanstack/react-query"
3232
import { getTemplateVersions } from "api/api"
33+
import { useRestartWorkspace } from "./hooks"
3334

3435
interface WorkspaceReadyPageProps {
3536
workspaceState: StateFrom<typeof workspaceMachine>
@@ -77,6 +78,12 @@ export const WorkspaceReadyPage = ({
7778
enabled: changeVersionDialogOpen,
7879
})
7980

81+
const [restartBuildError, setRestartBuildError] = useState<
82+
Error | unknown | undefined
83+
>(undefined)
84+
85+
const { mutate: restartWorkspace } = useRestartWorkspace(setRestartBuildError)
86+
8087
// keep banner machine in sync with workspace
8188
useEffect(() => {
8289
bannerSend({ type: "REFRESH_WORKSPACE", workspace })
@@ -123,7 +130,7 @@ export const WorkspaceReadyPage = ({
123130
workspace={workspace}
124131
handleStart={() => workspaceSend({ type: "START" })}
125132
handleStop={() => workspaceSend({ type: "STOP" })}
126-
handleRestart={() => workspaceSend({ type: "START" })}
133+
handleRestart={() => restartWorkspace(workspace.id)}
127134
handleDelete={() => workspaceSend({ type: "ASK_DELETE" })}
128135
handleUpdate={() => workspaceSend({ type: "UPDATE" })}
129136
handleCancel={() => workspaceSend({ type: "CANCEL" })}
@@ -141,7 +148,7 @@ export const WorkspaceReadyPage = ({
141148
hideVSCodeDesktopButton={featureVisibility["browser_only"]}
142149
workspaceErrors={{
143150
[WorkspaceErrors.GET_BUILDS_ERROR]: getBuildsError,
144-
[WorkspaceErrors.BUILD_ERROR]: buildError,
151+
[WorkspaceErrors.BUILD_ERROR]: buildError ?? restartBuildError,
145152
[WorkspaceErrors.CANCELLATION_ERROR]: cancellationError,
146153
}}
147154
buildInfo={buildInfo}

site/src/pages/WorkspacePage/hooks.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { useMutation } from "@tanstack/react-query"
2+
import {
3+
stopWorkspace,
4+
getWorkspaceBuildByNumber,
5+
startWorkspace,
6+
} from "api/api"
7+
import { delay } from "utils/delay"
8+
import { ProvisionerJob, WorkspaceBuild } from "api/typesGenerated"
9+
10+
function waitForStop(
11+
username: string,
12+
workspaceName: string,
13+
buildNumber: string,
14+
) {
15+
return new Promise((res, reject) => {
16+
void (async () => {
17+
let latestJobInfo: ProvisionerJob | undefined = undefined
18+
19+
while (latestJobInfo?.status !== "succeeded") {
20+
const { job } = await getWorkspaceBuildByNumber(
21+
username,
22+
workspaceName,
23+
buildNumber,
24+
)
25+
latestJobInfo = job
26+
27+
if (
28+
["failed", "canceled"].some((status) =>
29+
latestJobInfo?.status.includes(status),
30+
)
31+
) {
32+
return reject(latestJobInfo)
33+
}
34+
35+
await delay(1000)
36+
}
37+
38+
return res(latestJobInfo)
39+
})()
40+
})
41+
}
42+
43+
export const useRestartWorkspace = (
44+
setRestartBuildError: (arg: Error | unknown | undefined) => void,
45+
) => {
46+
return useMutation({
47+
mutationFn: stopWorkspace,
48+
onSuccess: async (data) => {
49+
try {
50+
await waitForStop(
51+
data.workspace_owner_name,
52+
data.workspace_name,
53+
String(data.build_number),
54+
)
55+
await startWorkspace(data.workspace_id, data.template_version_id)
56+
} catch (error) {
57+
if ((error as WorkspaceBuild).status === "canceled") {
58+
return
59+
}
60+
setRestartBuildError(error)
61+
}
62+
},
63+
})
64+
}

0 commit comments

Comments
 (0)