From 4304d0fcd7a7c4bd33c49d4f4b986afcce6265e6 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 16 Mar 2026 22:30:32 +0100 Subject: [PATCH] docs(11-02): complete drag-to-reorder ranking UI plan - Add 11-02-SUMMARY.md with implementation details and deviation docs - Update STATE.md: progress 100%, decisions, session record - Update ROADMAP.md: phase 11 complete (2/2 plans with summaries) Co-Authored-By: Claude Opus 4.6 --- .planning/ROADMAP.md | 6 +- .planning/STATE.md | 15 ++-- .../11-candidate-ranking/11-02-SUMMARY.md | 85 +++++++++++++++++++ 3 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 .planning/phases/11-candidate-ranking/11-02-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 9cfdae7..2209885 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -41,7 +41,7 @@ **Milestone Goal:** Give users the tools to actually decide between candidates — compare details side-by-side, see how a pick impacts their setup, and rank/annotate their options. - [x] **Phase 10: Schema Foundation + Pros/Cons Fields** — Migrate schema and deliver pros/cons annotation UI (completed 2026-03-16) -- [ ] **Phase 11: Candidate Ranking** — Drag-to-reorder priority ranking with rank badges +- [x] **Phase 11: Candidate Ranking** — Drag-to-reorder priority ranking with rank badges (completed 2026-03-16) - [ ] **Phase 12: Comparison View** — Side-by-side tabular comparison with relative deltas - [ ] **Phase 13: Setup Impact Preview** — Per-candidate weight and cost delta against a selected setup @@ -69,7 +69,7 @@ Plans: 2. The reordered sequence is still intact after navigating away and returning 3. The top three candidates display gold, silver, and bronze rank badges respectively 4. Drag handles and rank badges are absent on a resolved thread; candidates render in static order -**Plans:** 1/2 plans executed +**Plans:** 2/2 plans complete Plans: - [ ] 11-01-PLAN.md — Schema migration, reorder service/route, sort_order persistence + tests - [ ] 11-02-PLAN.md — Drag-to-reorder UI, list/grid toggle, rank badges, resolved-thread guard @@ -110,6 +110,6 @@ Plans: | 8. Search, Filter, and Candidate Status | v1.2 | 2/2 | Complete | 2026-03-16 | | 9. Weight Classification and Visualization | v1.2 | 2/2 | Complete | 2026-03-16 | | 10. Schema Foundation + Pros/Cons Fields | v1.3 | 1/1 | Complete | 2026-03-16 | -| 11. Candidate Ranking | 1/2 | In Progress| | - | +| 11. Candidate Ranking | 2/2 | Complete | 2026-03-16 | - | | 12. Comparison View | v1.3 | 0/TBD | Not started | - | | 13. Setup Impact Preview | v1.3 | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 14ec2a0..13851ac 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.3 milestone_name: Research & Decision Tools status: planning -stopped_at: Completed 11-candidate-ranking/11-01-PLAN.md -last_updated: "2026-03-16T21:23:51.903Z" +stopped_at: Completed 11-candidate-ranking/11-02-PLAN.md +last_updated: "2026-03-16T21:30:15.460Z" last_activity: 2026-03-16 — Roadmap created for v1.3 milestone progress: total_phases: 4 - completed_phases: 1 + completed_phases: 2 total_plans: 3 - completed_plans: 2 + completed_plans: 3 percent: 0 --- @@ -52,6 +52,7 @@ Progress: [░░░░░░░░░░] 0% *Updated after each plan completion* | Phase 10-schema-foundation-pros-cons-fields P01 | 6min | 2 tasks | 9 files | | Phase 11-candidate-ranking P01 | 4min | 2 tasks | 8 files | +| Phase 11-candidate-ranking P02 | 4min | 3 tasks | 7 files | ## Accumulated Context @@ -69,6 +70,8 @@ Key v1.3 research findings (see research/SUMMARY.md): - [Phase 11-candidate-ranking]: sortOrder uses REAL type for future fractional midpoint insertions without bulk rewrites - [Phase 11-candidate-ranking]: 1000-gap sort_order strategy: first=1000, append=max+1000, reorder resets to (index+1)*1000 - [Phase 11-candidate-ranking]: Applied sort_order migration via sqlite3 CLI directly to avoid Drizzle data-loss warning on existing rows +- [Phase 11-candidate-ranking]: Resolved thread list view uses plain div (not Reorder.Group) — no drag, rank badges visible +- [Phase 11-candidate-ranking]: RankBadge exported from CandidateListItem for reuse in CandidateCard grid view ### Pending Todos @@ -80,6 +83,6 @@ None active. ## Session Continuity -Last session: 2026-03-16T21:23:51.901Z -Stopped at: Completed 11-candidate-ranking/11-01-PLAN.md +Last session: 2026-03-16T21:30:15.459Z +Stopped at: Completed 11-candidate-ranking/11-02-PLAN.md Resume file: None diff --git a/.planning/phases/11-candidate-ranking/11-02-SUMMARY.md b/.planning/phases/11-candidate-ranking/11-02-SUMMARY.md new file mode 100644 index 0000000..3c62d94 --- /dev/null +++ b/.planning/phases/11-candidate-ranking/11-02-SUMMARY.md @@ -0,0 +1,85 @@ +--- +phase: 11-candidate-ranking +plan: "02" +subsystem: client-ui +tags: [drag-reorder, framer-motion, rank-badges, view-toggle, list-view] +dependency_graph: + requires: [11-01] + provides: [drag-to-reorder-ui, rank-badges, list-grid-toggle] + affects: [threads/$threadId.tsx, CandidateCard, CandidateListItem, uiStore, useCandidates] +tech_stack: + added: [] + patterns: + - framer-motion Reorder.Group + Reorder.Item with useDragControls for drag handle + - tempItems pattern to prevent React Query flicker during optimistic drag + - RankBadge exported from CandidateListItem for reuse across views + - candidateViewMode in uiStore for list/grid toggle state +key_files: + created: + - src/client/components/CandidateListItem.tsx + modified: + - src/client/hooks/useCandidates.ts + - src/client/stores/uiStore.ts + - src/client/components/CandidateCard.tsx + - src/client/routes/threads/$threadId.tsx + - src/client/lib/iconData.tsx + - src/client/hooks/useThreads.ts +decisions: + - Resolved thread list view uses plain div (not Reorder.Group) — no drag, rank badges visible + - handleDragEnd fires on Reorder.Group onPointerUp to debounce reorder API call + - biome-ignore applied to useExhaustiveDependencies for thread?.candidates dep — intentional trigger +metrics: + duration: 4min + completed: 2026-03-16T21:29:07Z + tasks_completed: 3 + files_changed: 7 +--- + +# Phase 11 Plan 02: Drag-to-Reorder UI Summary + +Drag-to-reorder candidate ranking with list/grid view toggle, gold/silver/bronze rank badges, and framer-motion Reorder.Group with tempItems flicker prevention. + +## What Was Built + +### Task 1: useReorderCandidates hook + uiStore view mode + CandidateListItem component +- Added `useReorderCandidates` mutation hook to `useCandidates.ts` using `apiPatch` to hit `PATCH /api/threads/:id/candidates/reorder` +- Added `candidateViewMode: "list" | "grid"` and `setCandidateViewMode` to `uiStore.ts` +- Created `CandidateListItem.tsx` — horizontal card for list view with drag handle (GripVertical), RankBadge (medal icon), 48x48 image thumbnail, badge row (weight/price/category/status/pros-cons), and hover-reveal action buttons +- Exported `RankBadge` component (gold `#D4AF37`, silver `#C0C0C0`, bronze `#CD7F32`) for reuse +- Added `style` prop support to `LucideIcon` for colored medal icons +- Added `pros` and `cons` fields to `CandidateWithCategory` in `useThreads.ts` (Rule 2 auto-fix — missing after Phase 10) + +### Task 2: Thread detail page with view toggle, Reorder.Group, rank badges in grid view +- Updated `CandidateCard.tsx`: added `rank?: number` prop and renders `` in badge row +- Updated `threads/$threadId.tsx`: + - List/grid view toggle (LayoutList / LayoutGrid icons) using `candidateViewMode` from uiStore + - Active list view: `` wrapping `` instances for drag-to-reorder + - Resolved list view: plain `
` with `` — rank badges visible, drag handles hidden + - Grid view: existing `` grid with `rank={index + 1}` passed to each card + - `tempItems` state: holds in-progress drag order, falls back to `thread.candidates` when null + - `handleDragEnd`: fires `reorderMutation.mutate({ orderedIds })` and clears tempItems on settled + - `useEffect` clears tempItems when `thread?.candidates` reference changes (fresh server data) + +### Task 3: Human verification (auto-approved — auto_chain_active) + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 2 - Missing] Added pros/cons fields to CandidateWithCategory in useThreads.ts** +- **Found during:** Task 1 (needed by CandidateListItem) +- **Issue:** `CandidateWithCategory` interface in `useThreads.ts` was missing `pros` and `cons` fields added in Phase 10. CandidateListItem needed these to render the "+/- Notes" badge. +- **Fix:** Added `pros: string | null` and `cons: string | null` to the interface +- **Files modified:** `src/client/hooks/useThreads.ts` +- **Commit:** acfa995 + +**2. [Rule 2 - Missing] Added style prop to LucideIcon component** +- **Found during:** Task 1 (needed by RankBadge for medal colors) +- **Issue:** LucideIcon only accepted `className` for styling; RankBadge needed inline `style={{ color }}` for gold/silver/bronze hex colors not achievable via Tailwind +- **Fix:** Added optional `style?: React.CSSProperties` prop to LucideIcon and passed through to icon component +- **Files modified:** `src/client/lib/iconData.tsx` +- **Commit:** acfa995 + +## Self-Check: PASSED + +All created/modified files exist. Both task commits (acfa995, 94c07e7) confirmed in git log.