Skip to content

UIU-3385: Add Settings components for Version History in Users#3034

Merged
slaemmer merged 11 commits into
masterfrom
UIU-3385
May 18, 2026
Merged

UIU-3385: Add Settings components for Version History in Users#3034
slaemmer merged 11 commits into
masterfrom
UIU-3385

Conversation

@slaemmer
Copy link
Copy Markdown
Contributor

@slaemmer slaemmer commented Apr 16, 2026

UIU-3385

Purpose

The Users app handles more sensitive personal data than most other FOLIO apps. Before rolling out Version History in Users, institutions must be able to configure (or fully disable) what is tracked, in order to comply with local and national data protection regulations.

This PR implements the initial settings UI under Settings > Users > General > Version history, giving Systems Librarians control over:

  • whether a version history is created at all
  • how long history is retained
  • whether the source of changes is anonymized
  • which fields (e.g. contact info, custom fields) are excluded from tracking

Approach

A new VersionHistorySettings entry is added at the end of the settingsGeneral list in src/settings/sections.js, gated behind a new ui-users.settings.versionHistory.view permission.

The UI consists of three components:

  • VersionHistoryForm renders the full settings form. Fields that require version history to be
    enabled are wrapped in a Tooltip explaining how to activate them.
  • VersionHistoryWarningModal is shown before saving whenever the new settings would delete previously stored data / not store all data in a way that differs from before.
  • VersionHistorySettings is the top-level container wiring these together with data fetching and custom fields loading.

On the data layer, useAuditSettingsQuery fetches from mod-audit and useVersionHistorySettings issues individual PUT requests per changed setting key. The utility functions in utils.js handle conversion between the API's flat settings array and form values, diffing current vs. submitted values to minimise API calls, warning detection, and form validation.

Two new permissions are declared in package.json: a view permission (read access to the mod-audit group settings) and an edit permission (extends view with per-key PUT permissions for each of the four setting keys: enabled, records.retention.period, anonymize, excluded.fields).

Pre-Merge Checklist

Before merging this PR, please go through the following list and take appropriate actions.

  • I've added appropriate record to the CHANGELOG.md
  • Does this PR meet or exceed the expected quality standards?
    • Code coverage on new code is 80% or greater
    • Duplications on new code is 3% or less
    • There are no major code smells or security issues
  • Does this introduce breaking changes?
    • If any API-related changes - okapi interfaces and permissions are reviewed/changed correspondingly
      • Added two now permissions, additive only.
      • Added optional dependency on audit-config interface. Setting page is not shown when interface is not provided
    • There are no breaking changes in this PR.

Should be merged after the Trillium release is fixed with CHANGELOG at the correct location.

Should be merged at the same time as the version history display PR for UIU-3388 as both together complement each other (user facing vs settings).

slaemmer and others added 2 commits April 15, 2026 16:33
Add a new settings section under Users > General > Version history
that allows configuring version history behavior:

- Radio buttons to choose retention mode (Never/Indefinitely/Duration)
- Duration length and unit fields when set duration is selected
- Checkbox to anonymize the change source
- Multi-select to exclude contact info and custom fields
- Warning modal when changes would result in data loss
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 16, 2026

Jest Unit Test Results

    1 files  ± 0    279 suites  +6   5m 21s ⏱️ +24s
1 395 tests +68  1 392 ✅ +68  3 💤 ±0  0 ❌ ±0 
1 436 runs  +68  1 433 ✅ +68  3 💤 ±0  0 ❌ ±0 

Results for commit ebbcb9f. ± Comparison against base commit b0f559e.

♻️ This comment has been updated with latest results.

slaemmer and others added 5 commits April 16, 2026 09:45
Declare `audit-config` as an optional okapi interface and filter the
Version History settings entry with it, so tenants without mod-audit
don't see a settings entry that cannot work.
- Gate the Save button with `ui-users.settings.versionHistory.edit`.
- Move the duration-mode InfoPopover out of the RadioButton label so its
  click doesn't toggle the radio and its content doesn't bleed into the
  accessible name; lay it out with stripes' Layout flex helper.
- Make the warning modal dismissible (Esc and backdrop now cancel).
- Always invalidate the audit-settings query cache after a save so a
  partial PUT failure can't leave the UI out of sync with the server.
- Track `storedRetentionDays` outside form state instead of carrying it
  through `initialValues`, and thread it explicitly to utils.
- Wait for `useCustomFieldsQuery` before rendering, and label
  orphaned/loading custom-field IDs as "Unknown field (<id>)" instead
  of leaking the raw `customFields.<refId>` path.
- Reuse existing translation keys for departments, tags, and proxy/sponsor.
- Add 13.1.0 IN PROGRESS changelog entry.
Replaces hand-rolled Modal+ModalFooter+Buttons with stripes'
ConfirmationModal. Same Esc-to-cancel behavior, drops the X close button,
gains automatic focus on the confirm button.
@slaemmer slaemmer marked this pull request as ready for review April 28, 2026 08:03
@slaemmer slaemmer requested a review from a team April 28, 2026 08:04
@Dmytro-Melnyshyn Dmytro-Melnyshyn self-requested a review April 28, 2026 11:14
handleSubmit returns a promise that final-form awaits — for the warning
path it resolves only after confirm/cancel + the in-flight PUT. Without
this, `submitting` cleared synchronously and a fast user could re-click
Save mid-save.

Also adds tests for useVersionHistorySettings, getStoredRetentionDays,
and the customFields loading branch; drops the assertion-free
"passes open=false" test and the no-op `waitFor(renderForm)` wrappers;
renames the mock submit buttons since destructiveness depends on initial
state, not submitted values.
@slaemmer slaemmer requested a review from s3fs April 28, 2026 12:11
Comment thread src/settings/VersionHistorySettings/VersionHistoryForm.js Outdated
A standalone Label was incorrect semantics for a section heading.
RadioButtonGroup's label prop renders the text as <legend> inside
<fieldset>, which is the right element for naming a group of form
controls. Small CSS override to restore the prior bold/form-label
visual weight, since stripes styles legends small/regular by default.
@babel/preset-react runs with runtime: 'automatic', so the bare
React import isn't needed for JSX.
@sonarqubecloud
Copy link
Copy Markdown

@sonarqubecloud
Copy link
Copy Markdown

@slaemmer slaemmer merged commit 542677d into master May 18, 2026
16 checks passed
@slaemmer slaemmer deleted the UIU-3385 branch May 18, 2026 12:53
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.

3 participants