Use shared cards in resource summary

This commit is contained in:
rcourtman
2026-03-20 10:19:35 +00:00
parent 7220839ca6
commit 012b10c3e7
3 changed files with 33 additions and 24 deletions
@@ -268,20 +268,17 @@ not compete for the same ownership on first read.
The overview now begins with one primary `Summary` shell instead of separate
peer `Runtime` and `Identity` cards, so current state and canonical identity
read as one first-screen answer rather than two adjacent mini-surfaces.
That summary shell now reads as one linear current-state and identity column
That summary now uses the same shared `Card` primitive as the workload drawers,
with a responsive two-column grid on wider screens, so the first read stays
compact without making the operator scan a stack of nested cards.
Each summary column keeps its own bordered card boundary, so the split read
still has a clear visual container on both sides instead of feeling like loose
label groups.
compact while each side still has a consistent bounded card.
The drawer header now stays focused on canonical identity and source/type
badges only, while workload/service drill-down links and Kubernetes platform
signals live with the summary shell, so the top strip does not compete with
the resource name, status, or primary identity line.
Inside that summary shell, the operational and supporting context rows stay
inline instead of sitting in a collapsed `Details` disclosure or nested
bordered cards, so the first read stays like one linear sheet rather than a
stack of cards inside the summary.
Inside that summary, the operational and supporting context rows stay inline
instead of sitting in a collapsed `Details` disclosure or nested bordered
cards, so the first read stays like one linear sheet rather than a stack of
cards inside the summary.
Discovery support now also lives inside overview-only `Discovery context`
instead of a peer drawer tab, so supplemental discovery detail stays available
without claiming the same navigation weight as runtime, identity, or
@@ -17,6 +17,7 @@ import type {
import { requiresGovernedResourceDisplay } from '@/types/resource';
import { formatUptime, formatRelativeTime, formatAbsoluteTime } from '@/utils/format';
import { StatusDot } from '@/components/shared/StatusDot';
import { Card } from '@/components/shared/Card';
import { TagBadges } from '@/components/Dashboard/TagBadges';
import { getAgentStatusIndicator } from '@/utils/status';
import {
@@ -907,17 +908,15 @@ const DrawerContent: Component<ResourceDetailDrawerProps> = (props) => {
{/* Overview Tab */}
<div class={activeTab() === 'overview' ? '' : 'hidden'} style={{ 'overflow-anchor': 'none' }}>
<div class="space-y-3">
<div
data-testid="resource-summary-section"
class="rounded border border-border bg-surface p-3"
>
<div data-testid="resource-summary-section">
<div class="text-[11px] font-medium uppercase tracking-wide text-base-content">
Summary
</div>
<div class="mt-3 grid gap-4 sm:grid-cols-2">
<div
<div class="mt-3 grid gap-3 sm:grid-cols-2">
<Card
data-testid="resource-current-state-section"
class="rounded border border-border bg-surface-hover p-3"
padding="sm"
class="h-full shadow-sm"
>
<div class="mb-2 text-[10px] font-medium uppercase tracking-wide text-base-content">
Current state
@@ -1105,11 +1104,12 @@ const DrawerContent: Component<ResourceDetailDrawerProps> = (props) => {
</div>
</Show>
</div>
</div>
</Card>
<div
<Card
data-testid="resource-identity-section"
class="rounded border border-border bg-surface-hover p-3"
padding="sm"
class="h-full shadow-sm"
>
<div class="mb-2 text-[10px] font-medium uppercase tracking-wide text-base-content">
Identity
@@ -1131,7 +1131,7 @@ const DrawerContent: Component<ResourceDetailDrawerProps> = (props) => {
</div>
</Show>
</div>
</div>
</Card>
</div>
</div>
@@ -196,12 +196,24 @@ describe('ResourceDetailDrawer change history section', () => {
.length,
).toBe(0);
const summarySection = screen.getByTestId('resource-summary-section');
expect(summarySection.querySelector('.mt-3.grid.gap-4')).toBeTruthy();
expect(summarySection.querySelector('.mt-3.grid.gap-4')?.classList.contains('sm:grid-cols-2')).toBe(true);
expect(screen.getByTestId('resource-current-state-section').classList.contains('rounded')).toBe(
expect(summarySection.querySelector('.mt-3.grid.gap-3')).toBeTruthy();
expect(summarySection.querySelector('.mt-3.grid.gap-3')?.classList.contains('sm:grid-cols-2')).toBe(true);
expect(screen.getByTestId('resource-current-state-section').classList.contains('rounded-md')).toBe(
true,
);
expect(screen.getByTestId('resource-identity-section').classList.contains('rounded')).toBe(
expect(screen.getByTestId('resource-current-state-section').classList.contains('bg-surface')).toBe(
true,
);
expect(screen.getByTestId('resource-current-state-section').classList.contains('shadow-sm')).toBe(
true,
);
expect(screen.getByTestId('resource-identity-section').classList.contains('rounded-md')).toBe(
true,
);
expect(screen.getByTestId('resource-identity-section').classList.contains('bg-surface')).toBe(
true,
);
expect(screen.getByTestId('resource-identity-section').classList.contains('shadow-sm')).toBe(
true,
);
expect(