Overview

#3510896: Add a new internal HTTP API for candidate `DynamicPropSource`s to enable a `ContentTemplate` UI built a HTTP API on top of FieldForComponentSuggester.

That's been around for >1 year and never used in the UI. So the labels are developer-supporting, not end-user supporting. But confusing.

  1. ✅ Too verbose: This Article's Title → just Title
  2. 🟡 Way too verbose when matching subsets that do NOT include the main property (or a computed property depending on the main property): Subset of this Article's field_silly_image: alt (1 of 7 props — absent: entity, title, width, height, srcset_candidate_uri_template, src_with_alternate_widths) switch to a nested structure: just {Silly Image: {Alternative Text}, to allow for a nested contextual menu to be presented in the UI being added at #3541037: Allow linking `ContentTemplate` SDC/code component instance props to fields (aka finally use `DynamicPropSource`s!).
  3. ✅ Way too verbose when matching subsets that DO include the main property (or a computed property depending on the main property): Subset of this Article's field_silly_image: src_with_alternate_widths, alt, width, height (4 of 7 props — absent: entity, title, srcset_candidate_uri_template) → switch to just Silly Image
  4. ✅ The ordering does not match the mental model of the site builder: it should match the order of the EntityFormDisplay.

Proposed resolution

See above!

Basically, refactor to be able to remove

              // Generate a label for the suggestion:
…
              // - one that describes the subset of the entity field otherwise,
              //   with explicit (developer-friendly, user-overwhelming) info on
              //   which field props are present vs absent.

which #3512433: Provide visibility into which (core) field types (74%), field type props (63%) can be mapped into Content Type Templates vs not, and which field widgets (36%) are supported added 🤣

User interface changes

#3541037: Allow linking `ContentTemplate` SDC/code component instance props to fields (aka finally use `DynamicPropSource`s!) becomes much better 😊

