diff --git a/frontend-modern/src/features/proxmox/ProxmoxBackupsTable.tsx b/frontend-modern/src/features/proxmox/ProxmoxBackupsTable.tsx index 35aea0348f..69cbb8012b 100644 --- a/frontend-modern/src/features/proxmox/ProxmoxBackupsTable.tsx +++ b/frontend-modern/src/features/proxmox/ProxmoxBackupsTable.tsx @@ -14,6 +14,7 @@ import ChevronRightIcon from 'lucide-solid/icons/chevron-right'; import { Card } from '@/components/shared/Card'; import { EmptyState } from '@/components/shared/EmptyState'; import { FilterButtonGroup, type FilterOption } from '@/components/shared/FilterButtonGroup'; +import { ProgressBar } from '@/components/shared/ProgressBar'; import { SearchInput } from '@/components/shared/SearchInput'; import { StatusDot } from '@/components/shared/StatusDot'; import { TableCard } from '@/components/shared/TableCard'; @@ -223,33 +224,32 @@ function formatDurationFromSeconds(seconds: number): string { return `${h}h ${m}m`; } -// Compact, table-row-sized horizontal usage bar. Used inline in the -// Backup files Size column (proportional to the largest archive in view) -// and in the Recent tasks Duration column (proportional to 2x the median -// duration so a typical task fills ~50% and outliers fill the bar). -// -// Layout invariant: the bar is positioned AFTER the value text in its -// cell, and the cell uses `justify-end`. Because the bar has a fixed -// width and is the rightmost element, every bar's left and right edges -// land at the same x in every row, so they read as a proper comparison -// chart instead of a row of free-floating segments. -function InlineProgressBar(props: { +// Canonical row metric bar — same shape as Storage's usage bar, Ceph's +// pool usage bar, and Workloads' MetricBar: a full-cell-width +// ProgressBar with the value text overlaid on top of the fill. The +// shared `ProgressBar` primitive (foreignObject-based fill that clips +// the label) is the one source of truth for this pattern in Pulse, so +// the Backups tabs read identically to the rest of the app. +function RowMetricBar(props: { valuePct: number; - toneClass: string; - width?: string; - label?: string; + fillClass: string; + label: string; + tooltip?: string; }) { - const widthClass = props.width ?? 'w-16'; return (