Repository navigation
Add core courses toggle to explorerΒ #21
Description
π§ Context
The Explorer (src/pages/Explorer.tsx) renders the full prerequisite DAG β every course in courseList becomes a node, laid out by dagre in computeLayout. With the current data that's ~25 nodes with heavy edge fan-out, which reads as an overwhelming wall on first load (nothing is selected yet, so everything is shown). With the full set of courses in the future, it'll be even denser.
This ticket makes the default view show only the core CS-program courses, with a toggle to opt into the full (overwhelming, but deliberate) graph. The data is already in place:
courses.jsoncarries acore?: booleanflag on each course.src/data/loadCourses.tsexportscoreCourseList(the core courses) alongsidecourseList,courses, andprereqEdges.
So: default = coreCourseList; "Show all" = courseList.
The Explorer already drops edges whose endpoints aren't both rendered (visibleEdges / knownCodes in Explorer.tsx). This ticket generalises that: the visible course set becomes core-only by default, and edge filtering follows from it.
Architecture (keep this seam)
This is the first feature that renders a subset of the graph, so set the pattern up cleanly β later filter modes (reachable-on-click, department/year, search) and edge features will build on it:
- Filtering lives outside layout. Compute the visible course set first, then hand it to
computeLayout.computeLayoutstays pure over its inputs β it lays out whatever nodes/edges it's given and must not read the toggle itself. (This also keeps the layout engine swappable in a later ticket without touching filter code.) - One "visible course set" is the single source of truth for what's shown. Edge filtering derives from it (an edge shows iff both endpoints are in the set). Expose/structure it so a later ticket can derive its own visibility from the same set β e.g. a synthetic gateway node, or a new kind of edge, shows only when its related course is visible. Don't hardcode "core vs all" anywhere except where the set is chosen.
- Selection behaviour is unchanged. Clicking a node still selects + highlights/dims via the existing
explorerStore; this ticket only changes which courses are in the graph and adds the toggle. Rebuilding the graph to a clicked course's reachable set is a separate, later ticket β do not do it here.
Watch out: "fake roots"
In core-only mode, a core course whose prerequisites are all non-core will have those edges dropped and render as if it has no prerequisites (a misleading "fake root"). The current core set was checked and is clean β every core course has at least one visible core prerequisite, and its non-core prereqs aren't graph nodes anyway, but keep this property in mind.
π οΈ Implementation Plan
Note: While working on this if you realize this draft plan isn't fully accurate, feel free to adjust as needed to achieve the desired functionality, and flag it in the PR description.
- Add toggle state to
explorerStoreβ e.g.showAllCourses: boolean(defaultfalse) plus a setter. This is UI state only, consistent with the store's existing role (it holds selection/highlight state, never course data). - Derive the visible course set in the Explorer from the flag:
showAllCourses ? courseList : coreCourseList. Keep this derivation outsidecomputeLayout. - Filter edges to those whose
fromandtoare both in the visible set (generalise the existingknownCodes/visibleEdgeslogic to use the visible set instead of the fullcourseList). - Pass the visible nodes + filtered edges into
computeLayout, and recompute layout when the visible set changes (the layoutuseMemomust now depend on the toggle / visible set, not run once). KeepcomputeLayoutpure over its inputs. - Add a toggle control inside the Explorer view (an overlay in a corner of the graph area) β not in the shared
Header, which renders on both routes. The label should reflect the current mode (e.g. "Show all courses" when core-only; "Show core only" when showing all). Let React FlowfitViewre-fit after the set changes so the new view is framed. - Leave click-to-select highlight/dim behaviour as-is; it should keep working within whatever set is currently visible.
- Run
pnpm devand confirm: core-only on load, toggle swaps to the full graph and back, no dangling edges, selection still highlights. Thenpnpm typecheck,pnpm lint,pnpm format,pnpm test.
β Acceptance Criteria
- On load, the Explorer shows only core courses (
coreCourseList), not the full graph - A toggle in the Explorer view (not in the shared
Header) switches between core-only and all courses, with a label that reflects the current mode - Toggling recomputes the layout over the new visible set and re-fits the view
- Edges render only between currently-visible courses β no edges dangling to hidden courses
- Existing click-to-select highlight/dim still works within the visible set
- Filtering happens outside
computeLayout;computeLayoutstays pure over its inputs and does not read the toggle - The visible course set is the single source for "what's shown," structured so a later ticket can derive its own visibility from it
- No fake roots in the default core view (every visible core course is a genuine root or has a visible prerequisite)
-
pnpm typecheck,pnpm lint,pnpm format:check, andpnpm testpass
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity