From e691b5328a25d70ba86cc7b89522dd264401a0f5 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 27 Mar 2026 22:21:15 +0000 Subject: [PATCH] refactor(recovery): align inventory row scan pattern --- .../internal/subsystems/storage-recovery.md | 5 ++ .../RecoveryProtectedInventorySection.tsx | 63 ++++++++++++------- .../Recovery/__tests__/Recovery.test.tsx | 4 ++ 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/storage-recovery.md b/docs/release-control/v6/internal/subsystems/storage-recovery.md index cd2f54cd1f..fc40ba9112 100644 --- a/docs/release-control/v6/internal/subsystems/storage-recovery.md +++ b/docs/release-control/v6/internal/subsystems/storage-recovery.md @@ -648,6 +648,11 @@ recovery-specific mini report. Recovery summary cards should prefer concise counts, bars, and badge-backed coverage cues over tall explanatory copy blocks so the protected-item table takes over the page at roughly the same visual density as the infrastructure and workloads monitoring surfaces. +That same inventory surface should also follow the established monitoring-table +scan pattern in its first column. Protected-item rows should lead with a clear +status cue, the primary item name, and compact badge-backed item/platform +context instead of relying on recovery-only rails or plain-text metadata lines +that make the table read like a report instead of an operational grid. That shared unified-resource dependency now also includes policy-governed resource metadata on the frontend decode path: storage and recovery surfaces that route through `frontend-modern/src/hooks/useUnifiedResources.ts` must diff --git a/frontend-modern/src/components/Recovery/RecoveryProtectedInventorySection.tsx b/frontend-modern/src/components/Recovery/RecoveryProtectedInventorySection.tsx index 2648397b10..ff7e741126 100644 --- a/frontend-modern/src/components/Recovery/RecoveryProtectedInventorySection.tsx +++ b/frontend-modern/src/components/Recovery/RecoveryProtectedInventorySection.tsx @@ -6,6 +6,7 @@ import { EmptyState } from '@/components/shared/EmptyState'; import { LabeledFilterSelect } from '@/components/shared/FilterToolbar'; import { PageControls } from '@/components/shared/PageControls'; import { SearchInput } from '@/components/shared/SearchInput'; +import { StatusDot } from '@/components/shared/StatusDot'; import { getSourcePlatformBadge } from '@/components/shared/sourcePlatformBadges'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/shared/Table'; import { STORAGE_KEYS } from '@/utils/localStorage'; @@ -38,9 +39,9 @@ import { } from '@/utils/recoveryTablePresentation'; import { getRecoveryOutcomeBadgeClass, + getRecoveryOutcomeLabel, normalizeRecoveryOutcome, } from '@/utils/recoveryOutcomePresentation'; -import { getRecoveryIssueRailClass, type RecoveryIssueTone } from '@/utils/recoveryIssuePresentation'; import { getRecoveryRollupPlatforms } from '@/utils/recoveryPlatformModel'; import { getRecoveryRollupItemLabel } from '@/utils/recoveryRecordPresentation'; import { getSourcePlatformLabel, normalizeSourcePlatformQueryValue } from '@/utils/sourcePlatforms'; @@ -414,14 +415,23 @@ export const RecoveryProtectedInventorySection: Component< const itemTypePresentation = getRecoveryItemTypePresentation(getRecoveryRollupItemTypeKey(rollup)) || null; const nowMs = Date.now(); - const issueTone: RecoveryIssueTone = getRecoveryRollupIssueTone(rollup, nowMs); - const issueRailClass = - issueTone === 'none' ? '' : getRecoveryIssueRailClass(issueTone); const stale = isRecoveryRollupStale(rollup, nowMs); const neverSucceeded = (!Number.isFinite(successMs) || successMs <= 0) && Number.isFinite(attemptMs) && attemptMs > 0; + const outcomeVariant = (() => { + switch (outcome) { + case 'success': + return 'success' as const; + case 'warning': + return 'warning' as const; + case 'failed': + return 'danger' as const; + default: + return 'muted' as const; + } + })(); return ( props.onSelectRollup(rollup.rollupId)} > - - - -
+
+ {label} @@ -451,22 +463,29 @@ export const RecoveryProtectedInventorySection: Component<
-
+
- {itemTypePresentation?.label} + + {itemTypePresentation?.label} + 0}> - - {platforms - .map((platform) => getSourcePlatformLabel(platform)) - .join(' • ')} - + + {(platform) => { + const badge = getSourcePlatformBadge(platform); + return ( + + {badge?.label || getSourcePlatformLabel(platform)} + + ); + }} +
-