From 8e10cf7887d445876ef567582178434c3fe08287 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 20:07:41 +0000 Subject: [PATCH 1/6] feat: add stop workspace button with confirmation dialog - Add stop workspace button with square icon that replaces start button for running workspaces - Implement confirmation dialog for stop operation to prevent accidental stops - Button shows only when workspace status allows stop action - Uses existing stopWorkspace API mutation - Follows existing UI patterns for workspace actions Fixes #18298 Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- .../pages/WorkspacesPage/WorkspacesTable.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 92ba3fe7ae3fa..3a5fd22406c3b 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -18,6 +18,7 @@ import { Avatar } from "components/Avatar/Avatar"; import { AvatarData } from "components/Avatar/AvatarData"; import { AvatarDataSkeleton } from "components/Avatar/AvatarDataSkeleton"; import { Button } from "components/Button/Button"; +import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"; import { ExternalImage } from "components/ExternalImage/ExternalImage"; import { VSCodeIcon } from "components/Icons/VSCodeIcon"; import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon"; @@ -49,6 +50,7 @@ import { BanIcon, PlayIcon, RefreshCcwIcon, + SquareIcon, SquareTerminalIcon, } from "lucide-react"; import { @@ -74,6 +76,7 @@ import { type PropsWithChildren, type ReactNode, useMemo, + useState, } from "react"; import { useMutation, useQuery, useQueryClient } from "react-query"; import { useNavigate } from "react-router-dom"; @@ -491,6 +494,9 @@ const WorkspaceActionsCell: FC = ({ onError: onActionError, }); + // State for stop confirmation dialog + const [isStopConfirmOpen, setIsStopConfirmOpen] = useState(false); + const isRetrying = startWorkspaceMutation.isPending || stopWorkspaceMutation.isPending || @@ -535,6 +541,16 @@ const WorkspaceActionsCell: FC = ({ )} + {abilities.actions.includes("stop") && ( + setIsStopConfirmOpen(true)} + isLoading={stopWorkspaceMutation.isPending} + label="Stop workspace" + > + + + )} + {abilities.actions.includes("updateAndStart") && ( <> = ({ disabled={!abilities.canAcceptJobs} /> + + {/* Stop workspace confirmation dialog */} + setIsStopConfirmOpen(false)} + onConfirm={() => { + stopWorkspaceMutation.mutate({}); + setIsStopConfirmOpen(false); + }} + type="delete" + loading={stopWorkspaceMutation.isPending} + /> ); }; From cb3396327ebbf8a58243631e5cd238b89527a08f Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 20:13:04 +0000 Subject: [PATCH 2/6] feat: disable stop button during loading to prevent duplicate clicks - Add disabled prop to PrimaryActionProps interface - Implement disabled state in PrimaryAction component - Apply disabled prop to stop button when stopWorkspaceMutation is pending - Prevents accidental duplicate stop requests during operation Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- site/src/pages/WorkspacesPage/WorkspacesTable.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 3a5fd22406c3b..9c0ee1f822da3 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -545,6 +545,7 @@ const WorkspaceActionsCell: FC = ({ setIsStopConfirmOpen(true)} isLoading={stopWorkspaceMutation.isPending} + disabled={stopWorkspaceMutation.isPending} label="Stop workspace" > @@ -611,12 +612,14 @@ const WorkspaceActionsCell: FC = ({ type PrimaryActionProps = PropsWithChildren<{ label: string; isLoading?: boolean; + disabled?: boolean; onClick: () => void; }>; const PrimaryAction: FC = ({ onClick, isLoading, + disabled, label, children, }) => { @@ -624,7 +627,12 @@ const PrimaryAction: FC = ({ - From 0d6032ae6a7f59f94814416ced4cc230aacc86d1 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 20:16:39 +0000 Subject: [PATCH 3/6] fix: remove unsupported loading prop from ConfirmDialog - ConfirmDialog component doesn't accept loading prop - Fixes TypeScript compilation error in CI - Button disabled state still prevents duplicate clicks Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- site/src/pages/WorkspacesPage/WorkspacesTable.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 9c0ee1f822da3..616ead4c02662 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -603,7 +603,6 @@ const WorkspaceActionsCell: FC = ({ setIsStopConfirmOpen(false); }} type="delete" - loading={stopWorkspaceMutation.isPending} /> ); From b779d6fc1517ab4dd6a831b00b7dd70381151096 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 21:38:32 +0000 Subject: [PATCH 4/6] fix: remove disabled prop from stop workspace button Use isLoading for button disabling instead of separate disabled prop. This simplifies the component interface while maintaining the same functionality - the button is disabled when loading. Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- site/src/pages/WorkspacesPage/WorkspacesTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 616ead4c02662..abddba7f18325 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -545,7 +545,7 @@ const WorkspaceActionsCell: FC = ({ setIsStopConfirmOpen(true)} isLoading={stopWorkspaceMutation.isPending} - disabled={stopWorkspaceMutation.isPending} + label="Stop workspace" > @@ -630,7 +630,7 @@ const PrimaryAction: FC = ({ variant="outline" size="icon-lg" onClick={onClick} - disabled={disabled} + disabled={disabled || isLoading} > {children} {label} From a26067db514733fb85717f8d56674f6428df20b1 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 21:57:12 +0000 Subject: [PATCH 5/6] fix: remove empty line to fix biome formatting Remove empty line left after removing disabled prop to satisfy biome formatter requirements. Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- site/src/pages/WorkspacesPage/WorkspacesTable.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index abddba7f18325..dbfeec819ae0b 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -545,7 +545,6 @@ const WorkspaceActionsCell: FC = ({ setIsStopConfirmOpen(true)} isLoading={stopWorkspaceMutation.isPending} - label="Stop workspace" > From ec096f810181e03f4ce34828fec608bd1cbe47c5 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:24:33 +0000 Subject: [PATCH 6/6] refactor: remove unused disabled prop from PrimaryAction Remove the disabled prop from PrimaryActionProps interface and component implementation since we now only use isLoading for button disabling. Co-authored-by: matifali <10648092+matifali@users.noreply.github.com> --- site/src/pages/WorkspacesPage/WorkspacesTable.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index dbfeec819ae0b..2dc25c0a392dc 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -610,14 +610,12 @@ const WorkspaceActionsCell: FC = ({ type PrimaryActionProps = PropsWithChildren<{ label: string; isLoading?: boolean; - disabled?: boolean; onClick: () => void; }>; const PrimaryAction: FC = ({ onClick, isLoading, - disabled, label, children, }) => { @@ -629,7 +627,7 @@ const PrimaryAction: FC = ({ variant="outline" size="icon-lg" onClick={onClick} - disabled={disabled || isLoading} + disabled={isLoading} > {children} {label}