Skip to content

fix: apply org unit hierarchy in event and enrollment pivot tables - #1846

Open
HendrikThePendric wants to merge 6 commits into
masterfrom
fix/pt-engine-handle-prefixed-ou-dimensions-DHIS2-22094
Open

HendrikThePendric wants to merge 6 commits into
masterfrom
fix/pt-engine-handle-prefixed-ou-dimensions-DHIS2-22094

Conversation

@HendrikThePendric

@HendrikThePendric HendrikThePendric commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Implements DHIS2-22094

Description

"Display organisation unit hierarchy" has no effect on event and enrollment pivot tables. Two things in this repo stand in the way.

The org unit dimension was looked up by literal key

applyHierarchy was reached through allByDimension['ou'], which never matches a stage-qualified dimension (<stageId>.ou) and matches at most one org unit dimension per layout. It now matches any org unit dimension: by dimensionType where the response provides one, by unqualified dimension id otherwise. The fallback is needed because the dimension descriptor carries no type — measured against the aggregate endpoint, metaData.items['<stageId>.ou'] is {"name": "Organisation unit"} and nothing more.

The aggregate request did not ask for metadata details

applyHierarchy reads each org unit's id from item.uid. That field only exists when the request sets includeMetadataDetails=true, and getAggregate went through fetch, which does not set it. Without it every id is undefined, the row lookup breaks, and the table renders with correct headers over an entirely empty value grid.

getAggregate now goes through get, which issues the data and metaData requests in parallel — skipMeta=true on one, skipData=true plus includeMetadataDetails=true on the other — and merges the responses. This is what analytics.aggregate.get already does and what data-visualizer-app uses; DV is why the hierarchy works there and not here.

Verified against a live instance that merging the two responses reproduces the combined one exactly — identical headers, rows, width, height and dimension order — plus ouNameHierarchy and uid on the items.

Splitting also routes the request through analyticsDataQuery, which sorts dimensions and items so that layouts differing only in order share a cache entry (DHIS2-17861). That sorting lives inside the query definition and is not reachable from the request builder.

Only getAggregate changes — getQuery still goes through fetch, so line listing keeps its single request per page — and its one consumer across the dhis2 org, event-visualizer-app's use-pivot-table-analytics-data.ts, needs no change because the merged response keeps the same shape.

Dependency chain

# Where What
1 dhis2-core DHIS2-22119 — no hierarchy metadata returned for a stage-qualified ou (#25259)
2 this PR engine finds the org unit dimension, and the request asks for the metadata it needs
3 dhis2/event-visualizer-app#384 sends showHierarchy=true on pivot requests

Enrollment pivots need 2 + 3 — they already send a bare ou.
Event pivots need all three; without 1 the backend returns no hierarchy to apply.

Verified end to end in event-visualizer-app with this branch pinned — see the "How to verify" section of #384.

🤖 Generated with Claude Code | Edited by @HendrikThePendric

@HendrikThePendric
HendrikThePendric marked this pull request as draft September 16, 2026 14:18
@HendrikThePendric HendrikThePendric changed the title fix: allow ou dimension to be prefixed fix: apply org unit hierarchy in event and enrollment pivot tables Sep 16, 2026
@HendrikThePendric
HendrikThePendric force-pushed the fix/pt-engine-handle-prefixed-ou-dimensions-DHIS2-22094 branch from 4eb00c0 to ebb0975 Compare September 17, 2026 11:43
HendrikThePendric and others added 2 commits September 17, 2026 15:01
`getAggregate` went through `fetch`, which issues one request for data and
metaData together. `get` issues two in parallel — one with `skipMeta=true`,
one with `skipData=true` and `includeMetadataDetails=true` — and merges them.
It is what `analytics.aggregate.get` already does and what data-visualizer-app
uses.

The metaData request is what makes `PivotTableEngine.applyHierarchy` work:
without `includeMetadataDetails` a `metaData.items` entry carries only a name,
so the org unit ids it reads from `item.uid` are all undefined.

Splitting also routes the request through `analyticsDataQuery`, which sorts
dimensions and items so that layouts differing only in order share a cache
entry.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sorting rewrites `itemIds`, which the row lookup resolves data rows through.
The characteristic failure is a table with correct headers and an entirely
empty value grid, which the hierarchy assertions alone do not catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@HendrikThePendric
HendrikThePendric force-pushed the fix/pt-engine-handle-prefixed-ou-dimensions-DHIS2-22094 branch from ebb0975 to 05ade2f Compare September 17, 2026 13:01
A backend that returns no hierarchy for the requested dimension still sends
the key as an empty object, which passes the truthiness guard and lets
applyHierarchy run. Rows must keep their order and their values.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants