cb2024f857
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.
2.4 KiB
2.4 KiB
Why
When a student pins a course in every elective set, the Top Plans panel goes blank and shows the placeholder "No plans yet achieve a specialization with the current pinned courses." This is misleading: the optimizer has already computed achievement (visible in the spec strip), but the Top Plans state is short-circuited to [] because no decision-tree search runs when there are no open sets. The student's completed plan IS the only plan — it should be the one rendered.
What Changes
- When
openSetIds.length === 0, synthesize a singlePlanOutcomefrom the pinned assignments +optimizationResult.achieved+ the priority scorer, and surface it through the existingtopPlansstate slice instead of clearing the slice. - Render the synthesized plan unconditionally (no
achievedSpecs.length > 0filter) so a 0-spec completed plan still shows the courses-and-zero-achievements summary rather than the search placeholder. - Header copy switches to "Your Plan" (singular) when
openSetIds.length === 0. Otherwise stays "Top Plans". - Leaf cache, search progress strip, "ranked by specs achieved" subtitle, and the search-complete/incomplete static text remain unchanged.
Capabilities
New Capabilities
None.
Modified Capabilities
optimization-engine: when all elective sets are pinned,useAppStateSHALL emit a single synthesizedPlanOutcomerather than clearing the top-K slice.unified-specialization-panel: the Top Plans panel SHALL render a synthesized completed plan with header copy "Your Plan" and SHALL NOT filter out a single completed plan with zero achievements.
Impact
app/src/state/appState.ts— replace thesetTopPlans([])early return with a synthesized one-element top-K whenopenSetIds.length === 0. UsemakePriorityScorer(state.ranking)(achieved)for the score.app/src/components/TopPlans.tsx— whenplans.length === 1and the only plan'scourseAssignmentscovers every elective set, render it as "Your Plan" (header copy). Drop thelength > 0visibility filter for that single-plan case so a 0-spec completed plan still renders. Other rendering paths unchanged.- No new tests strictly required, but a state-layer assertion for the synthesis would be nice. Existing 97 tests must continue to pass.
app/vite.config.ts— patch version bump (e.g.,1.5.1).CHANGELOG.md— release entry.- No data-file changes.