Skip to content

feat: mark unsaved changes on map title and warn before discarding them - #3742

Draft
BRaimbault wants to merge 2 commits into
masterfrom
feat/mark-edited
Draft

feat: mark unsaved changes on map title and warn before discarding them#3742
BRaimbault wants to merge 2 commits into
masterfrom
feat/mark-edited

Conversation

@BRaimbault

Copy link
Copy Markdown
Collaborator

Implements DHIS2-XXXXX

Description

Appends " - Edited" to the map title when the current map differs from what was last saved, mirroring data-visualizer-app's UX, and guards against losing that work: an in-app "Discard unsaved changes?" dialog before navigating to a different map, and a native browser prompt before closing the tab.

A savedMap reducer slice tracks the last-saved snapshot, kept in sync via the MAP_SET/MAP_NEW/MAP_PROPS_SET actions the app already dispatches. isMapDirty() compares the live map against that snapshot using an allowlist of saved-payload fields (reusing validLayerProperties/validMapProperties from favorites.js) rather than a blacklist of "ephemeral" fields — a blacklist missed that layer loaders replace a layer's config wholesale with loaded-only fields right after every map load, which made every map look "Edited" immediately on open during development. The title check is debounced 300ms so rapid changes (e.g. dragging an opacity slider) don't run the comparison on every tick; the navigation guard instead checks on demand only when it matters, so it's never stale.


Quality checklist

Add N/A to items that are not applicable.

  • Dashboard tested — N/A, change is scoped to the standalone app (App.jsx/useLoadMap.js), not the dashboard plugin embed
  • Cypress and/or Jest tests added/updated
  • Docs added — N/A
  • d2-ci dependencies replaced (analytics or maps-gl link https://github.com/dhis2/[lib]/pull/XXX) — N/A
  • Tester approved (name)

ToDos

  • N/A

Known issues

  • If the original blocked navigation was itself triggered by the browser Back button (not a link/menu click), clicking "Cancel" in the dialog calls history.back() again, which goes one step further back than intended. Matches data-visualizer-app's own equivalent implementation; not fixed here as it needs a larger navigation-direction-aware rework.

Screenshots

supporting images

BRaimbault and others added 2 commits July 29, 2026 14:16
…them

Appends " - Edited" to the map title when the current map differs from
what was last saved, mirroring the data-visualizer-app UX, and warns
before navigating away or closing the tab with unsaved changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
If the browser Back/Forward buttons revert a blocked navigation instead
of the dialog's own Cancel/Leave buttons, the confirm-leave modal was
never cleared -- it stayed on screen pointing at a stale location, and
acting on it (Cancel or Leave) would navigate further than intended or
desync the URL from the rendered map. Clear the pending confirm whenever
the listener proceeds unblocked.

Also stabilizes two useLoadMap test mocks (useDataEngine, useCachedData)
that returned a fresh object per render, which destabilized loadMap's
identity and caused its mount-effect to spuriously re-fire and mask this
bug in the regression test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@dhis2-bot

Copy link
Copy Markdown
Contributor

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

@dhis2-bot
dhis2-bot temporarily deployed to netlify July 29, 2026 13:09 Inactive
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