7.4 KiB
Compact Fleet Cards Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Remove the Fleet aggregate health strip, restore the upstream SimAdmin version on every card, and change the responsive card matrix to 1/2/2/4/5 columns.
Architecture: Keep the existing API and Fleet view-model pipeline because /api/v1/instances/:id/resources already supplies version. Make the presentation fix in FleetPage, remove the now-unused aggregate calculation, and update only the final Fleet CSS cascade and browser geometry assertions.
Tech Stack: React 19, TypeScript, animal-island-ui, Vitest, Testing Library, Vite, real Chrome DevTools Protocol E2E.
Global Constraints
- Keep overview and search in the desktop left sidebar.
- Keep per-instance CPU, memory, temperature, phone, SMS, status, tags, and operation menu.
- Render
SimAdmin <version>when available and版本未知when absent. - Use exactly 1/2/2/4/5 columns at 390/768/1024/1440/1920 pixels.
- Do not change API contracts, database code, instance-detail telemetry, or unrelated screens.
- Preserve the current cream, warm-brown, mint, shadowless card treatment.
- The shared worktree contains unrelated changes; do not create implementation commits unless explicitly requested.
Task 1: Lock The Fleet Content Contract
Files:
- Modify:
apps/web/src/fleet/fleet-page.test.tsx - Modify:
apps/web/src/app-shell.integration.test.tsx - Test:
apps/web/src/fleet/fleet-page.test.tsx - Test:
apps/web/src/app-shell.integration.test.tsx
Interfaces:
-
Consumes:
FleetSnapshot.statuses[*].summary.versionand the accessible Fleet card/region names. -
Produces: regression coverage for version rendering, missing-version fallback, and aggregate-strip removal.
-
Step 1: Add the upstream version to the Fleet fixture and assert visible card copy
summary: {
version: '1.1.6',
freshness: 'fresh',
resources: { cpuPercent: 24, memoryPercent: 51, maxTemperatureCelsius: 42 },
},
expect(within(card).getByText('SimAdmin 1.1.6')).toBeTruthy();
expect(screen.queryByRole('region', { name: '节点资源健康' })).toBeNull();
- Step 2: Add a missing-version fallback assertion using a separate card fixture
const withoutVersion: FleetSnapshot = {
...snapshot,
statuses: new Map([
['alpha', { ...snapshot.statuses.get('alpha')!, summary: { resources: { cpuPercent: 24 } } }],
]),
};
render(<FleetPage initialData={withoutVersion} />);
expect(screen.getByText('版本未知')).toBeTruthy();
- Step 3: Update AppShell integration expectations
Assert SimAdmin 2.0 is present in the Bravo card and 节点资源健康 is absent. Remove the old expectation that intentionally hid the version text.
- Step 4: Run the focused tests and verify RED
Run:
corepack pnpm --filter @multi-simadmin/web exec vitest run src/fleet/fleet-page.test.tsx src/app-shell.integration.test.tsx
Expected: FAIL because cards do not render row.version, the missing-version fallback is absent, and the aggregate region still exists.
Task 2: Implement Compact Fleet Content
Files:
- Modify:
apps/web/src/fleet/fleet-page.tsx - Test:
apps/web/src/fleet/fleet-page.test.tsx - Test:
apps/web/src/app-shell.integration.test.tsx
Interfaces:
-
Consumes: existing
FleetRow.version: string | nullfrombuildFleetTableViewModel. -
Produces:
.fleet-card-versionidentity text and no节点资源健康region. -
Step 1: Remove the aggregate-only calculation and formatting helpers
Delete average, healthPercent, healthRate, healthTemperature, the fleetHealth memo, and the complete .fleet-health-strip JSX block. Keep fleetSummary, which owns the left-sidebar totals.
- Step 2: Render the real version under the card name
<span className="fleet-card-version">{row.version ? `SimAdmin ${row.version}` : '版本未知'}</span>
Place it inside .fleet-card-entry after the <h2> and before the dashboard affordance so it remains part of the card identity link.
- Step 3: Run the focused tests and verify GREEN
Run:
corepack pnpm --filter @multi-simadmin/web exec vitest run src/fleet/fleet-page.test.tsx src/app-shell.integration.test.tsx
Expected: both test files pass with no React warnings.
Task 3: Lock And Implement Narrow Responsive Geometry
Files:
- Modify:
scripts/real-browser-e2e.mjs - Modify:
apps/web/src/styles.css - Test:
scripts/real-browser-e2e.mjs
Interfaces:
-
Consumes:
.fleet-card-grid,.fleet-card-version,.fleet-group-tabs,.fleet-sidebar, and.fleet-cardDOM selectors. -
Produces: deterministic 1/2/2/4/5 responsive geometry and screenshots.
-
Step 1: Change the E2E viewport contract before CSS
{ width: 390, height: 844, columns: 1, sidebarMode: 'stacked', mobile: true },
{ width: 768, height: 900, columns: 2, sidebarMode: 'stacked', mobile: false },
{ width: 1024, height: 900, columns: 2, sidebarMode: 'left', mobile: false },
{ width: 1440, height: 1000, columns: 4, sidebarMode: 'left', mobile: false },
{ width: 1920, height: 1080, columns: 5, sidebarMode: 'left', mobile: false },
Remove health-strip selectors and assertions. Add .fleet-card-version bounds and text-presence checks to the existing layout snapshot.
- Step 2: Run browser E2E and verify RED
Run:
$env:E2E_SCREENSHOT_DIR='C:\Users\86135\Downloads\multi-simadmin\artifacts\compact-fleet-cards'
corepack pnpm run test:e2e:browser
Expected: FAIL at the 1440px column count because current CSS renders 3 columns.
- Step 3: Update the final Fleet cascade
Set the default desktop .fleet-card-grid to four columns, change the wide breakpoint to five columns, preserve two columns through 1024px, and preserve one column at 390px. Remove the unused .fleet-health-strip rules. Add compact .fleet-card-version typography with ellipsis protection and no new card shadow.
- Step 4: Run browser E2E and verify GREEN
Run the same command from Step 2.
Expected: PASS at all five viewport widths with no overflow, clipped menus, wrapped hardware values, or moved desktop sidebar.
Task 4: Full Verification And Local Handoff
Files:
- Verify:
apps/web/src/fleet/fleet-page.tsx - Verify:
apps/web/src/styles.css - Verify:
scripts/real-browser-e2e.mjs
Interfaces:
-
Consumes: the completed Fleet UI and existing local canary gateway on port 8789.
-
Produces: fresh automated evidence, reviewed screenshots, and an accessible local build.
-
Step 1: Run the full Web quality gates
corepack pnpm --filter @multi-simadmin/web test
corepack pnpm --filter @multi-simadmin/web typecheck
corepack pnpm lint
corepack pnpm format:check
- Step 2: Inspect generated screenshots
Review 390px, 1440px, and 1920px captures. Confirm compact cards, readable versions, no aggregate strip, no overlap, and no excessive horizontal gutters.
- Step 3: Rebuild after E2E cleanup and verify local responses
corepack pnpm --filter @multi-simadmin/web build
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8789/
Invoke-WebRequest -UseBasicParsing http://127.0.0.1:8789/api/v1/instances
Expected: both URLs return HTTP 200 and the UI is available at http://127.0.0.1:8789/.