Skip to content

Commit 24dddd5

Browse files
author
Bruno Quaresma
authored
fix: keep button in loading state after start request is made (#20294)
After requesting a workspace start, it may take a while to become ready. Show a loading state in the meantime. Fixes #20233
1 parent 05b037b commit 24dddd5

2 files changed

Lines changed: 63 additions & 4 deletions

File tree

‎site/src/pages/TaskPage/TaskPage.stories.tsx‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,60 @@ export const ActivePreview: Story = {
320320
},
321321
};
322322

323+
export const WorkspaceStarting: Story = {
324+
decorators: [withGlobalSnackbar],
325+
beforeEach: () => {
326+
spyOn(API, "startWorkspace").mockResolvedValue(
327+
MockStartingWorkspace.latest_build,
328+
);
329+
},
330+
parameters: {
331+
reactRouter: reactRouterParameters({
332+
location: {
333+
pathParams: {
334+
username: MockStoppedWorkspace.owner_name,
335+
workspace: MockStoppedWorkspace.name,
336+
},
337+
},
338+
routing: {
339+
path: "/tasks/:username/:workspace",
340+
},
341+
}),
342+
queries: [
343+
{
344+
key: [
345+
"tasks",
346+
MockStoppedWorkspace.owner_name,
347+
MockStoppedWorkspace.name,
348+
],
349+
data: {
350+
prompt: "Create competitors page",
351+
workspace: MockStoppedWorkspace,
352+
},
353+
},
354+
{
355+
key: ["workspace", MockStoppedWorkspace.id, "parameters"],
356+
data: {
357+
templateVersionRichParameters: [],
358+
buildParameters: [],
359+
},
360+
},
361+
],
362+
},
363+
play: async ({ canvasElement }) => {
364+
const canvas = within(canvasElement);
365+
366+
const startButton = await canvas.findByText("Start workspace");
367+
expect(startButton).toBeInTheDocument();
368+
369+
await userEvent.click(startButton);
370+
371+
await waitFor(async () => {
372+
expect(API.startWorkspace).toBeCalled();
373+
});
374+
},
375+
};
376+
323377
export const WorkspaceStartFailure: Story = {
324378
decorators: [withGlobalSnackbar],
325379
beforeEach: () => {

‎site/src/pages/TaskPage/TaskPage.tsx‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { displayError } from "components/GlobalSnackbar/utils";
1313
import { Loader } from "components/Loader/Loader";
1414
import { Margins } from "components/Margins/Margins";
1515
import { ScrollArea } from "components/ScrollArea/ScrollArea";
16+
import { Spinner } from "components/Spinner/Spinner";
1617
import { useWorkspaceBuildLogs } from "hooks/useWorkspaceBuildLogs";
1718
import { ArrowLeftIcon, RotateCcwIcon } from "lucide-react";
1819
import { AgentLogs } from "modules/resources/AgentLogs/AgentLogs";
@@ -206,6 +207,11 @@ const WorkspaceNotRunning: FC<WorkspaceNotRunningProps> = ({ task }) => {
206207
},
207208
});
208209

210+
// After requesting a workspace start, it may take a while to become ready.
211+
// Show a loading state in the meantime.
212+
const isWaitingForStart =
213+
mutateStartWorkspace.isPending || mutateStartWorkspace.isSuccess;
214+
209215
const apiError = isApiError(mutateStartWorkspace.error)
210216
? mutateStartWorkspace.error
211217
: undefined;
@@ -223,16 +229,15 @@ const WorkspaceNotRunning: FC<WorkspaceNotRunningProps> = ({ task }) => {
223229
<div className="flex flex-row mt-4 gap-4">
224230
<Button
225231
size="sm"
226-
disabled={mutateStartWorkspace.isPending}
232+
disabled={isWaitingForStart}
227233
onClick={() => {
228234
mutateStartWorkspace.mutate({
229235
buildParameters: parameters?.buildParameters,
230236
});
231237
}}
232238
>
233-
{mutateStartWorkspace.isPending
234-
? "Starting workspace..."
235-
: "Start workspace"}
239+
<Spinner loading={isWaitingForStart} />
240+
Start workspace
236241
</Button>
237242
</div>
238243
</div>

0 commit comments

Comments
 (0)