Skip to content

feat: show layer alerts in the legend [DHIS2-16362] - #3787

Draft
BRaimbault wants to merge 5 commits into
feat/DHIS2-16362-phase-1from
feat/DHIS2-16362-error-handling
Draft

BRaimbault wants to merge 5 commits into
feat/DHIS2-16362-phase-1from
feat/DHIS2-16362-error-handling

Conversation

@BRaimbault

@BRaimbault BRaimbault commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Tests ~55% | Style ~5% | Code ~40%

Implements DHIS2-16362
Also prepares/implements:

Stacked on #3783 (Phase 1). Review that one first: this PR only adds the error handling.

Description

Layer errors, warnings and notes are shown in the legend instead of snackbars, in the same place in the app layer card and the dashboard plugin: title, alerts, then the legend.

Alert model

  • An alert is { id, severity, title, description?, details? }. Severity is error, warning or info.
  • All wording is in one catalog, src/constants/layerAlerts.js. Loaders pick an alert id and never write user-facing text.
  • Helpers are in src/util/layerAlerts.js. createLayerAlert(id, { params, details }) builds an alert from the catalog. createLayerAlertFromError(error) turns any thrown error into one, using a single map of DHIS2 error codes shared by all loaders (ERROR_CODE_ALERTS in the catalog).
  • Requests add their name to a failed request's error with .catch(throwWithRequest(resource)), so the details say which request failed.
  • "Details" shows the HTTP status, error code, server message and request. "Copy" adds the layer, app and server versions and the time, so users can send it to an admin.
  • A program, tracked entity type or org unit the user lost access to returns the same "does not exist" error as a deleted one. The wording says "not available" and gives both possible causes. This was checked with a restricted user on 2.43.

Tracked entity layer

  • Migrated to the new model, as the first layer type. Other layer types follow, one PR each.
  • No more snackbars for this layer.
  • Truncation and no-data warnings now show in the app layer card too, not only in dashboards.

Loading, shared by the app and the plugin

  • src/hooks/useLoadLayer.js returns loadLayer and canLoadLayer, without redux. loadLayer picks the loader for the layer type and gives it what it needs. It never throws: any layer type that fails finishes loading with an error alert and no data, instead of spinning forever.
  • App: useLoadLayerWithRedux (renamed from useLayersLoader) loads the store's layers that aren't loaded yet with useLoadLayer, and stores the results.
  • Plugin: Map.jsx loads its layers with useLoadLayer, and LayerLoader.jsx is removed. The fix: dashboard map fixes #3779 fixes are kept: each config loads once, and layers waiting for period types load later. Loads that finish after the views changed are ignored.

Reload

  • Alerts are cleared when a layer starts loading again (edit, drill, period sync, data table), so a reloading layer doesn't show the previous result's problems. loadLayer also drops them from the config, so loaders that copy the config can't bring them back.

Developer preview

  • Add alertPreview to the URL hash (#/?alertPreview or #/<mapId>?alertPreview) to show every alert on every layer. App only. It lives in src/util/layerAlertsPreview.js, so it can be removed with that file and one call.

Quality checklist

Add N/A to items that are not applicable.

  • Dashboard tested
  • Cypress and/or Jest tests added/updated
  • Docs added
  • d2-ci dependencies replaced: N/A
  • Tester approved (name)

ToDos

  • Migrate the other layer types to the alerts model, one PR each. Then remove everything tagged LEGACY-ALERTS (grep -rn LEGACY-ALERTS src), plus useLoaderAlerts.js, LegendAlert.jsx, the old alert codes and loadError.

Known issues

  • Layer types that are not migrated yet keep their old alerts: snackbars in the app, LegendAlert in the plugin.

Screenshots

supporting images

@dhis2-bot

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://pr-3787.maps.netlify.dhis2.org

@dhis2-bot
dhis2-bot temporarily deployed to netlify October 6, 2026 09:27 Inactive

@BRaimbault BRaimbault left a comment •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code comment need review, they should be minimal and cover only essential aspects the tests or the code itself do not clearly convey. Make sure they are timeless (not about development history). Here there is an exception, clearly mark areas that should be removed once all loaders/layers use the new model.

Comment thread src/components/legend/LayerAlerts.jsx
Comment thread src/components/legend/LayerAlerts.jsx
Comment thread src/util/layerAlerts.js Outdated
Comment thread src/util/layerAlerts.js Outdated
Comment thread src/util/layerAlerts.js Outdated
Comment thread src/loaders/trackedEntityLoader.js Outdated
Comment thread src/loaders/trackedEntityLoader.js Outdated
Comment thread src/util/layerAlerts.js Outdated
Comment thread src/hooks/useLoadLayerWithRedux.js
@dhis2-bot
dhis2-bot temporarily deployed to netlify October 6, 2026 10:54 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify October 6, 2026 10:56 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify October 6, 2026 11:18 Inactive
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 New issue
1 New Code Smells (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@dhis2-bot
dhis2-bot temporarily deployed to netlify October 6, 2026 11:47 Inactive

This branch was previously deployed

1 inactive deployment
netlify — 3f483b40 Deployed Oct 6, 2026 by dhis2-bot
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