Skip to content

ReportingUnitBlockDetails

Paulo Gomes da Cruz Junior edited this page Oct 23, 2026 · 4 revisions

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

ReportingUnitBlockDetails

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).

Route

/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().

Access gates

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 References

  • 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

Public Interface

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.

Behavior

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

Success branch

  • PageTitle with title set to Reporting Unit No. {ruId}, subtitle set to View reporting unit details, and breadCrumbs set 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 Column holds a ref; once data resolves, a useEffect sets tabindex="-1" on the h1 and calls .focus(). PageTitle itself 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-in No results state until issue #1250 lands.

Scope Decisions

  • 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 results state) 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-enabled plus the ADMIN role guard, per user decision D9 (one flag for both block-details surfaces). See Feature Flags.

Known Constraints

  • 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; ruId and blockId are not compile-time validated.

Change Impact

See Also

Waste Plus Wiki

Home

Architecture

Codes

Decisions

Knowledge Base

Development

Changes

Clone this wiki locally