Overview

Similar to #3522130: Add client-side transform for daterange_default to ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter, but for EntityReferenceAutocompleteWidget (plugin ID: entity_reference_autocomplete).

This is necessary for the simplest possible implementation of #3573831: [META] Code Components: add an "entity reference" prop type — enables "view modes" that combine multiple entities plus static inputs!, assuming the answer to whether to use that widget remains "yes" — but it depends on its designs

Proposed resolution

Implement client-side transform.

User interface changes

Entity reference auto-complete widget starts working :)

Issue fork canvas-3574857

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

wim leers created an issue. See original summary.

wim leers’s picture

wim leers’s picture

Title: Add client-side transform for entity_reference_autocomplete to \Drupal\experience_builder\Hook\ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter » Add client-side transform for entity_reference_autocomplete to ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter
Issue tags: -JavaScript +JavaScript

scott falconer made their first commit to this issue’s fork.

scott falconer’s picture

Assigned: Unassigned » scott falconer

scott falconer’s picture

Status: Active » Needs work
StatusFileSize
new8.88 KB
new5.04 KB
new8.73 KB
new7.31 KB

This updates Canvas field-widget transform metadata so entity_reference_autocomplete works client-side.
Attached are screenshots demonstrating the entity reference auto-complete widget working correctly in the Canvas UI.

What changed:
- Added entity_reference_autocomplete transform metadata in ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter().
- Updated FieldWidgetSupportTest expected support/completion values.
- Added focused unit test: tests/src/Unit/Hook/ReduxIntegratedFieldWidgetsHooksTest.php

Screenshots:
- 01-before-initial-field-value-full-page.png (initial state with existing entity reference value)
- 02-before-empty-field-full-page.png (field cleared and ready for autocomplete)
- 03-during-query-with-suggestions.png (typed query with autocomplete suggestion list visible)
- 04-after-selected-value-full-page.png (selected autocomplete value applied to the field)

Tests run:
- ddev phpcs src/Hook/ReduxIntegratedFieldWidgetsHooks.php tests/src/Kernel/EcosystemSupport/FieldWidgetSupportTest.php tests/src/Unit/Hook/ReduxIntegratedFieldWidgetsHooksTest.php
Result: pass (exit 0)
- ddev phpunit tests/src/Unit/Hook/ReduxIntegratedFieldWidgetsHooksTest.php
Result: pass (exit 0; 1 PHPUnit deprecation reported)
- ddev phpunit tests/src/Kernel/EcosystemSupport/FieldWidgetSupportTest.php
Result: pass (exit 0)
- ddev phpunit tests/src/Functional/BlockComponentFormTest.php
Result: pass (exit 0)
- Manual UI validation in Canvas editor:
Result: pass, the "Canvas Entity Reference (Autocomplete)" widget successfully selected "I am an empty node (2)" at /canvas/editor/node/2 (captured in attached screenshots)

AI disclosure: This patch and test/reporting notes were prepared with AI assistance and then validated locally with the commands above and manual testing.

scott falconer’s picture

Assigned: scott falconer » Unassigned
Status: Needs work » Needs review

All tests green.

rakhimandhania’s picture

wim leers’s picture

Status: Needs review » Needs work

Wow, I did not expect an MR on this so quickly after opening it! 🥳

The tests do not actually test anything.

This needs to update ui/tests/e2e/prop-types.cy.js similar to what https://git.drupalcode.org/project/canvas/-/merge_requests/627 does. It should basically test that a particular selection results in the corresponding target IDs, similar to these existing client-side transforms for other widgets:

      'file_generic' => ['mainProperty' => ['name' => 'fids']],
      'image_image' => ['mainProperty' => ['name' => 'fids']],

and

    $info['media_library_widget']['canvas'] = [
      'transforms' => [
        'mediaSelection' => [],
        'mainProperty' => ['name' => 'target_id'],
      ],
    ];

So that something like

foo (42), bar (3)

results in

[42, 3]

To test this, you could do something like:

