mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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 https://github.com/coder/coder/issues/20233
This commit is contained in:
@@ -320,6 +320,60 @@ export const ActivePreview: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const WorkspaceStarting: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
spyOn(API, "startWorkspace").mockResolvedValue(
|
||||
MockStartingWorkspace.latest_build,
|
||||
);
|
||||
},
|
||||
parameters: {
|
||||
reactRouter: reactRouterParameters({
|
||||
location: {
|
||||
pathParams: {
|
||||
username: MockStoppedWorkspace.owner_name,
|
||||
workspace: MockStoppedWorkspace.name,
|
||||
},
|
||||
},
|
||||
routing: {
|
||||
path: "/tasks/:username/:workspace",
|
||||
},
|
||||
}),
|
||||
queries: [
|
||||
{
|
||||
key: [
|
||||
"tasks",
|
||||
MockStoppedWorkspace.owner_name,
|
||||
MockStoppedWorkspace.name,
|
||||
],
|
||||
data: {
|
||||
prompt: "Create competitors page",
|
||||
workspace: MockStoppedWorkspace,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: ["workspace", MockStoppedWorkspace.id, "parameters"],
|
||||
data: {
|
||||
templateVersionRichParameters: [],
|
||||
buildParameters: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const startButton = await canvas.findByText("Start workspace");
|
||||
expect(startButton).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(startButton);
|
||||
|
||||
await waitFor(async () => {
|
||||
expect(API.startWorkspace).toBeCalled();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const WorkspaceStartFailure: Story = {
|
||||
decorators: [withGlobalSnackbar],
|
||||
beforeEach: () => {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { displayError } from "components/GlobalSnackbar/utils";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import { ScrollArea } from "components/ScrollArea/ScrollArea";
|
||||
import { Spinner } from "components/Spinner/Spinner";
|
||||
import { useWorkspaceBuildLogs } from "hooks/useWorkspaceBuildLogs";
|
||||
import { ArrowLeftIcon, RotateCcwIcon } from "lucide-react";
|
||||
import { AgentLogs } from "modules/resources/AgentLogs/AgentLogs";
|
||||
@@ -206,6 +207,11 @@ const WorkspaceNotRunning: FC<WorkspaceNotRunningProps> = ({ task }) => {
|
||||
},
|
||||
});
|
||||
|
||||
// After requesting a workspace start, it may take a while to become ready.
|
||||
// Show a loading state in the meantime.
|
||||
const isWaitingForStart =
|
||||
mutateStartWorkspace.isPending || mutateStartWorkspace.isSuccess;
|
||||
|
||||
const apiError = isApiError(mutateStartWorkspace.error)
|
||||
? mutateStartWorkspace.error
|
||||
: undefined;
|
||||
@@ -223,16 +229,15 @@ const WorkspaceNotRunning: FC<WorkspaceNotRunningProps> = ({ task }) => {
|
||||
<div className="flex flex-row mt-4 gap-4">
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={mutateStartWorkspace.isPending}
|
||||
disabled={isWaitingForStart}
|
||||
onClick={() => {
|
||||
mutateStartWorkspace.mutate({
|
||||
buildParameters: parameters?.buildParameters,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{mutateStartWorkspace.isPending
|
||||
? "Starting workspace..."
|
||||
: "Start workspace"}
|
||||
<Spinner loading={isWaitingForStart} />
|
||||
Start workspace
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user