mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
feat(site): show "update and start" button when update is forced (#13334)
This commit is contained in:
@@ -117,10 +117,8 @@ export const RestartButton: FC<ActionButtonPropsWithWorkspace> = ({
|
||||
handleAction,
|
||||
loading,
|
||||
workspace,
|
||||
disabled,
|
||||
tooltipText,
|
||||
}) => {
|
||||
const buttonContent = (
|
||||
return (
|
||||
<ButtonGroup
|
||||
variant="outlined"
|
||||
css={{
|
||||
@@ -129,13 +127,12 @@ export const RestartButton: FC<ActionButtonPropsWithWorkspace> = ({
|
||||
borderLeft: "1px solid #FFF",
|
||||
},
|
||||
}}
|
||||
disabled={disabled}
|
||||
>
|
||||
<TopbarButton
|
||||
startIcon={<ReplayIcon />}
|
||||
onClick={() => handleAction()}
|
||||
data-testid="workspace-restart-button"
|
||||
disabled={disabled || loading}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? <>Restarting…</> : <>Restart…</>}
|
||||
</TopbarButton>
|
||||
@@ -147,11 +144,20 @@ export const RestartButton: FC<ActionButtonPropsWithWorkspace> = ({
|
||||
/>
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
return tooltipText ? (
|
||||
<Tooltip title={tooltipText}>{buttonContent}</Tooltip>
|
||||
) : (
|
||||
buttonContent
|
||||
export const UpdateAndStartButton: FC<ActionButtonProps> = ({
|
||||
handleAction,
|
||||
}) => {
|
||||
return (
|
||||
<Tooltip title="This template requires automatic updates on workspace startup. Contact your administrator if you want to preserve the template version.">
|
||||
<TopbarButton
|
||||
startIcon={<PlayCircleOutlineIcon />}
|
||||
onClick={() => handleAction()}
|
||||
>
|
||||
Update and start…
|
||||
</TopbarButton>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
UpdateButton,
|
||||
ActivateButton,
|
||||
FavoriteButton,
|
||||
UpdateAndStartButton,
|
||||
} from "./Buttons";
|
||||
import { type ActionType, abilitiesByWorkspaceStatus } from "./constants";
|
||||
import { DebugButton } from "./DebugButton";
|
||||
@@ -89,6 +90,7 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
|
||||
// A mapping of button type to the corresponding React component
|
||||
const buttonMapping: Record<ActionType, ReactNode> = {
|
||||
update: <UpdateButton handleAction={handleUpdate} />,
|
||||
updateAndStart: <UpdateAndStartButton handleAction={handleUpdate} />,
|
||||
updating: <UpdateButton loading handleAction={handleUpdate} />,
|
||||
start: (
|
||||
<StartButton
|
||||
@@ -161,7 +163,13 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
|
||||
data-testid="workspace-actions"
|
||||
>
|
||||
{canBeUpdated && (
|
||||
<>{isUpdating ? buttonMapping.updating : buttonMapping.update}</>
|
||||
<>
|
||||
{isUpdating
|
||||
? buttonMapping.updating
|
||||
: workspace.template_require_active_version
|
||||
? buttonMapping.updateAndStart
|
||||
: buttonMapping.update}
|
||||
</>
|
||||
)}
|
||||
|
||||
{isRestarting
|
||||
@@ -236,10 +244,6 @@ function getTooltipText(
|
||||
return "This template requires automatic updates on workspace startup, but template administrators can ignore this policy.";
|
||||
}
|
||||
|
||||
if (workspace.template_require_active_version) {
|
||||
return "This template requires automatic updates on workspace startup. Contact your administrator if you want to preserve the template version.";
|
||||
}
|
||||
|
||||
if (workspace.automatic_updates === "always") {
|
||||
return "Automatic updates are enabled for this workspace. Modify the update policy in workspace settings if you want to preserve the template version.";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Workspace, WorkspaceStatus } from "api/typesGenerated";
|
||||
import type { Workspace } from "api/typesGenerated";
|
||||
|
||||
/**
|
||||
* An iterable of all action types supported by the workspace UI
|
||||
@@ -23,6 +23,10 @@ export const actionTypes = [
|
||||
"retry",
|
||||
"debug",
|
||||
|
||||
// When a template requires updates, we aim to display a distinct update
|
||||
// button that clearly indicates a mandatory update.
|
||||
"updateAndStart",
|
||||
|
||||
// These are buttons that should be used with disabled UI elements
|
||||
"canceling",
|
||||
"deleted",
|
||||
@@ -52,67 +56,105 @@ export const abilitiesByWorkspaceStatus = (
|
||||
const status = workspace.latest_build.status;
|
||||
if (status === "failed" && canDebug) {
|
||||
return {
|
||||
...statusToAbility.failed,
|
||||
actions: ["retry", "debug"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
};
|
||||
}
|
||||
|
||||
return statusToAbility[status];
|
||||
};
|
||||
switch (status) {
|
||||
case "starting": {
|
||||
return {
|
||||
actions: ["starting"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
case "running": {
|
||||
const actions: ActionType[] = ["stop"];
|
||||
|
||||
const statusToAbility: Record<WorkspaceStatus, WorkspaceAbilities> = {
|
||||
starting: {
|
||||
actions: ["starting"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
running: {
|
||||
actions: ["stop", "restart"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
},
|
||||
stopping: {
|
||||
actions: ["stopping"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
stopped: {
|
||||
actions: ["start"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
},
|
||||
canceled: {
|
||||
actions: ["start", "stop"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
},
|
||||
// If the template requires the latest version, we prevent the user from
|
||||
// restarting the workspace without updating it first. In the Buttons
|
||||
// component, we display an UpdateAndStart component to facilitate this.
|
||||
if (!workspace.template_require_active_version) {
|
||||
actions.push("restart");
|
||||
}
|
||||
|
||||
// in the case of an error
|
||||
failed: {
|
||||
actions: ["retry"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
},
|
||||
return {
|
||||
actions,
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
};
|
||||
}
|
||||
case "stopping": {
|
||||
return {
|
||||
actions: ["stopping"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
case "stopped": {
|
||||
const actions: ActionType[] = [];
|
||||
|
||||
// Disabled states
|
||||
canceling: {
|
||||
actions: ["canceling"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
deleting: {
|
||||
actions: ["deleting"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
deleted: {
|
||||
actions: ["deleted"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
pending: {
|
||||
actions: ["pending"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
},
|
||||
// If the template requires the latest version, we prevent the user from
|
||||
// starting the workspace without updating it first. In the Buttons
|
||||
// component, we display an UpdateAndStart component to facilitate this.
|
||||
if (!workspace.template_require_active_version) {
|
||||
actions.push("start");
|
||||
}
|
||||
|
||||
return {
|
||||
actions,
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
};
|
||||
}
|
||||
case "canceled": {
|
||||
return {
|
||||
actions: ["start", "stop"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
};
|
||||
}
|
||||
case "failed": {
|
||||
return {
|
||||
actions: ["retry"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Disabled states
|
||||
case "canceling": {
|
||||
return {
|
||||
actions: ["canceling"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
case "deleting": {
|
||||
return {
|
||||
actions: ["deleting"],
|
||||
canCancel: true,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
case "deleted": {
|
||||
return {
|
||||
actions: ["deleted"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
case "pending": {
|
||||
return {
|
||||
actions: ["pending"],
|
||||
canCancel: false,
|
||||
canAcceptJobs: false,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unknown workspace status: ${status}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user