refactor(recovery): simplify footprint summary card

This commit is contained in:
rcourtman 2026-03-28 09:59:18 +00:00
parent fb3fe50c63
commit f97981249c
3 changed files with 10 additions and 30 deletions

View file

@ -704,6 +704,10 @@ instead of feature-local spacing overrides. Recovery may select the shared
default `SummaryPanel` / `SummaryMetricCard` density mode, and it should not
reintroduce one-off padding hacks or right-side duplicate KPI blocks inside
`RecoverySummary.tsx`.
That same one-headline rule applies to the footprint card too. `Protected
Footprint` should lead with one dominant item-type count and carry platform
coverage as a support row instead of presenting dual headline counts plus mix
chips inside the same card.
That same scan-first rule applies to the workspace strip. Recovery should not
show tab labels and then repeat the same workspace count as standalone text in
the same strip; the workspace tabs should carry their own counts, while the

View file

@ -61,6 +61,7 @@ describe('RecoverySummary', () => {
expect(screen.getAllByText(/attention/i).length).toBeGreaterThan(0);
expect(screen.getByText(/recovery points/i)).toBeInTheDocument();
expect(screen.getByText(/item types/i)).toBeInTheDocument();
expect(screen.getByText('Platforms')).toBeInTheDocument();
expect(screen.getByText('Primary Item')).toBeInTheDocument();
expect(screen.getByText('Primary Platform')).toBeInTheDocument();
expect(screen.getByText('Avg / Day')).toBeInTheDocument();

View file

@ -93,8 +93,6 @@ export const RecoverySummary: Component<RecoverySummaryProps> = (props) => {
value: summary().neverSucceeded,
},
]);
const platformMixPreview = createMemo(() => platformCoverage().items.slice(0, 2));
const itemMixPreview = createMemo(() => itemCoverage().items.slice(0, 2));
const freshWithin24hCount = createMemo(
() =>
(freshnessBuckets().find((bucket) => bucket.key === 'under1h')?.count ?? 0) +
@ -169,44 +167,21 @@ export const RecoverySummary: Component<RecoverySummaryProps> = (props) => {
<SummaryMetricCard label="Protected Footprint" loaded={true} hasData={hasRollups()}>
<div class="flex h-full flex-col gap-2">
<div class="grid grid-cols-2 gap-3">
<div>
<div class="text-xl font-semibold tabular-nums text-base-content">
{itemCoverage().itemTypeCount}
</div>
<div class="text-[11px] text-muted">item types</div>
</div>
<div class="text-right">
<div class="text-xl font-semibold tabular-nums text-base-content">
{platformCoverage().platformCount}
</div>
<div class="text-[11px] text-muted">platforms</div>
<div>
<div class="text-xl font-semibold tabular-nums text-base-content">
{itemCoverage().itemTypeCount}
</div>
<div class="text-[11px] text-muted">item types</div>
</div>
<div class="border-t border-border-subtle pt-1.5">
<MetricRows
rows={[
{ label: 'Platforms', value: platformCoverage().platformCount },
{ label: 'Primary Item', value: itemCoverage().primaryItemLabel ?? 'n/a' },
{ label: 'Primary Platform', value: platformCoverage().primaryPlatformLabel ?? 'n/a' },
]}
/>
</div>
<div class="flex flex-wrap items-center gap-1 pt-0.5">
<For each={itemMixPreview()}>
{(item) => (
<span class={`inline-flex items-center rounded px-1.5 py-px text-[10px] font-medium ${item.toneClass}`}>
{item.label} {item.count}
</span>
)}
</For>
<For each={platformMixPreview()}>
{(platform) => (
<span class={`inline-flex items-center rounded px-1.5 py-px text-[10px] font-medium ${platform.toneClass}`}>
{platform.label} {platform.count}
</span>
)}
</For>
</div>
</div>
</SummaryMetricCard>