From c4433edadfcf44b7a9ae9fcfc446c66ee057bd96 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 17 Jul 2026 14:14:38 +0100 Subject: [PATCH] fix(frontend): disable the container update button up front when the server refuses the update capability The lifecycle buttons already read resource.actionReadiness and render disabled with the refusal reason before any click. The update button did not, so a user with a stale or disconnected agent could click Update, confirm, and only then get the refusal from POST /api/actions/plan (GitHub #1564). Wire the update button to the same per-resource readiness data: extract the readiness-refusal resolver shared with the lifecycle buttons into utils/actionReadiness.ts, thread actionReadiness through UpdateButtonProps at both render sites (Docker containers table and the workloads GuestRow via useWorkloads), and render the button disabled with the refusal reason as its tooltip. The post-click details.reason path from b3058d47e stays as the backstop for websocket-hydrated rows, which carry no readiness data until the REST revalidation lands. --- .../src/components/Workloads/GuestRow.tsx | 1 + .../shared/ContainerUpdateBadge.tsx | 2 +- .../__tests__/ContainerUpdateBadge.test.tsx | 51 +++++++++++++ .../shared/containerUpdateBadgeModel.ts | 10 ++- .../shared/useContainerUpdateButtonState.ts | 39 +++++++--- .../features/docker/DockerContainersTable.tsx | 1 + .../docker/dockerContainerLifecycleActions.ts | 24 +------ frontend-modern/src/hooks/useWorkloads.ts | 3 + frontend-modern/src/types/workloads.ts | 5 ++ .../utils/__tests__/actionReadiness.test.ts | 72 +++++++++++++++++++ frontend-modern/src/utils/actionReadiness.ts | 38 ++++++++++ 11 files changed, 212 insertions(+), 34 deletions(-) create mode 100644 frontend-modern/src/utils/__tests__/actionReadiness.test.ts create mode 100644 frontend-modern/src/utils/actionReadiness.ts diff --git a/frontend-modern/src/components/Workloads/GuestRow.tsx b/frontend-modern/src/components/Workloads/GuestRow.tsx index f51688c91b..27c042eccf 100644 --- a/frontend-modern/src/components/Workloads/GuestRow.tsx +++ b/frontend-modern/src/components/Workloads/GuestRow.tsx @@ -778,6 +778,7 @@ export function GuestRow(props: GuestRowProps) { containerId={props.guest.containerId ?? ''} containerName={props.guest.name} resourceId={props.guest.id} + actionReadiness={props.guest.actionReadiness} compact={true} /> diff --git a/frontend-modern/src/components/shared/ContainerUpdateBadge.tsx b/frontend-modern/src/components/shared/ContainerUpdateBadge.tsx index 4e69c3639d..5c645afe5b 100644 --- a/frontend-modern/src/components/shared/ContainerUpdateBadge.tsx +++ b/frontend-modern/src/components/shared/ContainerUpdateBadge.tsx @@ -190,7 +190,7 @@ export const UpdateButton: Component = (props) => {