Skip to content

Structured diff for JSON/block changes in the change view - #1060

Merged
KevinJump merged 1 commit into
v17/mainfrom
v17/feature/change-view-structured-diff
Sep 2, 2026
Merged

Structured diff for JSON/block changes in the change view#1060
KevinJump merged 1 commit into
v17/mainfrom
v17/feature/change-view-structured-diff

Conversation

@KevinJump

@KevinJump KevinJump commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace the word-diffed, pretty-printed JSON in the change-detail view with a structured diff: each USyncChange is classified (masked, single-sided, JSON, XML/text lines, word, scalar) and rendered with the strategy that suits it, instead of running every value through diffWords.
  • JSON/block values get a recursive leaf-change walk that matches array elements by identity (key/udi/alias+culture, with a fallback to index matching) so inserting one block in a block list reports one change, not a rewrite of the whole array.
  • Long text/XML gets a hand-rolled line diff (Umbraco only re-exports diffWords, so no new dependency) with collapsed unchanged runs.
  • The uui-table is replaced with a list of expandable rows so the diff gets the full width of the sidebar modal. A row starts open when it's the only change and collapsed once there's more than one; a failed (success: false) detail always forces itself open. Each JSON row has a "show raw values" toggle for the full old/new text.
  • Fixes two accidental-precedence bugs (length ?? 0 > 0 parses as length ?? (0 > 0)) and a case where Error/Warning notice details were being word-diffed against '' instead of shown as a message.

All diff logic lives in dependency-free modules under src/utils/diff/ (no imports from Lit or @umbraco-cms/*), so it can be exercised outside the backoffice; the identity-matching heuristic, JSON-string expansion, and line-diff bail-out behaviour were checked against fixtures in a throwaway harness before wiring up the component.

Test plan

  • npm run typescript:build — clean
  • npm run build — succeeds
  • npx prettier --check on all changed files
  • In the backoffice: block list with one block inserted → one change reported, not a full rewrite
  • Block reorder only → reorder notice, no/few leaf changes
  • Culture-variant property → culture tag shown, not baked into the name
  • Masked value (member/user) → never diffed, shown as hidden
  • A failed import with error/warning details → notice shown, row open by default
  • Dark mode

🤖 Generated with Claude Code

…view

Word-diffing pretty-printed JSON gave users a wall of text for a single
block insertion or property edit inside a block list/grid. Classify each
change detail (masked, single-sided, JSON, XML/text lines, word, scalar)
and render JSON changes as a flat list of leaf changes, matching block
array entries by identity (key/udi/alias+culture) rather than index so a
single insertion doesn't make every element look changed. Long text/XML
gets a hand-rolled line diff with collapsed unchanged runs, since Umbraco
only re-exports diffWords. Each change is now an expandable row instead
of a table cell, collapsed by default once there is more than one, with
a raw-values toggle for the full old/new text.

Also fixes two accidental-precedence bugs in the change count check, and
a case where Error/Warning notice details were word-diffed against ''.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@KevinJump
KevinJump merged commit 7da4b0d into v17/main Sep 2, 2026
5 checks passed
@KevinJump
KevinJump deleted the v17/feature/change-view-structured-diff branch September 2, 2026 13:24
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.

1 participant