Web UI rework (openspec/changes/web-ui-rework). Foundation slice: - Add @tanstack/react-table; remove orphaned recharts, d3 - Vendor shadcn primitives: tabs table dialog input label checkbox switch progress separator avatar textarea dropdown-menu scroll-area - Add Vitest + @testing-library/react + jsdom harness; npm test script - Delete no-op theme.ts shim; remove getAppTheme references - Smoke test proves the harness Gate: build + lint + test green.
10 KiB
Apply Progress — web-ui-rework
Cumulative apply log. Updated by
sdd-applyafter each slice/sub-slice. Strict TDD is not active for this change (no strict-tdd directive inopenspec/config.yaml); this run used standard mode againstdesign.md/tasks.md.
Status context consumed
schemaName: gentle-pi.sdd-status,changeName: web-ui-rework.applyStatereported by the status engine: blocked (blockedReasons: domain specs missing/partial; legacy flatspec.mdpresent without domain specs). This is a planning-completeness gap, not a safety/actionContextblocker.actionContext:mode: repo-local,workspaceRoot: /home/user/Manage_01,allowedEditRoots: ["/home/user/Manage_01"],warnings: []— safe.- This run executed the explicitly delegated Slice 1 (Foundation) scope per the
parent acceptance contract. The foundation work is fully specified in
tasks.md(Slice 1) and does not depend on the missing domain specs, so it proceeds under the parent's explicit delegation. Theinstructions.applyline itself says "Implement only unchecked tasks from the tasks artifact." artifactStore: openspec; persisted task checkboxes updated intasks.md(13 →[x]).
Slice 1 — Foundation (primitives, TanStack Table, Vitest, token/Badge cleanup) — COMPLETE
All 13 Slice-1 tasks in tasks.md are marked - [x]. Summary below.
Completed tasks (persisted checkboxes updated)
- Added the missing shadcn primitives (13):
tabs table dialog input label checkbox switch progress separator avatar textarea dropdown-menu scroll-areavianpx shadcn@latest add …. The 9 already-present primitives (button tooltip sheet card badge alert select skeleton collapsible) were not re-added. - Installed
@tanstack/react-table(^8.21.3, dependency). - Removed orphaned charting deps:
recharts,d3, and the companion@types/d3frompackage.json(zerofrom "recharts"/from "d3"/from "d3-*"imports existed infrontend/src). - Deleted
frontend/src/theme.ts(no-opgetAppThemeshim). Grep confirmed the only reference was the file itself; no source file imported it. - Added the
successBadge variant (chart-2) and thewarningvariant (chart-3) tofrontend/src/components/ui/badge.tsx, mirroring thedestructivesoft-cue pattern exactly per design §2.3. - Documented the
chart-1..5role mapping as an inline comment block above the tokens in both the@themeblock and.darkblock offrontend/src/index.css(chart-1=info/brand, chart-2=success, chart-3=warning, chart-4=destructive, chart-5=neutral-accent). No token value changed; no token dropped. Primary#4f8cff. - Created
frontend/vitest.config.ts(separate fromvite.config.ts):vitest/configdefineConfig,@vitejs/plugin-react,environment: "jsdom",globals: true,setupFiles: ["./src/test/setup.ts"], the@path alias fromtsconfig.app.json, andinclude: ["src/**/*.{test,spec}.{ts,tsx}"](does NOT claim thefrontend/tests/*.mjsnode suites). - Created
frontend/src/test/setup.tsregistering@testing-library/jest-dommatchers (via the/vitestentry for runtime + TS augmentation). - Installed dev deps:
vitest@^4.1.9,@testing-library/react@^16.3.2,@testing-library/jest-dom@^6.9.1,@testing-library/user-event@^14.6.1,jsdom@^29.1.1. - Added npm scripts:
"test": "vitest run","test:watch": "vitest","test:node": "node --test tests/*.test.mjs"(see Deviations). - Added one trivial passing component test:
src/components/ui/__tests__/badge.test.tsx(asserts asuccessBadge renders with thechart-2cue). - Verified lucide-react
1.14.0exports every name used by later slices:Pencil, X, Paperclip, Bold, Italic, Link, List, Mail, Send, Trash2, DatabaseBackup, ExternalLink.DatabaseBackupIS exported — no fallback needed (slice-3 nav will useDatabaseBackup). - Exit gate green:
npm run build+npm run lint+npm test+npm run test:nodeall pass; notheme/getAppThemeimports remain.
Files changed (tracked)
Modified:
frontend/package.json(added@tanstack/react-table, vitest/testing-library/jsdom dev deps, test scripts; removedrecharts,d3,@types/d3)frontend/package-lock.json(regenerated by npm)frontend/src/components/ui/badge.tsx(addedsuccess+warningvariants)frontend/src/components/ui/tabs.tsx(vendored primitive; un-exportedtabsListVariantsto satisfyreact-refresh/only-export-components— see Deviations)frontend/src/index.css(chart-1..5 role-mapping comment blocks in@theme+.dark)
Deleted:
frontend/src/theme.ts
Added (new):
frontend/vitest.config.tsfrontend/src/test/setup.tsfrontend/src/components/ui/__tests__/badge.test.tsx- 13 new shadcn primitives under
frontend/src/components/ui/:tabs.tsx, table.tsx, dialog.tsx, input.tsx, label.tsx, checkbox.tsx, switch.tsx, progress.tsx, separator.tsx, avatar.tsx, textarea.tsx, dropdown-menu.tsx, scroll-area.tsx
Untouched (no-unintended-edits respected): the 22 MUI page/component files in
Slice 1's scope (all frontend/src/pages/* and frontend/src/components/*.tsx outside
components/ui/) — git status --porcelain frontend/src/pages 'frontend/src/components/*.tsx' | grep -v 'components/ui/' returns nothing.
Also touched (gitignored generated docs, not tracked changes): frontend/src/.pi-map.md
and frontend/src/.pi-map.index.md were refreshed to remove the now-deleted theme.ts /
getAppTheme references (the project_map_patch tool is unavailable in this session, so
the stale generated maps were minimally reconciled to match source).
Commands run (validation)
npx shadcn@latest add tabs table dialog input label checkbox switch progress separator avatar textarea dropdown-menu scroll-area --yes→ created 14 files (13 primitives + a duplicate button written to a stray@/path; stray dir removed, dup button discarded).npm i @tanstack/react-table→ ok.npm i -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom→ ok.npm uninstall recharts d3 @types/d3→ ok.cd frontend && npm run build→ PASS (tsc -b+vite build).cd frontend && npm run lint→ PASS (0 errors, 0 errors; 2 pre-existingreact-hooks/exhaustive-depswarnings inUsersPage.impl.tsxthat are out of Slice-1 scope).cd frontend && npm test→ PASS (Vitest: 1 file, 1 test passed).cd frontend && npm run test:node→ PASS (legacy node:test suites green).
Deviations from design / task text (documented)
tabs.tsxvariant export. The vendored shadcntabs.tsxexportedtabsListVariants(acvafunction) alongside components, which violatesreact-refresh/only-export-componentsand brokenpm run lint. The project's own convention (button.tsx,select.tsx) is to not export thecvavariant helper, sotabsListVariantswas removed from theexport { … }statement (theconstis retained for internal use byTabsList). This keeps the component API intact for all later slices (TabbedCard uses<TabsList variant=…>, not the helper).test:nodescript form. The task text specifies"test:node": "node --test tests", but on Node v22.22.2 a bare directory argument is resolved as a CommonJS module entry point (Error: Cannot find module '…/tests'). The functional equivalent"test:node": "node --test tests/*.test.mjs"is used instead, which targets exactly the legacy node:test suites (users.test.mjs,userState.test.mjs) and passes.node --testauto-discovery also passes; the glob form is the explicit, minimal choice.- shadcn CLI path artifact. The CLI resolved the
@/alias to a literalfrontend/@/directory. All 13 primitives were moved tofrontend/src/components/ui/and the strayfrontend/@/tree was deleted; the duplicate generatedbutton.tsxwas discarded to keep the existing trackedbutton.tsxunchanged. - Stale generated
.pi-map.mdfiles referenced the deletedtheme.ts. Since theproject_map_patchtool is unavailable this session, they were minimally reconciled to match source (these are gitignored generated docs, not tracked changes).
Slice boundary / PR
- Slice 1 is the foundation slice (~vendored primitives dominate the line count). Per the Review Workload Forecast this slice is "at/over" 400 lines and may be taken as a vendored-primitives size exception or sub-split 1a/1b. The majority of the diff is generated shadcn primitives (mechanical, vendored). No delivery decision was provided in this run's delegation (the parent delegated a single foundation slice); this run implemented the whole foundation in one slice. The parent should confirm the PR shape (1a/1b split vs. generated-code size exception) when opening the PR.
Remaining tasks (Slices 2–8, 58 unchecked)
Slice 1 is the only completed slice. The remaining unchecked work (Slices 2–8) is listed
verbatim in tasks.md. The first unchecked items are (Slice 2 — Shared components):
- Migrate
frontend/src/components/SectionCard.tsx… - Migrate
frontend/src/components/SelectionRailCard.tsx… - … (see
tasks.mdSlice 2 → Slice 8)
Dependency order is fixed (DAG in tasks.md): 1 → 2 → {3,4,5,6}; 4 ← 3;
{3,4,5,6} → 7; {1..7} → 8. Next recommended: Slice 2 (Shared components) — it is
unblocked now that all primitives, TanStack Table, the Vitest harness, the success/
warning Badge variants, and the cleared theme.ts are in place.
Risks / notes for the parent
- The overall change
applyStateis blocked on missing domain specs (legacy flatspec.mdpresent without domain specs). This does not block Slice 1 (done) but should be resolved beforesdd-verify/archive. Recommended: convert/supplementspec.mdinto domain specs, or have the orchestrator confirm the flat spec is acceptable. - The two
react-hooks/exhaustive-depswarnings inUsersPage.impl.tsxare pre-existing and out of Slice-1 scope (lint still passes — warnings, not errors). npm auditreports 8 vulnerabilities in the dependency tree (pre-existing across the MUI/emotion/react stack); not introduced by this slice and out of scope.DatabaseBackupfrom lucide-react is available — Slice 3 nav should use it directly.