[HnR-Autograder:5] Dashboard refactor - #7438
Conversation
There was a problem hiding this comment.
Pull request overview
Refactors the dashboard’s assignment activity view by extracting “students table” rendering/sync logic into a dedicated students-table module with pluggable variants (plain vs auto-grading), and updates tests accordingly.
Changes:
- Introduces a
students-tablemodule with variant resolution, row/column construction, and per-cell rendering. - Implements
plainandauto-gradingvariants, including grade syncing selection for auto-grading assignments. - Moves/adjusts tests: narrows
AssignmentActivityassertions and adds focusedstudents-tableunit tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lms/static/scripts/frontend_apps/components/dashboard/test/AssignmentActivity-test.js | Updates AssignmentActivity tests to assert variant wiring rather than per-cell rendering details. |
| lms/static/scripts/frontend_apps/components/dashboard/students-table/types.ts | Adds shared types for the new students-table variant system. |
| lms/static/scripts/frontend_apps/components/dashboard/students-table/test/index-test.js | Adds dedicated tests for variant resolution, row flattening, rendering, and sync-grade selection. |
| lms/static/scripts/frontend_apps/components/dashboard/students-table/plain.tsx | Implements the plain (non-grading) students table variant and shared row building / render helpers. |
| lms/static/scripts/frontend_apps/components/dashboard/students-table/index.ts | Provides variant registry/resolution and hooks for table config and grades-to-sync. |
| lms/static/scripts/frontend_apps/components/dashboard/students-table/auto-grading.tsx | Implements the auto-grading variant (grade column rendering + grades-to-sync). |
| lms/static/scripts/frontend_apps/components/dashboard/AssignmentActivity.tsx | Switches AssignmentActivity to consume the new students-table hooks and capability gating. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| * specific capability to the least, so that a variant which handles a narrower | ||
| * case than another is listed before it. | ||
| */ | ||
| const VARIANT_MODULES: ConditionalVariantModule[] = [autoGradingVariant]; |
There was a problem hiding this comment.
The comment above correctly identifies that two matching predicates means the first silently wins (including gradesToSync), so students would be graded by the wrong rule with no error surfaced. I'd delete the comment and add a testcase to assert this doesn't happen.
I asked claude to make a sample test for this and he did this:
describe('VARIANT_MODULES', () => {
// Two variants claiming the same assignment means the first listed wins
// silently, including its `gradesToSync`. Vacuous with one conditional
// variant; guards the next one.
[
{ label: 'auto-grading', assignment: autoGradingAssignment },
{ label: 'plain', assignment: plainAssignment },
].forEach(({ label, assignment }) => {
it(`claims the ${label} assignment with at most one variant`, () => {
assert.isAtMost(
VARIANT_MODULES.filter(module => module.matches(assignment)).length,
1,
);
});
});
});
edd19d2 to
321e65c
Compare
321e65c to
cb8af34
Compare
cb8af34 to
ef6df8c
Compare
ef6df8c to
8798259
Compare
Everything that varies by assignment type in the students table moves out of
AssignmentActivityand into a small registry of variant modules undercomponents/dashboard/students-table/. No user-visible change: the view renders exactly what it rendered before.The motivation is the next feature — auto-grading per checkpoint, which adds a column group per window.
AssignmentActivityalready branched onisAutoGradingAssignmentin five places (columns, rows, the cell renderer, the grades to sync, and the sync button gate); a third assignment type would have meant a third set of conditionals through the same view.What moved into a variant module:
buildRows— how the API representation of a student is flattened into a table row.columns()— which columns the variant displays, and in what ordrenderItem— how each cell is rendered.gradesToSync— which grades the next sync sends to the LMS.The view now asks for those four things and renders them, with no knowledge of what kind of assignment it is displaying.
How a variant is resolved:
resolveVariantModulepicks the first module whosematchespredicate claims the assignment, keyed on the data the API actually returns (auto_grading_config)rather than on an explicit type field.
plainVariantis the fallbae others do not claim, so an assignment exposing a capability thisversion of the frontend does not know about still renders its annotation metrics instead of breaking.Ordering matters and nothing enforces that the predicates are mutuamented at
VARIANT_MODULES, and worth an assertion once a secondconditional variant exists.gradesToSyncas a capability:A variant which does not define
gradesToSyncdoes not grade, andassignmentSyncsGradesuses that to gate both the sync button and the polling of the last syncstatus — so a non-grading variant issues no grade-sync requests at is therefore the safe default for a new variant.
Adding an assignment type is now one new file plus one line in
VARIANT_MODULES.Known leftover:
onSyncScheduledstill reaches intoauto_grading_gradeto optimied, so it is the last piece of variant-specific logic in the view. It is marked with aTODOexplaining where it should go (markGradesAsSynced, next togradesToSync) and why it is better designed against two real callers than guessed from this one.