diff --git a/src/Hook/ShapeMatchingHooks.php b/src/Hook/ShapeMatchingHooks.php
index 14fea5f98..518bb223b 100644
--- a/src/Hook/ShapeMatchingHooks.php
+++ b/src/Hook/ShapeMatchingHooks.php
@@ -375,7 +375,7 @@ class ShapeMatchingHooks {
           'target_bundles' => array_combine($media_type_ids, $media_type_ids),
         ],
       ];
-      $storable_prop_shape->fieldWidget = 'media_library_widget';
+      $storable_prop_shape->fieldWidget = 'entity_reference_autocomplete';
     }
   }
 

… which would then NOT use the media library widget, but entity reference autocomplete to select an image to populate any "image object" prop, for example the one in the Canvas test SDC with optional image, without example test SDC (tests/modules/canvas_test_sdc/components/image-optional-without-example/image-optional-without-example.component.yml).

scott falconer’s picture

What changed in this reroll:
- Added a real client-side transform for entity reference autocomplete parsing in ui/src/utils/transforms.ts.
- Added entityAutocompleteTargetId to entity_reference_autocomplete transform metadata in ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter().
- Updated docs/redux-integrated-field-widgets.md to list the new transform.
- Updated tests/src/Kernel/EcosystemSupport/FieldWidgetSupportTest.php:
- Added entity_reference_autocomplete to SUPPORTED.
- Updated COMPLETION to 15 / 28.
- Removed tests/src/Unit/Hook/ReduxIntegratedFieldWidgetsHooksTest.php (maintainer feedback: it only tested array wiring).
- Added behavior-focused UI unit coverage:
- ui/tests/vitest/unit/transforms.test.js
- ui/tests/vitest/unit/formUtils.test.js

Tests run:
- ddev phpcs src/Hook/ReduxIntegratedFieldWidgetsHooks.php tests/src/Kernel/EcosystemSupport/FieldWidgetSupportTest.php
Result: pass (exit 0)
- ddev phpunit tests/src/Kernel/EcosystemSupport/FieldWidgetSupportTest.php
Result: pass (exit 0)
- ddev exec "cd /var/www/html/ui && npm run test -- tests/vitest/unit/transforms.test.js tests/vitest/unit/formUtils.test.js"
Result: pass (exit 0)

AI disclosure: This reroll and test/reporting notes were prepared with AI assistance and then reviewed/validated with the commands above.

scott falconer’s picture

Status: Needs work » Needs review

Thank you for the review! Comments addressed and tests passing.

wim leers’s picture

Status: Needs review » Needs work
scott falconer’s picture

Status: Needs work » Needs review
rakhimandhania’s picture

Issue tags: +AI Page Generation
jibran’s picture

Assigned: Unassigned » jibran

I'll look into the review this week.

lauriii’s picture

@jibran are you still planning to review this? 😇 Just double checking so that I know if I should try to find someone else to review this.

jibran’s picture

Assigned: jibran » Unassigned
Status: Needs review » Needs work

Sorry, I was busy the last two weeks and didn't get a chance to finish my review.

Have a look at the code. The changes look good. The branch needs a rebase, and after that, it is good to go.

ajv009’s picture

Assigned: Unassigned » ajv009
ajv009’s picture

Rebased the branch onto current 1.x as @jibran requested in #18.

The main thing to note: upstream 1.x picked up daterange_default support (from #3522130: Add client-side transform for daterange_default to ReduxIntegratedFieldWidgetsHooks::fieldWidgetInfoAlter), which touched several of the same files. The conflicts were straightforward to resolve:

  • FieldWidgetSupportTest.php: bumped COMPLETION to 16 / 28 (was 15/28 on both sides, each adding one widget)
  • docs/redux-integrated-field-widgets.md: kept both the dateRange and entityAutocompleteTargetId entries
  • ui/src/utils/transforms.ts: upstream refactored the link transform to support multi-value and extracted a resolveEntityUri helper. Updated that helper to use parseSingleEntityAutocompleteSelection from this MR instead of inline regex matching

No logic changes beyond integrating the two branches cleanly.

Transparency note: This rebase was performed with highly supervised usage of Claude Code. I verified the conflict resolutions personally. Happy to revert if anything looks off.

ajv009’s picture

Assigned: ajv009 » Unassigned
Status: Needs work » Needs review
jibran’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs screenshots

The changes look good now. Thank you.