Skip to content

feat: unapplied changes status indicator [DHIS2-22011] - #365

Merged
HendrikThePendric merged 14 commits into
masterfrom
feat/unapplied-changes-DHIS2-22011
Sep 24, 2026
Merged

HendrikThePendric merged 14 commits into
masterfrom
feat/unapplied-changes-DHIS2-22011

Conversation

@HendrikThePendric

@HendrikThePendric HendrikThePendric commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

Implements DHIS2-22011

Description

Editing the layout or the options updates visUiConfig, but the visualization on screen only changes once those edits are applied with one of the update-or-switch buttons. Until now nothing told the user that the two had drifted apart.

This adds an "Unapplied changes" caption next to those buttons in the layout panel's bottom bar, styled to match the "Edited" suffix in the title bar and announced with role="status". It is derived state rather than a flag: useHasUnappliedChanges compares the visualization on screen against the one the current visUiConfig would produce, so it clears itself once the change is applied. It reports a change whenever the selected output type is no longer applicable, and stays hidden when no output type can be produced at all — then every button that would apply the config is disabled and there is nothing for the user to act on.

Three supporting changes come with it:

  • areVisualizationsEquivalent already answered "does the saved visualization differ from the current one", and now serves the current-vs-configured comparison as well. Fields that the API returns richer than visUiConfig can rebuild — option set and legend set names, a repetition's backend-derived context, the custom value's name and aggregation type — compare by id.
  • Wire-only dy/latitude/longitude dimensions are dropped when a loaded visualization is normalized. A legacy Event Report persists its value column that way, and the app holds no layout position for them, so on their own they were enough to make a freshly loaded visualization look edited.
  • An unrelated bug surfaced while reusing the output type validity check: it only asked whether the layout held more than one tracked entity type, so a layout holding none — only context-free dimensions such as Last updated on — left the Tracked entity button enabled, and clicking it threw. It is now disabled with a reason, in its own commit.

Quality checklist

  • Cypress and/or Jest tests added/updated
  • Docs added
  • d2-ci dependency replaced N/A

Known issues

  • A custom value visualization saved without a top-level aggregationType reports unapplied changes with nothing changed: the ui config defaults the custom value's aggregation type to DEFAULT where the options default to SUM, so the two sides differ on that field alone. A test asserts this current behaviour. Left as is pending the custom value rework, rather than adding custom-value-specific logic to the comparison.

🤖 Generated with Claude Code

@dhis2-bot

Copy link
Copy Markdown
Contributor

🚀 Deployed on https://pr-365.event-visualizer.netlify.dhis2.org

@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 09:48 Inactive
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 235e427 to 4693c1e Compare September 2, 2026 10:17
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 10:18 Inactive
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 4693c1e to 87f019f Compare September 2, 2026 12:00
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 12:01 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 12:16 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 12:19 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 14:28 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 14:43 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 15:10 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 2, 2026 15:18 Inactive
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 76ac58b to 3822ec4 Compare September 3, 2026 06:59
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 3, 2026 07:00 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 3, 2026 08:09 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 3, 2026 08:14 Inactive
@HendrikThePendric HendrikThePendric self-assigned this Sep 3, 2026
Comment thread src/components/layout-panel/bottom-bar/output-type-validity.ts
@HendrikThePendric
HendrikThePendric marked this pull request as ready for review September 9, 2026 15:31
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 9, 2026 15:32 Inactive
@HendrikThePendric
HendrikThePendric removed the request for review from cooper-joe September 9, 2026 15:33
@HendrikThePendric
HendrikThePendric marked this pull request as draft September 10, 2026 07:00
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 21, 2026 15:03 Inactive
@HendrikThePendric HendrikThePendric changed the title feat: unapplied changes status indicator and update button removal from modals [DHIS2-22011] feat: unapplied changes status indicator [DHIS2-22011] Sep 21, 2026
HendrikThePendric and others added 2 commits September 22, 2026 11:13
…2-22011]

Deciding whether there are unapplied changes needs to know which output types
the current config can produce, which until now only the action button hook
could work out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…n [DHIS2-22011]

A legacy Event Report persists its value column as a dy/latitude/longitude
dimension. The app expresses that with the custom value fields instead and
holds no layout position for them, so they survived a load without ever being
rebuildable from visUiConfig — enough on its own to make a freshly loaded
visualization look edited.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
HendrikThePendric and others added 2 commits September 22, 2026 11:14
The section described sibling DHIS2 apps' helpers, none of which exist in this
repo, so it pointed readers at symbols they could not find.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 52c0035 to 92a36c5 Compare September 22, 2026 09:45
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 22, 2026 09:46 Inactive
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 92a36c5 to 5f3f681 Compare September 22, 2026 13:07
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 22, 2026 13:08 Inactive
@HendrikThePendric
HendrikThePendric marked this pull request as ready for review September 22, 2026 13:29
Comment thread src/modules/visualization/state.ts Outdated
Comment thread src/modules/visualization/state.ts Outdated
edoardo
edoardo previously approved these changes Sep 23, 2026
cooper-joe and others added 2 commits September 23, 2026 16:30
…HIS2-22011]

Squashed net effect of prototype/stale-state commits a05c758 and 643f263.
The action-button changes in a05c758 were reverted by 643f263, so only the
canvas overlay survives.
…2-22011]

Inline styles become a CSS module, the notice text goes through i18n, and
the stale state is suppressed while the visualization is loading.

The notice stays mounted so it can fade in and out, and toggles aria-hidden
so it leaves the accessibility tree while faded out.

The indicator tests move from the bottom bar spec to a canvas spec.
@HendrikThePendric
HendrikThePendric force-pushed the feat/unapplied-changes-DHIS2-22011 branch from 5f3f681 to 5d728ed Compare September 23, 2026 15:23
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 23, 2026 15:24 Inactive
… [DHIS2-22011]

The overlay wraps the canvas content, reads the store itself and owns both
the dimming and the notice, so Canvas is back to rendering PluginWrapper.
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 23, 2026 15:37 Inactive
Canvas already reads isVisualizationLoading for PluginWrapper, so the
overlay reading it from the store too made the two go through different
paths for the same state.
Drop the comments that restated the code, state the reason each field needs
special handling where the handling is, and let the code carry the parts that
were only explained in prose.
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 24, 2026 08:59 Inactive
…mensions [DHIS2-22011]

Nothing derives the custom value from a wire-only dimension, and the claim
did not hold for latitude/longitude at all. What is left is the reason the
drop flips the legacy flag.
…HIS2-22011]

The old name described the wire format rather than what the app does with
these dimensions, so every call site had to re-explain it.
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 24, 2026 12:26 Inactive
@dhis2-bot
dhis2-bot temporarily deployed to netlify September 24, 2026 12:31 Inactive
@sonarqubecloud

Copy link
Copy Markdown

Comment thread src/components/layout-panel/bottom-bar/output-type-validity.ts
@HendrikThePendric
HendrikThePendric merged commit a213f97 into master Sep 24, 2026
20 checks passed
@HendrikThePendric
HendrikThePendric deleted the feat/unapplied-changes-DHIS2-22011 branch September 24, 2026 15:13

This branch was previously deployed

1 inactive deployment
netlify — 3349ca54 Deployed Sep 24, 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.

4 participants