Repository navigation
ReportingUnitBlockDetails
type: Component title: ReportingUnitBlockDetails description: Read-only District Average block details page at /reporting-units/$ruId/$blockId (issue #1369). tags: [frontend, react, reporting-unit, district-average, read-only, page] timestamp: 2026-10-01T00:00:00Z
ReportingUnitBlockDetailsPage renders the read-only District Average block details page for a single reporting unit. It fetches the reporting unit, shows the page banner with a clickable breadcrumb and a focusable h1, the Block Details Summary card, and a Back action. The former results region was removed (decision D8) — the blocks list pattern now lives on the Reporting Unit Details page (ReportingUnitBlocksList).
/reporting-units/$ruId/$blockId (issue #1369, parent epic #625). Renamed from /reporting-units/$ruId/blocks/$blockId on 2026-10-01 (decision D8) — blockId is a direct child of the reporting unit, mirroring the backend AttachmentController mapping /api/reporting-units/{reportingUnitId}/{blockId}/attachments.
Registered as the file route frontend/src/routes/_authenticated/reporting-units/$ruId/$blockId.tsx, a sibling of $ruId/index.tsx in the reporting-units/ folder. It sits directly under the _authenticated gate, so the shell (<Layout>) comes from the layout, not the page. Route params are read in the component with useParams({ strict: false }) and parsed with Number().
| Gate | Where | Behavior when the user fails |
|---|---|---|
| Authentication |
_authenticated layout (by file placement) |
Unauthenticated → persist target, redirect to /login
|
| Feature flag |
beforeLoad in the route file checks reporting-unit-block-details-enabled (the route's own dedicated flag, same beforeLoad + throw notFound() pattern as reporting-unit-details-enabled on the RU details route) |
Throws notFound() — auth-aware 404 (NotFoundPage in the shell; unauthenticated visitors are sent to /) |
The route carries no role restriction: it is available to any authenticated user while the flag is on, because it belongs to neither the _admin nor the _client-access tier. That predates the file-based router migration — the earlier D9-era ADMIN role gate (see the historical decision note below) was dropped from the registry by #1254 (block creation and block details, 2026-10-13), nine days before the migration. The file route preserves the registry's final behaviour exactly: authentication plus reporting-unit-block-details-enabled, with no behavioural change at migration. The flag entry, including its environment matrix, is documented on Feature Flags.
- Source:
frontend/src/pages/ReportingUnitBlockDetails/index.tsx - Styles:
frontend/src/pages/ReportingUnitBlockDetails/index.scss - Tests:
frontend/src/pages/ReportingUnitBlockDetails/index.unit.test.tsx,index.e2e.test.tsx,index.a11y.test.tsx
| Name | Type | Description |
|---|---|---|
ReportingUnitBlockDetailsPage |
FC (default export) |
Page component consumed by the route table. |
Page-internal constants (not exported): EVENT_TARGET = 'reporting-unit-block-details' scopes the inline error notification.
The page renders one of three branches based on the useReportingUnitDetailsQuery result:
| Branch | Condition | Renders |
|---|---|---|
| Loading | isLoading |
Block Details Skeleton after 300 ms via the Delayed Flag Hook; nothing before that |
| Error / missing |
isError or no data
|
PageTitle Reporting Unit Block not found + Page Notification (eventTarget) + primary Retry button (refetch()) + secondary Back button (renderIcon={ArrowLeft}, typed navigate({ to: '/reporting-units/$ruId', params: { ruId: String(ruId) } })) |
| Success | data resolved | Banner + Page Notification + Block Details Summary + secondary Back button |
- PageTitle with
titleset toReporting Unit No. {ruId},subtitleset toView reporting unit details, andbreadCrumbsset to:
breadCrumbs={[
{ name: 'Reporting unit', path: `/reporting-units/${ruId}` },
{ name: 'Blocks', path: `/reporting-units/${ruId}/${blockId}` },
]}- Both crumbs are clickable (decision D6 — deviates from the issue acceptance criteria, which asked for a plain-text Blocks crumb). The Blocks crumb points to the current route: under decision D8 the blocks list lives on the Reporting Unit Details page rather than its own route, so
/reporting-units/$ruId/$blockId— a block addressed as a direct child of its reporting unit — is the deepest addressable path. - Focus: the banner
Columnholds a ref; once data resolves, auseEffectsetstabindex="-1"on theh1and calls.focus().PageTitleitself is unchanged. - Results region (removed 2026-10-01, decision D8): the empty pageable Table that previously rendered here (
id="block-details-results") was removed — the pattern now lives on the RU page's ReportingUnitBlocksList blocks list, which renders the built-inNo resultsstate until issue #1250 lands.
- Restructure in force (decision D8, 2026-10-01): the tombstone stays on the Reporting Unit Details page, a blocks list section was added below it, the summary card stays here as context, the results region was removed from this page, and the route was renamed to
/reporting-units/$ruId/$blockId. - The blocks list is intentionally empty (built-in
No resultsstate) until backend issue #1250 (block-information, submission-details, and eligibility endpoints) lands — itself blocked by #1228, #1289, and #1212. Once it lands, the RU page's blocks list populates and its rows link back to this page. - Status-tag vocabulary is constrained by ADR-004 but is not implemented yet; when it arrives, the columns render on the RU page's blocks list rows (see ReportingUnitBlocksList).
- No Edit, Trash, uploader, progress, or toolbar controls are rendered. These elements are hidden in Figma frame 161:29613 — do-not-render by decision.
- Decision D5 ("no feature flag") is superseded (2026-10-05): the route now sits behind
reporting-unit-block-details-enabledplus the ADMIN role guard, per user decision D9 (one flag for both block-details surfaces). See Feature Flags.
- The Blocks crumb navigates to the current route — intentional under decision D8: the blocks list lives on the Reporting Unit Details page, so there is no separate blocks-list route to target.
- The results region was removed (decision D8); the blocks list lives on the Reporting Unit Details page and populates once issue #1250 lands.
-
useParams({ strict: false })is required because the component is not the direct route owner in the strongly-typed router;ruIdandblockIdare not compile-time validated.
- Routing — ROUTES table entry for the renamed route.
- Frontend Architecture Overview — route diagram and shared hooks list.
- Block Details Summary — summary card rendered by this page.
- Block Details Skeleton — loading skeleton for this page.
- ReportingUnitBlocksList — blocks list on the RU page; its rows will link to this page once issue #1250 lands.
- useReportingUnitDetailsQuery — shared query hook backing the page.
This wiki documents NR Waste Plus for users and developers. Verify security and deployment guidance against the current application configuration before applying it elsewhere.
- Report an issue or ask a question in the GitHub repository.
- Follow the Contributing Guidelines to propose an update.
- Read the Code of Conduct.
Collection indexes support human browsing and machine retrieval. Keep both current when adding or moving wiki pages.
NR Waste Plus Wiki | GitHub Repository