feat(gradebook): weighted view with per-tab weights and exclude flag (pr3 of 3)#8419
Draft
LWS49 wants to merge 26 commits into
Draft
feat(gradebook): weighted view with per-tab weights and exclude flag (pr3 of 3)#8419LWS49 wants to merge 26 commits into
LWS49 wants to merge 26 commits into
Conversation
333c45a to
8b79b30
Compare
b37937a to
d4661f1
Compare
5508fd2 to
2f958d0
Compare
0e5d992 to
0155581
Compare
Introduces a course-wide gradebook showing per-student grades across all assessments. Instructors can toggle which assessment columns are visible via a hierarchical column picker (grouped by category/tab), then export the current view to CSV. Backend adds GradebookController#index (JSON), ability guard, and model methods on Assessment and Submission for fetching grade data. Table lib gains reusable ColumnPickerTemplate, MuiColumnPickerPrompt, ColumnPickerTreeGroup, and toolbar integration used by the gradebook.
- Add gradebook_weight (0-100 integer) column to course_assessment_tabs - Add manage_gradebook_weights/settings abilities (manager/owner only) - Add Course Admin -> Gradebook settings page to toggle the setting
1025c75 to
dd2063a
Compare
…alog, toolbar buttons, visibility state, and tests
- Add MuiColumnPickerDialog with Apply/Export actions, locked-column enforcement, and optional dataColumnIds hint when no data columns are selected
- Update MuiTableToolbar to render a trigger button (opens dialog) and a direct export button alongside the existing CSV download icon
- Extend useTanStackTableBuilder with column visibility state (localStorage persistence, dynamic reconciliation), onExportFromPicker, onDirectExport, and cross-page selection helpers (selectedCount, toggleAllFiltered, etc.)
- Add ColumnPickerTemplate interface and Body.ts selection fields
- Add full test coverage for dialog, toolbar, and hook behaviour
- Add lib.components.table.* locale keys (en/ko/zh)
- add Tab.update_gradebook_weights: transactional bulk update scoped to course tabs, with pre-flight ID validation and single pre-fetch query - extend GET /gradebook index JSON with weightedViewEnabled, canManageWeights, and per-tab gradebookWeight (gated by setting) - add PATCH /gradebook/weights: manager-only, returns 422 on validation failure or foreign tab, transactionally rolls back on any error
dd2063a to
7158142
Compare
…alog, toolbar buttons, visibility state, and tests
- Add MuiColumnPickerDialog with Apply/Export actions, locked-column enforcement, and optional dataColumnIds hint when no data columns are selected
- Update MuiTableToolbar to render a trigger button (opens dialog) and a direct export button alongside the existing CSV download icon
- Extend useTanStackTableBuilder with column visibility state (localStorage persistence, dynamic reconciliation), onExportFromPicker, onDirectExport, and cross-page selection helpers (selectedCount, toggleAllFiltered, etc.)
- Add ColumnPickerTemplate interface and Body.ts selection fields
- Add full test coverage for dialog, toolbar, and hook behaviour
- Add lib.components.table.* locale keys (en/ko/zh)
- Add gradebook_weight (0-100 integer) column to course_assessment_tabs - Add Course::Settings::GradebookComponent with weighted_view_enabled - Add manage_gradebook_weights/settings abilities (manager/owner only) - Add Course Admin -> Gradebook settings page to toggle the setting
- add Tab.update_gradebook_weights: transactional bulk update scoped to course tabs, with pre-flight ID validation and single pre-fetch query - extend GET /gradebook index JSON with weightedViewEnabled, canManageWeights, and per-tab gradebookWeight (gated by setting) - add PATCH /gradebook/weights: manager-only, returns 422 on validation failure or foreign tab, transactionally rolls back on any error
0155581 to
9d6cff0
Compare
…picker - add GradebookWeightedTable with 3-row sticky header showing per-tab additive weighted subtotals and per-student totals - add ConfigureWeightsPrompt for managers to edit tab weights (0–100) with real-time sum-to-100 warning and integer validation - add All vs By-weight view toggle in GradebookIndex (role-aware) - add column picker (Student info, Gamification groups); External ID defaults visible when any student has one, hidden otherwise - add computeWeighted helpers (computeTabSubtotal, computeStudentTotal, sumWeights) with full test coverage - add useDismissibleOnce hook for one-time dismissible hint UI
9d6cff0 to
dba6faa
Compare
Expose tab weight_mode and assessment gradebook_weight as numeric JSON fields in the gradebook API when weighted view is enabled. Fixes BigDecimal string serialization by using &.to_f for safe float conversion.
7158142 to
3316f5d
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
Implements the gradebook weighted view feature end-to-end. Adds a new staff-only gradebook page with two views: a flat "All assessments" table showing every published assessment, and a "By weight" view showing per-tab weighted totals (Canvas-style: Σ(tab% × weight), bonus allowed). The backend adds a
gradebook_weightcolumn on assessment tabs, grade summary queries, max-grade aggregation, and ability checks for staff read access and manager-only weight editing. The frontend adds a configurable per-tab weights dialog with an exclude-from-weighted-total flag, a course-admin toggle to enable the weighted view, and a one-time dismissable hint that surfaces the setting to managers before they've turned it on.Design decisions
CourseSuspendedAlertpattern (MUI Alert +Linkinto admin settings). Hint is manager-gated (canManageWeights) and only shows while the setting is off, so it disappears once it's done its job.${userId}:${key}- matches the pattern already used inuseTanStackTableBuilder; per-device behaviour is an accepted limitation for an onboarding nudge. Backend-persisted dismissal is the upgrade path if ever needed, deliberately deferred.Regression prevention
Automated tests cover: weighted total computation including excluded tabs (
computeWeighted.test.ts),ConfigureWeightsPromptrendering and exclude toggle,GradebookTableandGradebookWeightedTablecell rendering,GradebookColumnTree,GradebookIndexrouting and role gating,WeightedViewHintvisibility and dismissal,useDismissibleOncehook,GradebookSettingsadmin toggle, backend controller specs forindexandupdate_weights, and model specs forTab#gradebook_weight,Assessment.max_grades,Submission.grade_summary, and ability checks.Manual testing confirmed: manager sees hint when weighted view is off; hint absent when weighted view is on; TA/staff sees no hint; dismiss persists across page reload; dismissed state is per-user (second manager sees it fresh); settings link navigates correctly to Course Settings → Gradebook.
Backward compat preserved - weighted view is additive; existing gradebook pages and assessment flows are unchanged.