feat(gradebook): keep-highest N for equal-mode tabs + pin expanded rows#8438
Open
LWS49 wants to merge 4 commits into
Open
Conversation
422b4af to
44284da
Compare
df2ffce to
95135ce
Compare
2d24331 to
4c71a02
Compare
95135ce to
f875efc
Compare
7d9fdb4 to
ade1ddf
Compare
d4cb3aa to
72edac9
Compare
ade1ddf to
521efed
Compare
…links & sorting
Introduce the course gradebook: a frozen-column table of students × assessments
with a column picker, CSV export, and per-grade links into submissions.
Gradebook table
- Page with TanStack-backed table: pinned checkbox + Name columns, sticky
header and Max Marks rows, frozen-column border seams that survive sticky
scroll compositing.
- Column picker (assessments grouped by tab/category) and CSV export of the
selected columns; empty-state hint when no data columns are chosen.
- External ID column, shown when any student has one.
- Grade cells link to the student's submission; a dismissible GradeLinkHint
banner explains the affordance (persisted per-user via useDismissibleOnce).
- "Search students" global search.
- Default sort with name ascending, null/undefined at bottom of sort regardless of order
Shared table builder
- getColumnCanGlobalFilter is gated on column visibility ("search what you
see"): hiding a column via the picker removes it from search, and the
nullable-first-row type sniff is bypassed. Affects all TanStack tables.
Backend
- Gradebook controller, ability and course component; index JSON serializes
students, assessments, submissions (with submissionId) and gamification.
- Submission grade query also selects the submission id for grade links.
- Remove the redundant ScoreAssessmentSummary download from Statistics.
Add weighted view built on top of gradebook: - add tables course_gradebook_contributions and course_gradebook_assessment_contributions - weighted table with equal/custom weight modes and per-assessment weight inputs, with a sum gate on custom weights - points / percentage display toggle - inline per-student assessment breakdown (row expand) - projected-total hint - gradebook_excluded column, serialization, and update-weights API echo - per-assessment include/exclude in the configure-weights modal, seeding custom weights from included assessments only - excluded assessments shown in the breakdown with no contribution - add SegmentedSelect component for stylized selection that is not "on-off"
521efed to
2efbb02
Compare
Expanding a student in the weighted gradebook now keeps that student's summary row pinned beneath the sticky header while their per-assessment breakdown is open, so the totals stay visible while scrolling the detail. The view becomes a single-open accordion (opening one student collapses any other), the focused row auto-scrolls to just under the header on expand (respecting prefers-reduced-motion), and focus stays on the expand/collapse toggle for keyboard users.
- Permit keepHighest in update_weights_params - Parse keepHighest from request and pass to bulk_update via keep_highest - Echo keepHighest in serialize_weight_updates response - Serialize keepHighest from contribution in index.json.jbuilder - Add controller tests: round-trip persist and index response - Add model tests: bulk_update persists keep_highest in equal mode
72edac9 to
07a4215
Compare
b8aa279 to
b78d187
Compare
16ea8b5 to
1c5b845
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two features to the weighted gradebook view. First, instructors can configure a per-tab keep-highest limit in equal mode: after enabling it for a tab, only the top N submission ratios count toward that tab's subtotal - the rest are dropped as lowest. The limit only applies in equal mode (custom mode exposes per-assessment weights instead) and is stored as a new
gradebook_keep_highestcolumn oncourse_assessment_tabs. Second, the per-student score breakdown panel now pins to one open row at a time - expanding a second student collapses the first, keeping the table readable at scale.Design decisions
Regression prevention
Covers: keep-highest ratio selection and averaging, ties at the boundary, keepHighest > included (no drop), keepHighest=0 equality with legacy average, composition with per-assessment exclusion, dropped-vs-excluded display distinction in points and percentage modes, pin-to-one-expanded behaviour, keyboard focus retention on toggle, auto-scroll on expand,
keepHighestround-trip through the Redux reducer, model validation (non-negative integer), controller permit and serialisation.Manual testing: confirmed all scenarios above including keep-highest in equal mode, custom mode hiding the control, disabled state with one included assessment, save/reload persistence, dropped label and value rendering, and pin-expanded collapse behaviour.
Backward compat: tabs with no
gradebook_keep_highestvalue default to 0, which preserves existing averaging behaviour exactly.