193 lines
7.4 KiB
Markdown
193 lines
7.4 KiB
Markdown
# 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.version` and 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**
|
|
|
|
```tsx
|
|
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**
|
|
|
|
```tsx
|
|
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:
|
|
|
|
```powershell
|
|
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 | null` from `buildFleetTableViewModel`.
|
|
- Produces: `.fleet-card-version` identity 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**
|
|
|
|
```tsx
|
|
<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:
|
|
|
|
```powershell
|
|
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-card` DOM selectors.
|
|
- Produces: deterministic 1/2/2/4/5 responsive geometry and screenshots.
|
|
|
|
- [ ] **Step 1: Change the E2E viewport contract before CSS**
|
|
|
|
```js
|
|
{ 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:
|
|
|
|
```powershell
|
|
$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**
|
|
|
|
```powershell
|
|
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**
|
|
|
|
```powershell
|
|
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/`.
|