v1.5.1: Show completed plan in Top Plans

Once every elective set is pinned, the Top Plans panel now renders the
user's completed selection as a single "Your Plan" card showing the
achievement count and pinned courses. Previously the panel went blank
because the all-pinned branch in useAppState cleared topPlans, even
though the spec strip was already showing the achievement.

Synthesizes a single PlanOutcome from pinnedAssignments +
optimizationResult.achieved + the priority scorer; TopPlans detects the
all-pinned state via ELECTIVE_SETS.every(...) and bypasses the
length>0 filter so a 0-spec completed plan still renders honestly.
This commit is contained in:
2026-05-10 11:57:56 -04:00
parent 3a5ebaa17a
commit cb2024f857
10 changed files with 246 additions and 5 deletions
@@ -0,0 +1,24 @@
## 1. State synthesis
- [x] 1.1 In `app/src/state/appState.ts`, import `makePriorityScorer` from `../solver/priority`
- [x] 1.2 Replace the `setTopPlans([])` line in the `openSetIds.length === 0` early-return branch with a synthesized single-element top-K: `{ courseAssignments: pinnedAssignments, achievedSpecs: optimizationResult.achieved, priorityScore: scorer(optimizationResult.achieved) }`. Keep `setTreeResults([])`, `setTopPlansPartial(false)`, `setSearchProgress(null)`, `setTreeLoading(false)` as-is
- [x] 1.3 Confirm the synthesized state respects external credits implicitly via `optimizationResult.achieved` (no extra plumbing needed)
## 2. UI: detect all-pinned and render
- [x] 2.1 In `app/src/components/TopPlans.tsx`, compute `const allPinned = ELECTIVE_SETS.every((s) => pinnedCourses[s.id])`
- [x] 2.2 Switch the visibility filter: `const visible = allPinned ? plans : plans.filter((p) => p.achievedSpecs.length > 0)`
- [x] 2.3 Switch the header text: render `"Your Plan"` when `allPinned`, otherwise `"Top Plans"`
- [x] 2.4 Hide the "ranked by specs achieved" subtitle when `allPinned`
## 3. Tests + verification
- [x] 3.1 Run the existing 97-test suite; confirm all still pass
- [ ] 3.2 Browser verify: pin a single course in every set and observe that Top Plans now renders the completed plan with the same achievement count as the spec strip; header reads "Your Plan"
- [ ] 3.3 Browser verify the 0-spec edge case: pin courses that yield no achievement; the panel still shows the plan with `0` achievements (no "No plans yet…" placeholder)
- [ ] 3.4 Browser verify unpin: unpin one set, header reverts to "Top Plans", search runs normally
## 4. Version + changelog
- [x] 4.1 Bump `__APP_VERSION__` and `__APP_VERSION_DATE__` in `app/vite.config.ts` (e.g., `1.5.1`)
- [x] 4.2 Add a `CHANGELOG.md` entry: completed plan now surfaces in the Top Plans panel as "Your Plan" once every set is pinned; was previously empty