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 <noreply@anthropic.com>
This commit is contained in:
@@ -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 | - |
|
||||
|
||||
@@ -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
|
||||
|
||||
85
.planning/phases/11-candidate-ranking/11-02-SUMMARY.md
Normal file
85
.planning/phases/11-candidate-ranking/11-02-SUMMARY.md
Normal file
@@ -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 `<RankBadge rank={rank} />` in badge row
|
||||
- Updated `threads/$threadId.tsx`:
|
||||
- List/grid view toggle (LayoutList / LayoutGrid icons) using `candidateViewMode` from uiStore
|
||||
- Active list view: `<Reorder.Group>` wrapping `<CandidateListItem>` instances for drag-to-reorder
|
||||
- Resolved list view: plain `<div>` with `<CandidateListItem isActive={false}>` — rank badges visible, drag handles hidden
|
||||
- Grid view: existing `<CandidateCard>` 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.
|
||||
Reference in New Issue
Block a user