XB AI: User selection should be taken into account while building page
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3540211. -->
Reported by: [narendrar](https://www.drupal.org/user/1730192)
Related to !40 !1467
>>>
<h3 id="overview">Overview</h3>
<p>While creating a page using AI in XB, Component selection should be taken into account even if the user doesn't explicitly ask for that.<br>
<strong>Scenario 1:</strong><br>
User has selected “Card Container” component on the preview. There’s an empty content slot. User asks “Can you add some cards to show case the product highlights?”. I’d expect these cards to be added to the slot.</p>
<p><strong>Scenario 2:</strong><br>
User has selected hero component on the preview. Hero component has an empty slot for buttons. User asks “Can you add some cards to show case the product highlights?”. I’d expect these cards to be added in a new container below the hero.</p>
<p>Currently the page builder agent generates components to be placed, in the following format</p>
<pre> reference_nodepath: [array, of, integers] # From Step 3<br> placement: below # 'above' or 'below'<br> components:<br> - sdc.component.id:<br> props:<br> prop_name: "value"<br> slots:<br> slot_name:<br> - sdc.nested.component:<br> props:<br> nested_prop: "value"<br> message: "Concise 1-2 sentence summary of changes made"</pre><p>Right now, this only supports placing one or more components into a single specified position. It doesn’t handle prompts that require placing components in different positions at the same time.</p>
<p>Some examples:</p>
<p>Page already contains components, and User asks <em>Add a heading with the text ‘What is Drupal’ to the top of the page, and a paragraph explaining the features of Drupal to the bottom of the page.</em></p>
<p>The page contains a two-column component. User selects it and asks: <em>Add two cards to each slot of this component</em></p>
<p>Multiple regions available <em>Add a button with text ‘Contact us’ to all the regions</em></p>
<h3 id="proposed-resolution">Proposed resolution</h3>
<p>Changed the yml structure returned by the agent to the following format</p>
<pre> operations:<br> - target: [FIRST_LOCATION] // Can be region name or slot id ('parentuuid/slot_name' format)<br> reference_uuid: UUID of an existing component. New components would be placed above or below this component, if provided.<br> placement: [inside or below or above]. inside is used only for adding components to an empty region or slot.<br> components:<br> - sdc.component.id:<br> props:<br> prop_name: "value"<br> - sdc.another_component.id:<br> props:<br> prop_name: "value"<br> - target: [SECOND_LOCATION]<br> reference_uuid: [UUID or leave empty]<br> placement: [inside or below or above]<br> components:<br> - sdc.another.component:<br> props:<br> another_prop: "value"</pre><p>This allows adding components at multiple positions simultaneously. </p>
<p>Once the agent provides output in the above format, its first passed through <code>CanvasAiPageBuilderHelper::addUuidToAllComponent()</code>, which assigns a unique UUID to each components.</p>
<p>The result is then given to <code>CanvasAiPageBuilderHelper::createExpectedPageLayout()</code>, which takes two inputs: the current layout and the component structure with UUIDs attached. Based on the values of target, reference_uuid, and placement, components are positioned in the correct place within the layout by <code>CanvasAiPageBuilderHelper::placeComponentsInLayout()</code></p>
<p>This step doesn’t actually update the page itself. It only performs array operations on the current layout data. Once the expected layout structure is prepared,<code> CanvasAiPageBuilderHelper::getCalculatedNodepath()</code> calculates the nodePath values for each newly added component.</p>
<h3 id="ui-changes">User interface changes</h3>
> Related issue: [Issue #3543519](https://www.drupal.org/node/3543519)
> Related issue: [Issue #3544614](https://www.drupal.org/node/3544614)
> Related issue: [Issue #3545378](https://www.drupal.org/node/3545378)
> Related issue: [Issue #3549232](https://www.drupal.org/node/3549232)
> Related issue: [Issue #3530701](https://www.drupal.org/node/3530701)
issue