Which Before Interim (#34) After
type: integer
type: string, format: uri-reference, x-allowed-schemes: [http, https]

(Note that this is still not using the "proper" hierarchical UI, but this visualizes what that WILL show. See #3548322: Improve how list of field suggestions is displayed in the UI for `ContentTemplates` and remove `ContentTemplates` from feature flag.)

Issue fork canvas-3547598

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:

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

Project: Experience Builder » Drupal Canvas

wim leers changed the visibility of the branch 3547598-better-dynamic-prop-source-suggestions to hidden.

wim leers’s picture

wim leers’s picture

wim leers’s picture

Issue summary: View changes

LOL, apparently I wrote

              // Generate a label for the suggestion:
…
              // - one that describes the subset of the entity field otherwise,
              //   with explicit (developer-friendly, user-overwhelming) info on
              //   which field props are present vs absent.

back in #3512433: Provide visibility into which (core) field types (74%), field type props (63%) can be mapped into Content Type Templates vs not, and which field widgets (36%) are supported 🤣

wim leers’s picture

wim leers’s picture

Issue summary: View changes

Step 2 is done partially: https://git.drupalcode.org/project/canvas/-/merge_requests/107/diffs?com...

→ now shows as Silly image (only width, for example.

wim leers’s picture

Status: Active » Reviewed & tested by the community

The current MR represents all changes that can happen without drastically changing #3541037: Allow linking `ContentTemplate` SDC/code component instance props to fields (aka finally use `DynamicPropSource`s!), too.

What remains: generating a nested structure. However, what we failed to discuss/realize yesterday, but do need to solve somehow, is the distinction between nesting for:

  • a field pointing to a field on another entity → requires a nested contextual menu
  • a field of which only a subset is consumed (and this could also be a reference field!)

Because it's possible that both occur!

Quotes from the test coverage, for datetime string matching:

            "field_event_duration (only end_value)" => 'ℹ︎␜entity:node:foo␝field_event_duration␞␟end_value',
            "field_event_duration" => 'ℹ︎␜entity:node:foo␝field_event_duration␞␟value',

and for UUID matching:

            "Authored by → User → uuid" => 'ℹ︎␜entity:node:foo␝uid␞␟entity␜␜entity:user␝uuid␞␟value',
            "Authored by (only target_uuid)" => 'ℹ︎␜entity:node:foo␝uid␞␟target_uuid',

and for integer matching

            "Authored by → User → access" => 'ℹ︎␜entity:node:foo␝uid␞␟entity␜␜entity:user␝access␞␟value',
            "Authored by → User → changed" => 'ℹ︎␜entity:node:foo␝uid␞␟entity␜␜entity:user␝changed␞␟value',
            "Authored by → User → created" => 'ℹ︎␜entity:node:foo␝uid␞␟entity␜␜entity:user␝created␞␟value',
            "Authored by → User → login" => 'ℹ︎␜entity:node:foo␝uid␞␟entity␜␜entity:user␝login␞␟value',
            "Authored on" => 'ℹ︎␜entity:node:foo␝created␞␟value',
            "Changed" => 'ℹ︎␜entity:node:foo␝changed␞␟value',
            "Silly image 🤡 → File → changed" => 'ℹ︎␜entity:node:foo␝field_silly_image␞␟entity␜␜entity:file␝changed␞␟value',
            "Silly image 🤡 → File → created" => 'ℹ︎␜entity:node:foo␝field_silly_image␞␟entity␜␜entity:file␝created␞␟value',
            "Silly image 🤡 → File → filesize" => 'ℹ︎␜entity:node:foo␝field_silly_image␞␟entity␜␜entity:file␝filesize␞␟value',
            "Silly image 🤡 (only height)" => 'ℹ︎␜entity:node:foo␝field_silly_image␞␟height',
            "Silly image 🤡 (only width)" => 'ℹ︎␜entity:node:foo␝field_silly_image␞␟width',

👆 we need to decide how we want to present those; presenting the same is probably not going to make a lot of sense if executed in the simplest way, because in that last example, we'd present the following tree:

Authored by 
    → User
        access
        changed
        created
        login
Authored on
Changed
Silly image 🤡
    → File
        changed
        created
        filesize
    only height
    only width

Either way, what's in this MR causes zero disruption to #3541037: Allow linking `ContentTemplate` SDC/code component instance props to fields (aka finally use `DynamicPropSource`s!), so landing this MR first 👍

  • wim leers committed 9f218c54 on 1.x
    [#3547598] feat(Shape matching): Refine the labels and ordering in the...
wim leers’s picture

Assigned: wim leers » lauriii
Status: Reviewed & tested by the community » Needs review
Issue tags: +Needs product manager review

For the explanation + question in #11.

lauriii’s picture

I don't see why #11 couldn't be implemented in a nested tree of dropdowns? It is just that in the case of a reference field that doesn't allow additional properties, you'd have to go through another level of nesting which seems fine as the first iteration of this – it's still much better than showing them all as a single list. We can potentially apply some optimizations on that in future.

wim leers’s picture

From a technical POV, it can. That's literally what I illustrated in the code blocks.

From a usability POV, I think it's really bad. Because in some cases, the nesting means following an entity reference, in other cases it means picking a single field property of the field in the top level.

wim leers’s picture

Assigned: lauriii » wim leers
Status: Needs review » Needs work

Point 4 in the issue summary (matching form display order) doesn't work correctly. Root cause: EntityFormDisplay::getComponents() confusingly doesn't return them in the right order 🙃

wim leers changed the visibility of the branch 3547598-formdisplay-getcomponents-is-absurdly-bad to hidden.

wim leers changed the visibility of the branch 3547598-formdisplay-getcomponents-is-absurdly-bad to active.

wim leers’s picture

Wow, now GitLab is broken — the branch points to the open MR at https://git.drupalcode.org/issue/canvas-3547598/-/merge_requests/129, but that is a 404 🙃

  • wim leers committed e8ff828e on 1.x
    [#3547598] fix(Shape matching): Fix sorting of DynamicPropSource...
wim leers’s picture

#3548322: Improve how list of field suggestions is displayed in the UI for `ContentTemplates` and remove `ContentTemplates` from feature flag is the FE follow-up to implement #11 at the UI level. @lauriii responded in #14, but incompletely. See #15 for the outstanding question.

hooroomoo’s picture

StatusFileSize
new143.97 KB

We can do something like this where we utilize separators and labels to differentiate between a field pointing to a field on another entity and a field of which only a subset is consumed (and this could also be a reference field!) .

I mocked this up in Figma using the example @wimleers gave in #11 (last code block):

So use a label in this case ("File") for fields for another entity and add a separator after it.

sc

OR 'File' can open its own menu with its options.

Only local images are allowed.

wim leers’s picture

Assigned: lauriii » hooroomoo
Status: Needs review » Needs work
Issue tags: -Needs product manager review
lauriii’s picture

hooroomoo’s picture

Expected API here :-)

And have it in a way where the frontend can just render the JSON directly without any re-ordering/manipulating based on @lauriii's guidelines in #25?

id would just be used by the frontend for the unique key required in a React list item so the frontend doesn't have to generate its own.

  {
    "id": "some-unique-id" 
    "label": "Image",
    "source": <opaque JSON object>,
    "items": [
      { "id": "some-unique-id", "label": "Changed", "source": <opaque JSON object> },
      { "id": "some-unique-id",  "label": "Created", "source": <opaque JSON object> },
      { "id": "some-unique-id", "label": "File size", "source": <opaque JSON object> }, 
    ]
  },
hooroomoo’s picture

Assigned: hooroomoo » Unassigned
wim leers’s picture

If somebody wants to pick this up before me (please do!): this requires refactoring \Drupal\canvas\ShapeMatcher\FieldForComponentSuggester::structureSuggestionsForResponse() to output the structure @hooroomoo outlined in #26.

wim leers’s picture

Assigned: Unassigned » wim leers

wim leers’s picture

Made good progress on this today. Sprinkled 🚧 comments to pick this up tomorrow. Will finish then.

wim leers’s picture

wim leers’s picture

Fully green! 🥳

Time now to generate the JSON structure outlined by @hooroomoo in #26.

wim leers’s picture

Time to visualize the progress. See the updated issue summary.

Now it's time to aim for meeting all of the requirements set forth by @lauriii at #3548322-13: Improve how list of field suggestions is displayed in the UI for `ContentTemplates` and remove `ContentTemplates` from feature flag:

  1. We should sort the fields based on default form display order (when there is a form display to reference)
  2. Fields not on the form display should be displayed below the ones that are on form display in alphabetical order
  3. In the scenario of file entity in images, we should simplify the structure and bring the file entity properties to the second level
  4. .

  5. We should capitalize properties
  6. We should not display 'only' as a prefix
  • #1 already landed in this issue as part of !107+!129.
  • #4 + #5 are done as you can seen in the screenshots, in the in-progress !191.
  • #2 I'm not sure what it is referring to. 😅

Working on #3 now.

wim leers’s picture

Issue summary: View changes

Fix HTML.

wim leers’s picture

#3 is implemented 👍

That leaves now only the hierarchical response structure outlined by @hooroomoo in #26.

wim leers’s picture

Assigned: wim leers » Unassigned
Status: Needs work » Reviewed & tested by the community

As the screenshots in the "UI changes" section illustrate, this is already a big leap forward.

The UI will take advantage of this in the follow-up this unblocks, see #3548322-16: Improve how list of field suggestions is displayed in the UI for `ContentTemplates` and remove `ContentTemplates` from feature flag and the subsequent comment for guidance.

wim leers’s picture

Assigned: Unassigned » jessebaker
StatusFileSize
new38 KB

primary-panel.cy.js's previews components on hover test case seems to be failing consistently on CI for this MR (passing consistently on 1.x HEAD), but locally it passes just fine:

Re-tested a 3rd time: https://git.drupalcode.org/project/canvas/-/jobs/6811379 🤞

Worst of all: that is testing component previews in the list of components available to instantiate, which this MR is not even getting close to touching any code path for 😭

@jessebaker touched that file yesterday, so I'm hoping he has a hunch…

wim leers’s picture

Assigned: jessebaker » Unassigned

OMG — now it passed: https://git.drupalcode.org/project/canvas/-/jobs/6811379 (but now navigation.cy.js failed 🤷‍♂️ — random fails are such a PITA!).

  • wim leers committed 6d0717b0 on 1.x
    [#3547598] feat(Shape matching): Update API response to provide a...
wim leers’s picture

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.