docs(38-02): complete admin tag management client UI plan
- Add 38-02-SUMMARY.md - Advance STATE.md to 38-02 complete - Mark 38-02-PLAN.md complete in ROADMAP.md
This commit is contained in:
@@ -280,7 +280,7 @@ Plans:
|
|||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
- [x] 38-01-PLAN.md — Schema migration (parentId), service layer (CRUD + cycle detection), API routes, tests
|
- [x] 38-01-PLAN.md — Schema migration (parentId), service layer (CRUD + cycle detection), API routes, tests
|
||||||
- [ ] 38-02-PLAN.md — Client hooks, tag list page (tree view + quick-add + search), edit page (rename/reparent/delete), sidebar activation
|
- [x] 38-02-PLAN.md — Client hooks, tag list page (tree view + quick-add + search), edit page (rename/reparent/delete), sidebar activation
|
||||||
|
|
||||||
**UI hint**: yes
|
**UI hint**: yes
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ gsd_state_version: 1.0
|
|||||||
milestone: v2.4
|
milestone: v2.4
|
||||||
milestone_name: Admin Foundation
|
milestone_name: Admin Foundation
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 35-03-PLAN.md — FIX-05 (cursor-pointer audit) resolved
|
stopped_at: Completed 38-02-PLAN.md — admin tag management client UI
|
||||||
last_updated: "2026-04-19T20:29:07.741Z"
|
last_updated: "2026-04-19T20:32:22Z"
|
||||||
last_activity: 2026-04-19
|
last_activity: 2026-04-19
|
||||||
progress:
|
progress:
|
||||||
total_phases: 20
|
total_phases: 20
|
||||||
@@ -30,7 +30,7 @@ Plan: 2 of 2
|
|||||||
Status: Ready to execute
|
Status: Ready to execute
|
||||||
Last activity: 2026-04-19
|
Last activity: 2026-04-19
|
||||||
|
|
||||||
Progress: [████████░░] 94%
|
Progress: [█████████░] 97%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -110,6 +110,6 @@ Items carried forward from v2.3:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-19T20:29:07.738Z
|
Last session: 2026-04-19T20:32:22Z
|
||||||
Stopped at: Completed 35-03-PLAN.md — FIX-05 (cursor-pointer audit) resolved
|
Stopped at: Completed 38-02-PLAN.md — admin tag management client UI
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
94
.planning/phases/38-admin-tag-management/38-02-SUMMARY.md
Normal file
94
.planning/phases/38-admin-tag-management/38-02-SUMMARY.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
phase: 38-admin-tag-management
|
||||||
|
plan: "02"
|
||||||
|
subsystem: client
|
||||||
|
tags: [admin, tags, react-query, tree-view, crud]
|
||||||
|
dependency_graph:
|
||||||
|
requires: ["38-01"]
|
||||||
|
provides: ["admin-tag-ui"]
|
||||||
|
affects: ["src/client/routes/admin/", "src/client/hooks/"]
|
||||||
|
tech_stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- collapsible tree view with buildTree/flattenTree/filterTree utilities
|
||||||
|
- dual React Query key invalidation (admin-tags + tags)
|
||||||
|
- cycle-safe parent picker via getDescendantIds client-side filtering
|
||||||
|
- impact-aware delete confirmation (item count + child count)
|
||||||
|
key_files:
|
||||||
|
created:
|
||||||
|
- src/client/hooks/useAdminTags.ts
|
||||||
|
- src/client/routes/admin/tags.tsx
|
||||||
|
- src/client/routes/admin/tags.$tagId.tsx
|
||||||
|
modified:
|
||||||
|
- src/client/routes/admin.tsx
|
||||||
|
decisions:
|
||||||
|
- "buildTree/flattenTree/filterTree co-located in tags.tsx — pure JS utilities, no separate lib file needed"
|
||||||
|
- "Dual query key invalidation on all tag mutations keeps public tags cache fresh alongside admin cache"
|
||||||
|
- "getDescendantIds used client-side for parent picker filtering — server validates cycles authoritatively"
|
||||||
|
metrics:
|
||||||
|
duration: "2m"
|
||||||
|
completed: "2026-04-19"
|
||||||
|
tasks_completed: 2
|
||||||
|
tasks_total: 2
|
||||||
|
files_changed: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 38 Plan 02: Admin Tag Management Client UI Summary
|
||||||
|
|
||||||
|
React Query hooks, collapsible tree list page, edit page with cycle-safe reparent and impact-aware delete confirmation, and Tags sidebar link activated in the admin panel.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| # | Name | Commit | Files |
|
||||||
|
|---|------|--------|-------|
|
||||||
|
| 1 | Client hooks + tag list page with tree view and quick-add | 1f8b85d | useAdminTags.ts, admin/tags.tsx |
|
||||||
|
| 2 | Tag edit page with rename, reparent, delete + sidebar link activation | 0571ee4 | admin/tags.$tagId.tsx, admin.tsx |
|
||||||
|
|
||||||
|
## What Was Built
|
||||||
|
|
||||||
|
### `src/client/hooks/useAdminTags.ts`
|
||||||
|
|
||||||
|
Five React Query hooks: `useAdminTags` (list), `useAdminTag` (single with 404 retry suppression), `useCreateAdminTag`, `useUpdateAdminTag`, `useDeleteAdminTag`. All mutations invalidate both `["admin-tags"]` and `["tags"]` to keep the public tag cache fresh.
|
||||||
|
|
||||||
|
### `src/client/routes/admin/tags.tsx`
|
||||||
|
|
||||||
|
Tag list page at `/admin/tags` with:
|
||||||
|
- `buildTree` — builds hierarchical tree from flat array with self-referential parent links
|
||||||
|
- `flattenTree` — depth-first flatten respecting the `expanded` Set for show/hide
|
||||||
|
- `filterTree` — recursive filter that preserves parent rows when descendants match
|
||||||
|
- Collapsible chevron-based tree rows with 20px-per-depth indentation
|
||||||
|
- Quick-add inline form with name input, parent picker (`No parent (top-level)` default), and "Add Tag" button
|
||||||
|
- Search input filtering tree in-place
|
||||||
|
- Skeleton loading, error state, two empty states (no tags / no search results)
|
||||||
|
|
||||||
|
### `src/client/routes/admin/tags.$tagId.tsx`
|
||||||
|
|
||||||
|
Tag edit page at `/admin/tags/$tagId` with:
|
||||||
|
- `getDescendantIds` — recursively collects all descendant IDs to exclude from parent picker (client-side cycle prevention)
|
||||||
|
- `getDeleteConfirmText` — builds contextual confirmation: item count warning + child count warning + "This cannot be undone."
|
||||||
|
- Name rename field and cycle-safe parent picker (`parentOptions` excludes self + all descendants)
|
||||||
|
- Delete confirmation modal with impact-aware body text per D-13/D-14
|
||||||
|
- Actions row: Delete Tag (left, destructive) / Save Changes (right, primary)
|
||||||
|
|
||||||
|
### `src/client/routes/admin.tsx`
|
||||||
|
|
||||||
|
Replaced the disabled `<div cursor-not-allowed>` Tags entry with an active `<Link to="/admin/tags">` following the Items link pattern. "Soon" badge removed.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None — plan executed exactly as written.
|
||||||
|
|
||||||
|
## Threat Surface Scan
|
||||||
|
|
||||||
|
No new network endpoints, auth paths, or schema changes introduced (client-only plan). T-38-05 admin shell guard already present in admin.tsx. T-38-06 client-side cycle prevention implemented as UX layer; server validates authoritatively.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- src/client/hooks/useAdminTags.ts: FOUND
|
||||||
|
- src/client/routes/admin/tags.tsx: FOUND
|
||||||
|
- src/client/routes/admin/tags.$tagId.tsx: FOUND
|
||||||
|
- src/client/routes/admin.tsx: modified (contains `to="/admin/tags"`, no `cursor-not-allowed`)
|
||||||
|
- Commit 1f8b85d: FOUND
|
||||||
|
- Commit 0571ee4: FOUND
|
||||||
|
- Build: PASSED (✓ built in 964ms)
|
||||||
|
- Tests: PASSED (500 pass, 0 fail)
|
||||||
Reference in New Issue
Block a user