Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

10 — Interaction Specification (Results Module)

Precise interactions per screen. Motion defaults per 00-shared/08_Interaction_&_Motion.md; a11y obligations per 00-shared/09_Accessibility_Baseline.md; components C-* per 00-shared/03_Component_Library.md, R-* per 07_Component_Library.md.


I1 — Marks Entry Grid (S1)

I1.1 Keyboard & focus

  • Tab order per row: marksObtainedgraderemarks → next row's marksObtained.
  • Enter commits the focused cell and saves the row (per-row upsert, examination.service.ts:147-175); Tab from remarks moves to next student's marks field (when grid layout) or commits + moves (card layout).
  • Esc clears the row's dirty state back to last-saved value.

I1.2 Save choreography

  • Row states: clean → dirty → saving → saved | error (S1 §3).
  • saving: inline C-ProgressIndicator on the row only — never a full-screen block (row independence).
  • saved: row turns clean; C-AppSnackbar "Saved — {student}" < 3 s; multiple saves coalesce into one snackbar.
  • error: field shows errorText; row stays dirty; snackbar ≥ 4 s with requestId for 5xx.
  • "Save all pending": queues dirty rows in order; each still fires its own POST; failures leave that row dirty and continue others.

I1.3 Offline

  • Connectivity lost mid-entry → C-AppOfflineBanner; current edit remains in the field; row enters the offline draft (15_Flutter §Offline).
  • Reconnect → banner "n unsynced rows" with Sync action; replay in row order; per-row success/failure surfaced (failed rows stay dirty).

I1.4 Published rows

  • Rows with server publishedAt (examination-result.schema.ts:24-25) render locked (fields disabled, "Published" chip). UI-only — server still accepts writes ((planned) lock).

I2 — Exam-Subject Detail (S2)

  • Coverage progress animates width 300 ms on load (08_Interaction_&_Motion.md); announces once via SemanticsService — no repeated announcements on rebuild.
  • "Enter marks" → push S1; return preserves S1's dirty state (keep cubit alive in the navigator stack).

I3 — Student Results List (S3)

  • Pull-to-refresh refetches rows and re-groups; cache is refreshed, not evicted first (renders from old + updates in place).
  • Filter chips are instant, client-side, and sticky during session.
  • Tapping a group header collapses/expands the group (default expanded).

I4 — Report Card (S4)

  • Read-only: no edits, no pull-to-refresh; data is server-computed (result.service.ts:46-98).
  • Share action (web share sheet) shares a text summary (forward-looking); Print/PDF (planned) (Results.md:57).
  • Stale display: if exam status flips to published while the card is open (in-app event results-published), refresh the card and show the "Published" chip without user action.

I5 — Grade Summary & Publish (S5)

  • Aggregation runs N subject fetches; show skeleton bars; results stream in as each resolves (partial render).
  • Publish button: disabled until coverage = 100 % (advisory); on tap → C-AppDialog confirm (B4 warning, no-revert copy) → POST /api/v1/examinations/:id/publish (examination.controller.ts:54-56) → on 2xx replace banner with "Results published on {date}".
  • On 429 RATE_LIMITED: disable publish, show countdown of the retry window.

I6 — Motion & feedback summary

ActionFeedbackDuration
Row save startinline row spinner (static under reduced motion)until response
Row savedsnackbar success< 3 s
Row rejectedinline error + snackbar (4 s)≥ 4 s
Publish successbanner + snackbarbanner persists
Offlinebanner (persists until synced)persists
Coverage changeprogress bar 300 ms ease-out300 ms