Settings pages: a Save button on every page, enabled only when something changed

Description

Problem

  • Permissions (Jira and Confluence) and Display preferences (Settings → Preferences and the personal preferences page) have no Save button. Every toggle and every group change is stored at once, with one request per change. A permission scheme takes effect the moment its toggle is turned on, before any group is chosen, while the page itself warns that nobody can perform the operations until groups are defined.

  • Every other settings page has a Save button that is always enabled. It can be clicked with nothing to save, and nothing shows that the page has unsaved changes. Only AI → Data sharing disables Save until something changes.

Change

  • Every settings page saves with a Save button, like General. Permissions and Display preferences no longer store each change at once.

  • Save is disabled while the form matches the stored values. It becomes enabled after a change, and is disabled again after a successful save or when the change is undone by hand. Validation keeps blocking a save as today (for example the AI provider settings).

  • Pages with a Save button per section (Message templates, Slack defaults) follow the same rule per section. Dialogs and forms with their own Save (work item type mapping, Slack connection, AI template editor) are not changed.

  • Leaving a page with unsaved changes asks whether to discard them.

  • One shared mechanism serves every page (the settings form compares itself with the stored values), not a check written per page.

  • Settings pages from tickets that are not on dev yet (Work calendars AP-2466, Decision confirmation AP-730) follow the same rule.

  • Built on AP-2498 (Display preferences storage), so it merges after AP-2498.

Fixes included

  1. AI settings: saving the General tab sent the Data sharing values loaded when the page opened, and the other way round, so saving one tab could revert what was just saved on the other. Both tabs now share the stored settings.

  2. An invalid count on the Approval expiration and Notifications pages shows why it is invalid and the allowed range, and is checked again when the maximum or the unit changes.

Acceptance criteria

  • On every settings page, in Jira and Confluence, Save is disabled when the page opens, enabled after a change, disabled again after the change is undone, and disabled after a successful save. After a reload the page shows the saved values.

  • Permissions: turning on a permission scheme and choosing groups stores nothing until Save; after Save the scheme and its groups apply together.

  • Display preferences: ticking or unticking locations stores nothing until Save.

  • Leaving a page with unsaved changes asks before discarding them; leaving a page with no changes does not ask.

Manual tester notes

  • Jira and Confluence: go through every page under Settings and the personal preferences page. Check Save on open, after a change, after undoing it, after saving, and after a reload.

  • Permissions: turn on a scheme, choose groups and leave the page without saving; confirm the prompt, come back: the scheme is still off. Turn it on, choose groups and save: a user outside those groups can no longer perform the operation.

  • Message templates and Slack defaults: each section's Save works on its own; changing one section does not enable another section's Save.

  • Switch between settings pages with unsaved changes (prompt) and without changes (no prompt).

  • AI: change something on Data sharing, switch to the General tab and open another settings page: the prompt still appears. On Data sharing turn off a toggle and Save, then on General change the response temperature and Save, reload: both changes are kept.

  • Email with Gmail or Outlook authorised: Save is disabled when the page opens and after a successful save.

  • Personal preferences: untick "Use custom preferences": the global locations are shown dimmed; tick it again: your own ticks are back. Save with it unticked: after a reload the global locations apply.

  • Typing into an empty field and deleting the text again disables Save (Email sender, webhook URLs). Removing a group, custom field or re-approval status and adding it back disables Save (Confluence permissions, AI Data sharing, Page versioning).

  • Approval expiration: delete a count and type it again: the field shows what you type (no 13 instead of 3), and Save is disabled once the value is back to the stored one. An empty or out-of-range count shows a red border, disables Save and prompts on leave. The reminder interval on Notifications behaves the same.

  • AI: with a stored model that is not the provider's default, switch the provider away and back: the stored model and API key are back and Save is disabled.