Open
Milestone Apr 1, 2026–Jul 10, 2026

Review of changes and Conflict resolution

Migrated issue

Reported by: f.mazeikis

Was manually converted to a milestone on June 19, 2026, from [META] Review of changes and Conflict resolution (#3587587 - closed).

Overview

This is a meta to track work to add ability to add the following:

  • Add conflict detection when underlying entity that auto-save entry has been based on is updated outside of Canvas UI
  • Add ability to detect and resolve such conflicts using Canvas UI
  • Build UI that allows to use side-by-side comparison when resolving such conflict
  • Ability to conveniently Review changes to multiple entities re-using much of the same new UI

Refer to child issues for actionable steps.

  • 🟢 Description and requirements:
    • 🕴️Product Speak
    • 🕴️User journeys
    • 📋 Additional criteria
  • 🟢 Proposed resolution:
    • 👨‍🔬 Canvas Engineering Speak
    • 🤓 Definitions
    • 👷‍♀️👷‍♂️ UI Changes
  • 🟡 ADR
  • 🟢 Designs
    • Conflict resolution UI
    • Review of changes UI
  • 🚧🏗️ Related issues
  • 🚫 Out of Scope

Current problems

  1. Users reviewing changes in their autosave before publishing are unaware if the published content has been updated externally, risking silent overwrites of concurrent work.
  2. When concurrent changes occur between the updated entity a user has in their autosave and the published version of the same entity a user started with, users lack visibility into the conflicting versions.
  3. Relying on the “preview” functionality for individual entities in Canvas UI is insufficient when reviewing changes in autosave, as there is no comparison to currently published versions of entities.
  4. Users don't have a quick and convenient way to visually review changes made to multiple entities.

Proposed resolution

Product Speak:

Expected outcome from a Product POV, by @lauriii:

We should create clear, visual interface to identify and resolve version conflicts before publishing. By flagging conflicts in the review panel and providing a side-by-side comparison modal per entity, users can confidently select the correct version to proceed with, preventing accidental overwrites. Same functionality can also be used to preview any non-conflicting changes vs the published version of the entity.

User journeys:

Original user journeys written by @lauriii, expanded and clarified with the help of @mark-dodgson:

Conflict Identification

Given a user has an un-published autosave changes on an entity in Canvas

And that the same entity has been updated and saved before user published their changes

When the user clicks "Review Changes" to publish

Then the specific entity is visibly flagged with a "Conflict" indicator in the review panel and cannot be selected for publishing

And a dedicated "Conflict resolution CTA" section appears in "Review Changes" panel above the list of entities with changes.

Conflict Resolution Preview Access

Given the user is viewing the "Review Changes" panel and there are auto-save entries with detected conflicts

When the user clicks on the "Resolve X conflicts" button in the "Conflict resolution CTA" section above the list of un-published entities in the "Review Changes" panel

Then the "Conflict resolution UI" opens and it contains the list of all detected conflicts in the order they appear in "Review Changes"

And this UI has controls that allow the user to navigate between the conflicts, view them in side-by-side comparison and resolve each one individually.

Conflict Resolution Access via contextual menu

Given the user is viewing the "Review Changes" panel when conflicts are detected

When the user chooses an entity with a conflict and clicks on "Resolve Conflict" option in the contextual menu this entity entity

Then the "Conflict resolution UI" opens starting the list with the entity chosen by the user

And the rest of the entities with conflicts in the "Conflict resolution UI" list are ordered as they appear in "Review changes" panel.

Conflict Resolution Selection

Given the user is viewing the side-by-side comparison of a an entity with detected conflict in the "Conflict resolution UI"

When the user is prompted to resolve the conflict

Then the user must be presented with two distinct, mutually exclusive options: "Keep Published Version" or "Keep Autosaved Version".

Executing the resolution

Given the user has selected one of the versions in the conflict resolution modal

When the user confirms their selection

Then the conflict is resolved immediately for this and other users in Canvas Ui.

Expected conflict resolution ui behavior

Given the user is using conflict resolution UI

When resolves a conflict

Then Canvas UI is updated immediately to reflect the users action

And all counts of conflicts in Canvas UI are updated

And the entity is no longer marked as having a conflict.

Resolving the conflict by choosing the Autosaved version

Given the user has selected the Autosaved of the version in the conflict resolution modal

When the user confirms their selection by clicking "Resolve Conflict" button in the "Conflict resolution UI"

Then the changes in the Published version are ignored

And the conflict indicator is removed from the "Review Changes" panel for this entity

And the entity can be selected for publishing in the "Review Changes" panel

And the user can publish the changes made to this entity.

Resolving the conflict by choosing the Published version

Given the user has selected one the Published version in the conflict resolution modal

When the user confirms their selection by clicking "Resolve Conflict" button in the "Conflict resolution UI"

Then user made changes to this entity in Canvas are discarded

And the entity is removed from the "Review changes" list

And there are no changes to publish for this entity in Canvas UI.

Side-by-Side Preview Access

Given the user is viewing the "Review Changes" panel

When the user clicks on the "Review selected changes" link at the bottom of "Review Changes" panel

Then a new Canvas UI element opens displaying a side-by-side comparison of the published version and the autosaved version of the first entity selected for publishing

And all the other entities with changes that are selected for publishing are also available for preview in this new UI.

And the Page entities appear in the same order as they appear in the "Review Changes" panel.

Side-by-Side Preview UI navigation

Given the user opens the new Canvas side-by-side review UI panel

When the user wants to review another entity using this UI

Then they can use the pagination in the left bottom corner to see how many entities are available for preview and which entity number they are on

And they can use "previous" and "next" navigation controls of the new "side-by-side review UI" to move between all Page entities with changes selected for publishing.

Side-by-Side Preview Access via contextual menu

Given the user is viewing the "Review Changes" panel

When the user clicks on contextual menu option "Review Changes" of a specific entity selected for publishing

Then a new Canvas UI element opens displaying a side-by-side comparison of the entity user clicked selected via the contextual menu

And this entity is set to be the first item in the pagination of the new side-by-side UI panel

And this new Canvas UI element has controls that allow user to navigate between the entities selected for publishing and view them in side-by-side comparison

And all the rest of Page entities selected for publishing appear in the in the pagination of the new side-by-side UI panel using same order as they appear in the "Review Changes" panel.

Additional criteria:

  1. A conflict in Canvas can occur by any means of updating the underlying entity that Canvas user has updated in their autosave. This includes (but is not limited to) config and content import, CLI commands, editing and saving of the entity by another user via Drupal UI or code.
  2. If user resolves a conflict in favour of published entity version, then the entry for that entity is removed from the autosave, resulting in nothing to save or publish until user edits that entity again.
  3. If a user resolves a conflict in the Canvas UI in favour of entity version in autosave:
    • If the user continues making changes to an entity with a "conflict resolved" flag in autosave via the Canvas UI, their actions will not trigger a new "conflict detection" flag
    • After "conflict resolved" flag is added to an entity in autosave, only further changes to published version of the entity can trigger new "conflict detected" flag
    • If a user resolves conflict in the Canvas UI in favour of entity version in autosave, we should track which specific entity and specific conflict has been resolved, in case additional conflicts occur after resolving the initial conflict
  4. If Canvas will be integrated with Workspaces, the expectation is for conflict resolution to continue work as is in the FE part of Canvas and BE part of Canvas should use entity revision id changes for “Conflict detection”
  5. When user opens a modal with side by side visual comparison there should be UI element that allows the comparison modal to be expanded to fill the viewport
  6. Visual side-by-side comparison of changes should work on all screen sizes supported by Canvas
  7. Visual side-by-side comparison should be reasonably fast when loading side by side comparisons
  8. Visual side-by-side comparison must be able successfully render visual comparisons of complex pages with deep component trees.
  9. Entities that can't be meaningfully compared using visual representations should be compared using their text-based representations (for example - global CSS entity)

Canvas Engineering Speak

Current conflict detection

We have added rudimentary conflict detection as part of and .

In #3490565 we put in logic to throw an exception if client didn't send the latest auto-save hash for the entity and regions. This prevents 2 users for editing at the same time and wiping out each others changes.

In we expanded this functionality further and added support in Canvas UI enforcing "Canvas does not support concurrent editing" by forcing Canvas users to refresh their page when a conflict in autosave is detected.

This does not cover changes to entity that occur due to entity update and save outside of Canvas UI. For example, if user opens Canvas UI and starts editing "Full content template" for the "Article" content type.

What entity changes are needed to detect a conflict:

  • Canvas Page (content entity): any change (including a change in the revision ID) is considered to be a conflict. The only exception is the changed field - updating it without updating any other field values (including revision id) will not be detected as a conflict.
  • Content Template, Code Component, Region, Pattern (config entities): the hash of all entity properties will be used to detect changes. The only fields exempt from the hash are: status and label properties.

The broad plan:

  • Start small - Canvas Page support as MvP, extend to all the other entity types later
  • Text-based side-by-side comparison will use JS library with pretty diff
  • Visual side-by-side will use modified Canvas preview endpoint
  • Visual comparison will only be available for entity types where it makes sense - Pages, Templates, etc. Entities with no meaningful visual preview (global CSS 🤨) will only use text-based comparison
  • Don't break existing conflict detection, only expand, improve and bugfix where required
  • Reuse currently existing infrastructure that is proven to work (like preview endpoint)
  • Reuse conflict resolution UI to allow reviews of all entities with changes selected for publishing

The detailed plan:

  1. Make minor auto-save/pending refactor to encapsulate the auto-save entries in a top level data property.
  2. Add logic to detect and store conflicts that can be resolved in the new UI:
    • Changes in AutoSaveManager and associated tests
    • Start storing original_hash on auto-save entry save, that way we can tell if underlying entity has been updated. Do not send original_hash to client side
    • Start detecting, storing and updating conflict property on auto-save entry save. Only send it client side if the conflict is active and only in the relevant `errors` item
  3. Add HTTP 409 response definition for auto-save/pending endpoint to openapi.yml:
    • Use errors at the top level to mark which entities contain conflicts
    • In the errors add items for each entity with the detected conflict. Mark items we can resolve in UI with new error code and use meta property of the error item to store the conflict object
    • The conflict object should have the conflictId, status and timestamp properties
    • HTTP 409 response should return both data and errors properties, so client side could know which entities have active conflicts
  4. Make auto-save/pending controller return HTTP 409 if any active conflicts are found in the list of entries to be returned
  5. Make sure entity cache tags from auto-save entries are used in caching of the auto-save/pending response
  6. Return both data and errors properties on HTTP 409, so client side could know which entities have conflicts
  7. Extend these changes to publishing and ?? endpoints:
    • Validation during autosave publishing should compare revision ids and a hashes and prevent publishing if a conflict is detected and not previously marked as resolved
    • If any unresolved conflicts are detected during publishing, the autosave should be updated with flags identifying entities with unresolved conflicts
  8. Add an ability to resolve a conflict via HTTP PATCH call to the auto-save API endpoint (or a new dedicated endpoint) with the conflict id and status
  9. Modify preview endpoint to accept argument that will allow endpoint to return current auto-save version of the preview (default option) or the published version of this entity
  10. Add new Canvas endpoint for text-based previews:
    • Config export and default content export representations of entities should be used
    • Both published and auto-save entity per request or two separate requests
    • Argument listing properties or a dedicated route with hardcoded entity type to property map can be used to filter text-based representation to a subset of fields/properties (for example - "only input values" or "only JS code")
    • Text-based comparison will be available to most (if not all) entity types and will be based on default content export representations for content entities and config export versions of config entities
    • For some entity types only a subset of their properties could be displayed in text-based side-by-side (Code tab for code components and global css) + full text-based representation in a separate tab
  11. Emit notifications in the BE on conflict detection (figure out how to only do it once per detected conflict too) with "action" that allows client side to open conflict resolution UI.
  12. Have fun along the way

User interface changes

  • "Review changes" dropdown in the Canvas UI should display conflicts when they are detected
  • New "Visual comparison UI" that allows user to view a side by side comparison of the of updated entity in autosave versus the published version of same entity
  • New "Conflict resolution UI" that shows side by side comparison of updated entity in autosave versus the conflicting published entity. This UI should have controls that allow user to select one version, which results in discarding the other
  • "Review changes" dropdown in the Canvas UI should have a mechanism to open a modal (or similar) that would contain "Conflict resolution UI" for entities with detected conflicts
  • "Review changes" dropdown in the Canvas UI should have a mechanism to open a modal (or similar) that would contain "Visual comparison UI" for updated entities

🛑 ADR

Work in progress

🟢 Designs

All designs made by @mark-dodgson and exported as PNGs from Figma.

Conflict resolution

  1. Toast notification with a detected conflict:

    Figma design showing toast notification with detected conflict in the Canvas UI
  2. Conflict detected CTA and marked entities in the "Review changes" panel:

    Design for "Review changes" panel when conflicts are detected
  3. Conflict resolution UI with side-by-side visual comparison:

    Design for visual side-by-side comparison in conflict resolution ui
  4. Conflict resolution UI when no active conflicts detected:

    Design for the status page if the user resolves all conflicts or opens the conflict resolution ui via a path when there are no conflicts to resolve

Review of changes

  1. New link at the bottom of "Review changes" panel:

    Design for the updated Review changes dropdown in Canvas UI
  2. New "Review changes" UI using visual entity representation for side-by-side comparison of the published entity version with the version user has in Canvas auto-save:

    Design for the visual side-by-side comparison in review changes ui
  3. New "Review changes" UI using text-based entity representation for side-by-side comparison:

    Design for the text-based side-by-side comparison in review changes ui

🚧🏗️ Related issues

  1. [#3520592][PP-1] Do not allow a user Publish request while there are pending changes to the current layout - currently describes a bug that still needs be fixed. This (#3587587 (closed)) issue helps resolving conflicts and adds visual comparison, but fixing #3520592 would fix a bug causing incorrect conflict detection.
  2. [#3532056]For less conflict errors only validate region auto-save on layout PATCH - should still be fixed. It will reduce the amount of conflicts that can occur, but won't solve the problem entirely and this issue will only make it easier to handle the conflicts.
  3. [#3492065]Enable concurrent editing: Replace the postPreview action with atomic equivalents - should definitely still be implemented. It would add groundwork for implementing concurrent editing for multiple Canvas users. This (#3587587 (closed)) issue intentionally keeps concurrent changes to the same autosave entry out of scope. Me and @bnjmnm think both this (#3587587 (closed)) and #3492065 issues should work fairly well together as they solve related, but different problems. Some refactor or updates might be required, depending on which issue gets finished and merged first.

‼️ This issue does not make any of the related issues irrelevant or supersedes them ‼️

🚫 Out of scope

  1. Concurrent editing - "Conflict free concurrent editing" described in [#3492059] or any other changes related to concurrent editing of entities in Canvas UI by multiple users is out of scope for this issue.
  2. Pre-existring "rudimentary conflict detection" - will continue to work as is:

    Screenshot of autosave conflict detection
  3. Fine-grained conflict detection - current implementation of conflict detection does not force the user to refresh the page if the following fields or properties are modified:
    • changed field on for Canvas Page entities (or any other entities implementing EntityChangedInterface)
    • status and label properties of Canvas config entities

    This will continue to work as is, but will not be expanded to include any additional fields.

  4. Updating the version of the entity in the autosave with changes to it's data fields when possible - Currently If config entity is saved with label and/or status property updates, these values will also be updated in it's respective autosave entry, if one exists. This will continue working as is. Expanding this functionality to other fields or properties will require careful consideration and is out of scope for this ticket.

Related issue: Issue #3520592

Related issue: Issue #3532056

Related issue: Issue #3492059

Related issue: Issue #3492065

Related issue: Issue #3553775

Related issue: Issue #3586600

  • Work items 16
  • Merge requests 18
  • Participants 4
  • Labels 38
Loading
Loading
Loading
Loading
68% complete
68%
Start date
Apr 1, 2026
Apr 1
-
Jul 10 2026
Due date
Jul 10, 2026 (1 day remaining)
16
Work items 16 New issue
Open: 5 Closed: 11
None
Total weight
None
18
Merge requests 18
Open: 3 Closed: 0 Merged: 15
0
Releases
None
Reference: project/canvas%"Review of changes and Conflict resolution"