Enable concurrent editing: Replace the postPreview action with atomic equivalents
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3492065. --> Reported by: [larowlan](https://www.drupal.org/user/395439) Related to !709 !1511 !1510 !1440 >>> <h3 id="overview">Overview</h3> <p>In <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3467954" title="Status: Closed (fixed)">#3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc.</a></span> we introduce a <code>PreviewEnvelope</code> controller result.<br> Returning this allows combining a preview render array with a JSON data object and still invoking the preview renderer to combine the render array and the rest of the page elements into a HTML property in a JSON response.</p> <p>It also adds a slice to hold the current preview HTML and introduces a <code>patchComponent</code> action that fires when a component's props are updated. This calls a backend controller that update <strong>only the component being edited</strong> in the auto-save store. This means component edits work concurrently.</p> <p>However, we still call postPreview for many other changes to the layout slice and these <strong>overwrite any other changes being made by a concurrent editor</strong></p> <h3 id="proposed-resolution">Proposed resolution</h3> <p>After <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3467954" title="Status: Closed (fixed)">#3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc.</a></span> and <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3492061" title="Status: Closed (fixed)">#3492061: Include the preview HTML in the layout controller payload</a></span> are in, we no longer need to call postPreview to get the initial preview HTML. So from this point we can move to atomic operations against the auto-save rather than a 'write the full layout and model every time' approach.</p> <p>This allows us to:</p> <p>Remove the postPreview api from the front-end<br> Introduce a patchModelAndLayout api method<br> Add a listener middleware to the store that listens for the following actions:</p> <ul> <li>deleteNode</li> <li>duplicateNode</li> <li>moveNode</li> <li>shiftNode</li> <li>sortNode</li> <li>insertNodes</li> </ul> <p>For each of these:</p> <ul> <li>dispatch the patchModelAndLayout api with the action's payload</li> <li>Rewrite the preview controller in Drupal to respond to this payload and mirror that operation in the auto-save entry for the given entity.</li> <li>Add a onQueryStarted method for patchModelAndLayout that unwraps the preview html and calls dispatch to set the new HTML</li> </ul> <p>e.g. if a user duplicates a node in the UI the workflow should be</p> <ol> <li>duplicateNode reducer called</li> <li>listener middleware reacts to duplicateNode action and fires patchModelAndLayout</li> <li>Drupal controller receives PATCH request for duplicateNode and applies the same logic to its representation of the model/layout as the front end, writing <strong>just those changes</strong> to the autosave store</li> <li>Drupal controller response with HTML</li> <li>onQueryStarted method of patchModelAndLayout action stores the new HTML</li> </ol> <h3 id="ui-changes">User interface changes</h3> > Related issue: [Issue #3492059](https://www.drupal.org/node/3492059)
issue