diff --git a/frontend-modern/src/features/docker/DockerHostDrawerOverview.tsx b/frontend-modern/src/features/docker/DockerHostDrawerOverview.tsx index 90efa67548..a721cf3612 100644 --- a/frontend-modern/src/features/docker/DockerHostDrawerOverview.tsx +++ b/frontend-modern/src/features/docker/DockerHostDrawerOverview.tsx @@ -1,10 +1,12 @@ -import { For, Show } from 'solid-js'; +import { For, Show, createMemo } from 'solid-js'; import { DrawerDiskListCard, buildDrawerDiskListItems, type DrawerDiskListItem, } from '@/components/Workloads/DrawerDiskListCard'; +import { useResourceDetailDrawerDockerActionsState } from '@/components/Infrastructure/useResourceDetailDrawerDockerActionsState'; +import { areSystemSettingsLoaded, shouldHideDockerUpdateActions } from '@/stores/systemSettings'; import type { Resource } from '@/types/resource'; import { formatBytes, @@ -196,8 +198,24 @@ export function DockerHostDrawerOverview(props: DockerHostDrawerOverviewProps) { if (typeof count === 'number') { rows.push({ label: 'Containers', value: `${count}` }); } - if (typeof docker()?.updatesAvailableCount === 'number') { - rows.push({ label: 'Updates', value: `${docker()!.updatesAvailableCount}` }); + const updates = docker()?.updatesAvailableCount; + if (typeof updates === 'number') { + rows.push({ + label: 'Updates', + value: `${updates}`, + valueClass: updates > 0 ? 'text-sky-700 dark:text-sky-300' : undefined, + }); + } + const checkedAt = cleanText(docker()?.updatesLastCheckedAt); + if (checkedAt) { + const parsed = Date.parse(checkedAt); + if (Number.isFinite(parsed)) { + rows.push({ + label: 'Checked', + value: formatRelativeTime(parsed), + title: new Date(parsed).toLocaleString(), + }); + } } if (hasDockerSwarmEvidence(props.host)) { const role = cleanText(docker()?.swarm?.nodeRole); @@ -210,6 +228,30 @@ export function DockerHostDrawerOverview(props: DockerHostDrawerOverviewProps) { return rows; }; + type DockerHostCommandMeta = { + type?: string; + status?: string; + message?: string; + failureReason?: string; + }; + + const hostSourceId = createMemo(() => cleanText(docker()?.hostSourceId) || null); + const updatesAvailable = createMemo(() => docker()?.updatesAvailableCount ?? 0); + const hostCommand = createMemo( + () => docker()?.command as DockerHostCommandMeta | undefined, + ); + const hostCommandActive = createMemo(() => + ['queued', 'dispatched', 'acknowledged', 'in_progress'].includes( + cleanText(hostCommand()?.status).toLowerCase(), + ), + ); + const updateActions = useResourceDetailDrawerDockerActionsState({ + dockerHostSourceId: hostSourceId, + dockerUpdatesAvailable: updatesAvailable, + }); + const updateActionsLoading = () => !areSystemSettingsLoaded(); + const updateAllHidden = () => shouldHideDockerUpdateActions(); + const memoryRows = (): DockerOverviewRow[] => { const memory = memorySource(); if (!memory) return []; @@ -294,7 +336,89 @@ export function DockerHostDrawerOverview(props: DockerHostDrawerOverviewProps) {