diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 92ba3fe7ae3fa..2dc25c0a392dc 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" + /> ); }; @@ -593,7 +623,12 @@ const PrimaryAction: FC = ({ -