Skip to content

feat(gradebook): add weighted view with per-tab grade weights (pr3 of 3)#8419

Draft
LWS49 wants to merge 1 commit into
lws49/feat-gradebook-weights-pr2-apifrom
lws49/feat-gradebook-weights-pr3-fe
Draft

feat(gradebook): add weighted view with per-tab grade weights (pr3 of 3)#8419
LWS49 wants to merge 1 commit into
lws49/feat-gradebook-weights-pr2-apifrom
lws49/feat-gradebook-weights-pr3-fe

Conversation

@LWS49
Copy link
Copy Markdown
Collaborator

@LWS49 LWS49 commented May 29, 2026

Summary

Adds a "By weight" view to the staff gradebook so course managers can assign per-tab grade weights and see weighted subtotals and a Total column per student. The view is gated behind a course-level setting toggled from Course Admin → Gradebook. When enabled, a toggle group appears in the gradebook toolbar; the default view (All assessments) is unchanged.

Managers can open a Configure Weights dialog to assign integer weights (0–100) per tab. Weights do not need to sum to 100 — the Total is normalised to whatever the weights sum to, and a warning is shown when the sum is off. A "Treat Ungraded as 0" toggle adjusts how missing submissions are counted, matching the Canvas-style convention. TAs see the weighted view and subtotals but not the Configure Weights button.

This is PR 3 of 3. PR 1 added the gradebook_weight column, weighted_view_enabled course setting, and abilities. PR 2 exposed those via the gradebook JSON and added the PATCH /gradebook/weights endpoint.

Design decisions

  • Weights normalise, not clamp to 100 - saving weights that do not sum to 100 is allowed; the Total divides by actual weight sum rather than 100. This avoids blocking saves mid-edit and matches how most LMSes handle partial configurations.
  • "Treat Ungraded as 0" is view-only, not persisted - the toggle only affects the current browser session. Persisting it would require a user preference store; the spec explicitly deferred that.
  • Compute helpers are pure functions in a separate module - computeTabSubtotal and computeStudentTotal live in computeWeighted.ts with no Redux dependencies, making them independently testable and reusable.
  • ConfigureWeightsDialog calls dispatch(updateGradebookWeights(...)) not the thunk factory directly - the thunk pattern requires dispatch; calling the factory without it silently discards the API call (caught and fixed in review).

Regression prevention

Tests added:

  • computeWeighted.test.ts - covers null propagation (empty tab, no grades, toggle off), ratio calculation, ungraded-as-zero, weighted average, weight-0 exclusion, normalisation when weights ≠ 100
  • ConfigureWeightsDialog.test.tsx - covers rendering, live sum, sum ≠ 100 warning, inline errors for out-of-range and non-integer values, Save dispatch, Cancel no-op
  • GradebookWeightedTable.test.tsx - covers 3-row header structure, Total column warning, per-student subtotals, tab with no assessments (dash), Treat Ungraded as 0 recompute, all-weights-zero empty state, canManageWeights gate on Configure Weights button
  • GradebookIndex.test.tsx (+3) - toggle hidden when setting off, toggle shown when on, By weight view mounts on click
  • All 77 gradebook tests pass; no regressions in existing table, column-picker, or CSV tests

Backward compatibility - the "All assessments" view and all existing gradebook behaviour are unchanged. The weighted view is only reachable when the course-level setting is explicitly enabled.

Manual testing checklist (to be run before merge):

  • Enable "Calculate total by tab weights" in course admin settings as manager; reload and confirm it persists; TA/student hitting /admin/gradebook is blocked
  • Navigate to gradebook - "All assessments | By weight" toggle appears; default is All assessments (existing view unchanged)
  • Switch to By weight → click Configure Weights → enter weights (e.g. 60 / 40) → Save → subtotal columns and Total column populate with correct percentages
  • Set weights to 60 / 30 → warning in dialog and "90% total ⚠" in Total column subheader
  • Set all weights to 0 → empty-state banner appears; Total shows "—"
  • Flip "Treat Ungraded as 0" → ungraded submissions count as 0 toward denominator; numbers change; flip back and numbers restore
  • Sign in as TA → weighted view and subtotals visible; Configure Weights button absent
  • Disable setting in admin → gradebook shows All assessments only with no toggle; re-enable → weights still intact

… toggle

- add GradebookWeightedTable with 3-row sticky header showing per-tab
  weighted subtotals and overall weighted totals per student
- add ConfigureWeightsDialog for managers to edit tab weights (0–100),
  with sum-to-100 warning and integer/NaN validation
- add All vs By-weight view toggle in GradebookIndex (role-aware)
- add computeWeighted helpers for tab subtotal and student total
- store weightedViewEnabled, canManageWeights, and per-tab gradebookWeight
  from API; wire updateWeights thunk for PATCH /gradebook/weights
- add i18n keys and full test coverage for table, dialog, and helpers
@LWS49 LWS49 changed the title Lws49/feat gradebook weights pr3 fe feat(gradebook): add weighted view with per-tab grade weights May 29, 2026
@LWS49 LWS49 changed the title feat(gradebook): add weighted view with per-tab grade weights feat(gradebook): add weighted view with per-tab grade weights (pr3 of 3) May 29, 2026
@LWS49 LWS49 changed the base branch from master to lws49/feat-gradebook-weights-pr2-api May 29, 2026 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant