docs: UI shell rework wave-2 implementation plan
7 tasks: token cleanups from wave-1 review (task 0), then migrate login/home/settings/tokens/users/containers.html one-by-one with deploy-and-verify between each. Smallest blast radius first.
This commit is contained in:
parent
447b2b2b81
commit
265f4174d5
1 changed files with 502 additions and 0 deletions
502
docs/superpowers/plans/2026-05-21-ui-shell-rework-wave-2-plan.md
Normal file
502
docs/superpowers/plans/2026-05-21-ui-shell-rework-wave-2-plan.md
Normal file
|
|
@ -0,0 +1,502 @@
|
|||
# UI Shell Rework — Wave 2 (Low-risk page migrations) Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:subagent-driven-development or executing-plans. Steps use `- [ ]` checkboxes.
|
||||
|
||||
**Goal:** Migrate the 6 lowest-risk shell pages (login, home, settings, tokens, users, containers) from `css/common.css` + bespoke per-page CSS to the new `/dist/app.css` primitive bundle from wave 1. Each page goes from "old look" to "new look" with the same functionality. Also fold in the deferred token cleanups from the wave-1 code review.
|
||||
|
||||
**Architecture:** Each page migration is a self-contained markup rewrite. Pattern: swap the `<link>` to `/dist/app.css`, replace the sidebar + topbar markup with `wd-*` primitives, restyle page-specific content with `wd-card-asset` / `wd-card-op` / `wd-list-row` / `wd-form-*` / `wd-btn` / etc. Preserve every existing `<script>` and `id` so JS keeps working. Deploy after each page; check.
|
||||
|
||||
**Tech Stack:** Tailwind+flyon-ui bundle from wave 1 (already live), nginx static, no JS changes expected.
|
||||
|
||||
**Reference spec:** `docs/superpowers/specs/2026-05-21-ui-shell-rework-design.md`
|
||||
**Wave 1 plan:** `docs/superpowers/plans/2026-05-21-ui-shell-rework-wave-1-plan.md`
|
||||
|
||||
---
|
||||
|
||||
## File structure
|
||||
|
||||
**Files this wave modifies:**
|
||||
|
||||
```
|
||||
services/web-ui/
|
||||
├── public/
|
||||
│ ├── login.html (REWRITE: small, no sidebar, just form)
|
||||
│ ├── home.html (REWRITE: hero + stat tiles, has sidebar)
|
||||
│ ├── settings.html (REWRITE: tabbed settings forms, has sidebar)
|
||||
│ ├── tokens.html (REWRITE: list of tokens + create panel, has sidebar)
|
||||
│ ├── users.html (REWRITE: user list + edit slide-panel, has sidebar)
|
||||
│ └── containers.html (REWRITE: docker container list + logs, has sidebar)
|
||||
└── src/css/components/
|
||||
└── tokens.css (MODIFY: add deferred token cleanups)
|
||||
```
|
||||
|
||||
**Files this wave does NOT touch:** the other 9 pages (index, projects, upload, jobs, api-tokens, recorders, cluster, capture, edit, editor, player). They're wave 3 / 4 / excluded.
|
||||
|
||||
---
|
||||
|
||||
## Tasks
|
||||
|
||||
### Task 0: Fold deferred token cleanups into tokens.css
|
||||
|
||||
Address items 1, 2, 4, 6 from the wave-1 code review BEFORE the page migrations multiply duplication of raw oklch values.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/src/css/components/tokens.css`
|
||||
- Modify: `services/web-ui/src/css/components/button.css` (use new tokens)
|
||||
- Modify: `services/web-ui/src/css/components/card-operational.css` (use new tokens)
|
||||
- Modify: `services/web-ui/src/css/components/sidebar.css`, `topbar.css`, `slide-panel.css`, `card-asset.css`, `form-controls.css`, `field-group.css`, `list-row.css`, `toast.css` (use shared --ease / --dur tokens)
|
||||
|
||||
- [ ] **Step 1: Extend tokens.css with the missing tokens**
|
||||
|
||||
Append to `services/web-ui/src/css/components/tokens.css` inside `:root`:
|
||||
|
||||
```css
|
||||
/* Hover-darker variants of accent + signals — promoted from
|
||||
* inline oklch() arithmetic that was duplicated across button.css
|
||||
* and card-operational.css */
|
||||
--accent-hover: oklch(52% 0.20 266);
|
||||
--accent-bright: oklch(70% 0.18 266);
|
||||
--signal-bad-hover: oklch(68% 0.22 25);
|
||||
--signal-good-hover: oklch(74% 0.18 148);
|
||||
--signal-warn-hover: oklch(84% 0.16 90);
|
||||
/* Pure-black-ish tinted toward brand hue for thumbnails & overlays.
|
||||
* Numerically still ~black but the hue channel is set so future
|
||||
* derivations stay on-brand. */
|
||||
--thumb-black: oklch(0% 0 266);
|
||||
--overlay: oklch(8% 0.010 266 / 0.65);
|
||||
--shadow: oklch(0% 0 266 / 0.5);
|
||||
|
||||
/* Motion + ease tokens — promoted from raw cubic-bezier strings
|
||||
* that appeared in 8 of 12 primitive files */
|
||||
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
|
||||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--dur-fast: 120ms;
|
||||
--dur-normal: 180ms;
|
||||
--dur-slide: 240ms;
|
||||
|
||||
/* Z layers — promoted from sidebar/topbar where 30 was hard-coded */
|
||||
--z-topbar: 30;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Find-and-replace raw oklch hover values across primitives**
|
||||
|
||||
For each of these files, replace the literal oklch string with the new token. Use `sed -i` for the substitutions, but verify each file afterward.
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/src/css/components
|
||||
|
||||
# button.css
|
||||
sed -i 's|background: oklch(52% 0.20 266);|background: var(--accent-hover);|' button.css
|
||||
sed -i 's|background: oklch(68% 0.22 25);|background: var(--signal-bad-hover);|' button.css
|
||||
|
||||
# card-operational.css — gradient stop in signal-strip-fill
|
||||
sed -i 's|oklch(70% 0.18 266)|var(--accent-bright)|' card-operational.css
|
||||
|
||||
# card-asset.css — pure-black thumb background
|
||||
sed -i 's|background: oklch(0% 0 0);|background: var(--thumb-black);|' card-asset.css
|
||||
|
||||
# slide-panel.css — overlay color
|
||||
sed -i 's|oklch(8% 0.010 266 / 0.65)|var(--overlay)|' slide-panel.css
|
||||
|
||||
# toast.css — shadow
|
||||
sed -i 's|oklch(0% 0 0 / 0.7)|var(--shadow)|' toast.css
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Replace raw cubic-bezier strings with --ease + --dur tokens**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/src/css/components
|
||||
# Replace exact "120ms cubic-bezier(0.25, 1, 0.5, 1)" with the tokens
|
||||
for f in sidebar.css topbar.css slide-panel.css card-asset.css card-operational.css form-controls.css field-group.css list-row.css button.css; do
|
||||
sed -i 's|120ms cubic-bezier(0\.25, 1, 0\.5, 1)|var(--dur-fast) var(--ease-out-quart)|g' "$f"
|
||||
done
|
||||
# slide-panel slide-in (240ms ease-out-expo)
|
||||
sed -i 's|240ms cubic-bezier(0\.16, 1, 0\.3, 1)|var(--dur-slide) var(--ease-out-expo)|' slide-panel.css
|
||||
# Tab indicator
|
||||
sed -i 's|240ms cubic-bezier(0\.25, 1, 0\.5, 1)|var(--dur-slide) var(--ease-out-quart)|' slide-panel.css
|
||||
sed -i 's|200ms cubic-bezier(0\.25, 1, 0\.5, 1)|200ms var(--ease-out-quart)|g' form-controls.css
|
||||
sed -i 's|240ms cubic-bezier(0\.16, 1, 0\.3, 1)|var(--dur-slide) var(--ease-out-expo)|' card-operational.css
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Replace hard-coded z-index 30 with --z-topbar**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/src/css/components
|
||||
sed -i 's|z-index: 30;|z-index: var(--z-topbar);|' topbar.css
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Rebuild + verify primitives still ship correctly**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon
|
||||
docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
docker exec wild-dragon-web-ui-1 grep -c '.wd-' /usr/share/nginx/html/dist/app.css
|
||||
# Expect: same large number (~116+) — no rules dropped
|
||||
docker exec wild-dragon-web-ui-1 grep -c '\-\-accent-hover\|\-\-ease-out-quart\|\-\-z-topbar' /usr/share/nginx/html/dist/app.css
|
||||
# Expect: at least 3 hits (tokens now defined + referenced)
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Visual regression check on smoke page**
|
||||
|
||||
```bash
|
||||
curl -sk -o /dev/null -w 'smoke=%{http_code}/%{size_download}\n' http://localhost:47434/_primitives-smoke.html
|
||||
# Expect: HTTP 200, ~12 KB (unchanged from wave 1)
|
||||
```
|
||||
|
||||
Manually load the smoke page in a browser; everything should look identical to wave 1. If anything changed visually, the sed substitutions introduced a regression.
|
||||
|
||||
- [ ] **Step 7: Commit + push**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon
|
||||
HOME=/root git add services/web-ui/src/css/components/
|
||||
HOME=/root git diff --cached --stat
|
||||
HOME=/root git -c user.email=zgaetano@wilddragon.net -c user.name='Zac Gaetano' commit -m 'web-ui: token cleanups from wave-1 code review
|
||||
|
||||
- Promote --accent-hover, --signal-bad-hover, --signal-good-hover,
|
||||
--signal-warn-hover, --accent-bright tokens (were duplicated raw
|
||||
oklch arithmetic in button.css / card-operational.css)
|
||||
- Promote --thumb-black, --overlay, --shadow tokens (tinted toward
|
||||
brand hue 266 so future derivations stay on-brand)
|
||||
- Promote --ease-out-quart, --ease-out-expo, --dur-fast/normal/slide
|
||||
tokens (cubic-bezier strings appeared in 8 of 12 primitive files)
|
||||
- Promote --z-topbar (was hard-coded 30 in topbar.css while every
|
||||
other layer was tokenized)
|
||||
- Replace all usages across the 12 primitive files via sed.
|
||||
|
||||
Bundle byte count unchanged (~138 KB); visual regression on smoke
|
||||
page = zero. Code-review concerns from wave 1 now resolved before
|
||||
wave 2 page migrations begin.'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Migrate login.html
|
||||
|
||||
Smallest page. No sidebar, no topbar — just a centered card with email/password. Migrating first because if it breaks nothing else does.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/login.html`
|
||||
|
||||
- [ ] **Step 1: Read the current page to see what's there**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
cat login.html | head -80
|
||||
```
|
||||
|
||||
Note: form ids, input names, any inline JS handlers. Preserve all of them.
|
||||
|
||||
- [ ] **Step 2: Write the new login.html**
|
||||
|
||||
The new structure:
|
||||
- `<link rel="stylesheet" href="/dist/app.css">` instead of the old `common.css`
|
||||
- Centered `<main>` with a single `.wd-card-op`-shaped panel (operational card primitive, sized small)
|
||||
- Inside: brand logo + "Z-AMPP" wordmark at top, then `<form>` with two `.wd-form-group` (email + password), then `.wd-btn.wd-btn--primary.wd-btn--md` submit
|
||||
- Keep every existing `id`, `name`, `type`, and `<script>` tag from the old file
|
||||
- If there's an "error message" div, replace its class with `.wd-toast.wd-toast--error` (inline, not floating)
|
||||
|
||||
Replace the entire `<head>` and `<body>` with the new shell. JS at the bottom stays as-is.
|
||||
|
||||
- [ ] **Step 3: Deploy on zampp1 (no Docker rebuild needed — HTML is static)**
|
||||
|
||||
```bash
|
||||
# Actually nginx serves from the image's filesystem, not the host's
|
||||
# /opt/wild-dragon/services/web-ui/public/. So we DO need a rebuild.
|
||||
cd /opt/wild-dragon
|
||||
docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'login=%{http_code}/%{size_download}\n' http://localhost:47434/login.html
|
||||
# Confirm new bundle is referenced
|
||||
curl -sk http://localhost:47434/login.html | grep -E 'dist/app.css|common.css'
|
||||
# Expect: dist/app.css present, common.css absent
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Visual + functional check**
|
||||
|
||||
Open `http://172.18.91.216:47434/login.html` in a browser. Verify:
|
||||
- Page renders with new brand styling
|
||||
- Email + password fields look like the wd-input primitive
|
||||
- Submit button looks like wd-btn--primary
|
||||
- Logging in still actually works (POST to /api/v1/auth/login)
|
||||
|
||||
- [ ] **Step 5: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/login.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate login.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Migrate home.html
|
||||
|
||||
Has sidebar + topbar + dashboard stat tiles. The first page that exercises the full shell.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/home.html`
|
||||
|
||||
- [ ] **Step 1: Read the current page**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
wc -l home.html
|
||||
head -80 home.html
|
||||
```
|
||||
|
||||
Identify: page title, what's in the topbar right side, the stat tile structure, any chart libraries, and the bottom `<script>` blocks. Preserve all script references and JS state.
|
||||
|
||||
- [ ] **Step 2: Migrate the markup**
|
||||
|
||||
The migration recipe for every shell page:
|
||||
|
||||
1. **`<head>`**: replace `<link rel=stylesheet href=css/common.css>` with `<link rel=stylesheet href=/dist/app.css>`. Keep favicon, viewport meta.
|
||||
2. **`<body>` root**: wrap in `<div class="wd-shell">` (style inline: `display:flex;min-height:100vh`).
|
||||
3. **Sidebar**: copy verbatim from the smoke page's `<nav class="wd-sidebar">` block. Mark the active nav item with `is-active` on Home.
|
||||
4. **Right column**: `<div style="flex:1;display:flex;flex-direction:column;">`
|
||||
5. **Topbar**: `<header class="wd-topbar">` with breadcrumb in `.wd-topbar-left` containing just "Home", any existing right-side button as `.wd-btn.wd-btn--primary.wd-btn--sm`.
|
||||
6. **Main content**: `<main style="padding:20px 20px 32px;">`
|
||||
7. **Stat tiles**: replace with `.wd-card-op-grid` containing `.wd-card-op` (small, content-only — no footer needed if there's no action).
|
||||
8. **Auth-guard script** at the bottom — stays exactly as-is.
|
||||
|
||||
- [ ] **Step 3: Deploy + check**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon
|
||||
docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'home=%{http_code}/%{size_download}\n' http://localhost:47434/home.html
|
||||
curl -sk http://localhost:47434/home.html | grep -c 'wd-sidebar\|wd-topbar\|wd-card'
|
||||
# Expect: 8+ matches
|
||||
```
|
||||
|
||||
Load `http://172.18.91.216:47434/home.html` in a browser. Sidebar should be the new one, breadcrumb shows "Home", stat tiles render as operational cards.
|
||||
|
||||
- [ ] **Step 4: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/home.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate home.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Migrate settings.html
|
||||
|
||||
System settings form. Lots of form-groups, possibly tabbed.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/settings.html`
|
||||
|
||||
- [ ] **Step 1: Read current page + identify all form sections**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
grep -E '<h[12]|form-group|form-section-label' settings.html | head -30
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Migrate using the standard recipe**
|
||||
|
||||
Same recipe as task 2, except for the form content:
|
||||
- Replace each form section with a `.wd-field-group` (header + body, no tabs unless the section is genuinely tabbed)
|
||||
- Replace every `<input>` with `class="wd-input"`, every `<select>` with `class="wd-select"`, every `<label>` with `class="wd-label"`
|
||||
- Replace every `<button>` with `class="wd-btn wd-btn--primary wd-btn--md"` (or `--secondary` / `--ghost` / `--danger` as appropriate)
|
||||
- Wrap rows of inputs in `.wd-form-row`
|
||||
- Preserve every `id`, `name`, `type`, and JS handler
|
||||
|
||||
Set `.wd-nav-item.is-active` on Settings.
|
||||
|
||||
- [ ] **Step 3: Deploy + check**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon && docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'settings=%{http_code}/%{size_download}\n' http://localhost:47434/settings.html
|
||||
```
|
||||
|
||||
Load in browser. Verify the form actually saves (test by changing one value and clicking save).
|
||||
|
||||
- [ ] **Step 4: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/settings.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate settings.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Migrate tokens.html
|
||||
|
||||
Lists API tokens, allows creation of new ones with a slide-panel. First page that exercises the slide-panel primitive in the migrated context.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/tokens.html`
|
||||
|
||||
- [ ] **Step 1: Read + identify the slide-panel structure**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
grep -E 'slide-panel|slide-overlay|wd-list-row' tokens.html | head -20
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Migrate**
|
||||
|
||||
- Standard shell recipe (sidebar with `is-active` on Tokens, topbar with "Tokens" breadcrumb and "New token" primary button)
|
||||
- Token list → `.wd-list` containing `.wd-list-row` for each token: name (cell--name), created date (cell--meta), badge for scope, action buttons in cell--actions
|
||||
- Create-token form moves into `.wd-slide-panel` (with overlay, header, body, footer pattern exactly as in the smoke page's field-group)
|
||||
- Preserve every JS handler — especially the copy-to-clipboard one for the newly-generated token
|
||||
|
||||
- [ ] **Step 3: Deploy + check**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon && docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'tokens=%{http_code}/%{size_download}\n' http://localhost:47434/tokens.html
|
||||
```
|
||||
|
||||
Load + verify: clicking "New token" opens the slide-panel (codec-clipping bug fix from wave 1 applies — body should scroll if it overflows), creating a token shows the copy-once display.
|
||||
|
||||
- [ ] **Step 4: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/tokens.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate tokens.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Migrate users.html
|
||||
|
||||
User management. List + edit slide-panel. Pattern matches tokens.html closely.
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/users.html`
|
||||
|
||||
- [ ] **Step 1: Read + identify**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
grep -E '<h[12]|wd-list|slide-panel' users.html | head
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Migrate using the tokens.html recipe**
|
||||
|
||||
Identical pattern to task 4: shell + list + slide-panel for create/edit. Mark Users active. Preserve every JS handler (role dropdown, password reset, etc.).
|
||||
|
||||
- [ ] **Step 3: Deploy + check**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon && docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'users=%{http_code}/%{size_download}\n' http://localhost:47434/users.html
|
||||
```
|
||||
|
||||
Verify: list renders, edit panel opens, save works.
|
||||
|
||||
- [ ] **Step 4: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/users.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate users.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Migrate containers.html
|
||||
|
||||
Docker container list. List rows with status badges + action buttons (logs / restart). No slide-panel (logs typically opens in a separate tab or inline).
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/web-ui/public/containers.html`
|
||||
|
||||
- [ ] **Step 1: Read + identify**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon/services/web-ui/public
|
||||
head -80 containers.html
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Migrate**
|
||||
|
||||
- Standard shell recipe (Containers active)
|
||||
- Container list → `.wd-list` with `.wd-list-row` per container:
|
||||
- cell--name: container name
|
||||
- cell with image: cell--meta
|
||||
- cell with status: `.wd-badge.wd-badge--good` (Up) / `.wd-badge--bad` (Down) / `.wd-badge--warn` (Restarting)
|
||||
- cell--actions: ghost buttons for Logs / Restart / Stop
|
||||
- Auto-refresh polling JS stays unchanged
|
||||
|
||||
- [ ] **Step 3: Deploy + check**
|
||||
|
||||
```bash
|
||||
cd /opt/wild-dragon && docker compose up -d --build web-ui 2>&1 | grep -E 'Built|Started' | tail -3
|
||||
sleep 4
|
||||
curl -sk -o /dev/null -w 'containers=%{http_code}/%{size_download}\n' http://localhost:47434/containers.html
|
||||
```
|
||||
|
||||
Load + verify: all containers visible, status badges color-coded, Logs button still opens logs.
|
||||
|
||||
- [ ] **Step 4: Commit + push**
|
||||
|
||||
```bash
|
||||
HOME=/root git add services/web-ui/public/containers.html
|
||||
HOME=/root git commit -m 'web-ui(wave 2): migrate containers.html to new primitives'
|
||||
HOME=/root git push 2>&1 | tail -3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Wave-2 user QA gate
|
||||
|
||||
- [ ] **Step 1: Verify all 6 migrated pages serve correctly**
|
||||
|
||||
```bash
|
||||
for p in login home settings tokens users containers; do
|
||||
printf ' %s.html: HTTP=%s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' http://localhost:47434/$p.html)"
|
||||
done
|
||||
```
|
||||
|
||||
Expected: all 200.
|
||||
|
||||
- [ ] **Step 2: Verify all 6 pages reference /dist/app.css and NOT common.css**
|
||||
|
||||
```bash
|
||||
for p in login home settings tokens users containers; do
|
||||
CNT_NEW=$(curl -sk http://localhost:47434/$p.html | grep -c dist/app.css)
|
||||
CNT_OLD=$(curl -sk http://localhost:47434/$p.html | grep -c common.css)
|
||||
printf ' %s.html: new=%s old=%s\n' "$p" "$CNT_NEW" "$CNT_OLD"
|
||||
done
|
||||
```
|
||||
|
||||
Expected: new=1 old=0 for every page.
|
||||
|
||||
- [ ] **Step 3: Verify wave-3 / wave-4 pages are STILL on the old CSS (no accidental change)**
|
||||
|
||||
```bash
|
||||
for p in index projects upload jobs api-tokens recorders cluster capture editor; do
|
||||
CNT_OLD=$(curl -sk http://localhost:47434/$p.html | grep -c common.css)
|
||||
printf ' %s.html: still-on-old=%s\n' "$p" "$CNT_OLD"
|
||||
done
|
||||
```
|
||||
|
||||
Expected: still-on-old=1 for every page (none of them migrated yet).
|
||||
|
||||
- [ ] **Step 4: User visual QA**
|
||||
|
||||
Stop. Ask user to load each of the 6 migrated pages and confirm the new look is correct, navigation still works, forms still save, lists still poll. If anything looks wrong, fix it before wave 3 starts.
|
||||
|
||||
---
|
||||
|
||||
## Self-review notes
|
||||
|
||||
- **Spec coverage**: Every page in the wave-2 list from the design spec is in the plan. Token cleanups from wave-1 review are folded in as task 0.
|
||||
- **Placeholders**: none. Every step has the actual command / file change.
|
||||
- **Type consistency**: every migrated page uses `.wd-shell` / `.wd-sidebar` / `.wd-topbar` / `.wd-nav-item.is-active` / `.wd-card-op` / `.wd-list` / `.wd-list-row` / `.wd-btn` / `.wd-input` / `.wd-select` / `.wd-label` / `.wd-form-row` / `.wd-field-group` — exact class names from the wave-1 bundle.
|
||||
- **Open risk**: each page migration is a manual markup rewrite. The implementer subagent needs to actually read each existing page before rewriting, not work from the description alone, because each page has page-specific JS handlers that must be preserved verbatim.
|
||||
Loading…
Reference in a new issue