Problem/Motivation

It should be able to store ui patterns inside the entity form.

Solution

Add an own storage including field widget.

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

christian.wiedemann created an issue. See original summary.

just_like_good_vibes’s picture

we also had some discussions about this, covering other different use cases from the contrib space.
it appears, that would be nice, in the general case, to store not 1 ui_patterns configuration, but a sequence of n configurations (that covers the case of 1), and also being able to store other metadata in addition to the ui_patterns config (like a key/value).
What do you think?

christian.wiedemann’s picture

Lets discuss this! I was just creating a simple field type to store ui patterns configuration.

pdureau’s picture

it appears, that would be nice, in the general case, to store not 1 ui_patterns configuration, but a sequence of n configurations (that covers the case of 1), and also being able to store other metadata in addition to the ui_patterns config (like a key/value).

Indeed, because we are talking about storage, which is hard to change once implemented, we need to do it right.

Instead of storing directly the data from ComponentForm:

component_id: 'ui_suite_bootstrap:accordion_item'
variant_id: null
slots:
  title:
    sources: []
props: {  }

It will be better to be positioned one level upper and store a slot sources list:

- 
  source_id: component
  source:
    component:
      component_id: 'ui_suite_bootstrap:accordion_item'
      variant_id: null
      slots:
        title:
          sources: []
      props: {  }

This upper level will not be used yet, so:

  • this MR's field widget will only load the first item of the root list, check if it is a component structure, and build ComponentForm from the data
  • this MR's field formatter will only load the first item of the root list, check if it is a component structure, and execute ComponentElementBuilder the data

For the field formatter, we can do event better, by updating the logic directly in ComponentElementBuilder::build(): add a new public method which is wrapping protected function buildSlot(array $build, string $slot_id, array $definition, array $configuration, array $contexts): array; or something like that, as an additional builder starting point.

The goal is to avoid the need to create fake components like that when we want to build a list of slot sources instead of a single component:

[
      '#type' => 'component',
      '#component' => 'my_project:fake_root',
      '#ui_patterns' => [
        'component_id' => 'my_project:fake_root',
        'slots' => [
          'content' => [
            'sources' => $data,
          ],
        ],
      ],
    ];
christian.wiedemann’s picture

Lets discuss that in a meeting.

christian.wiedemann’s picture

I think everybody have differnt use cases in mind. We should merge our ideas.

pdureau’s picture

I think everybody have differnt use cases in mind. We should merge our ideas.

Indeed. Different use cases doesn't necessary mean different implemntations.

christian.wiedemann’s picture

Yes! So from my point of view the Storage should store one complete UI Patterns config. We should change the cardinality to unlimited. But the content is just one config.
What we are missing is a mechanism to change a config structure in whole. For this I want to bring the idea from Mikkael (or what I understand) into play. Maybe we add processors to config.

component_id: comp
variant_id: variant
processors:
  - fake_root_processor
props: ...
slots: --

These processors can be configured during the mapping process. This can also help to reduce the mapping if a config field exists.
Each is processor is ... of course ... a configurable plugin.

So fake_root processors is for your case. For our case to automaticly merge the config from the field to resulting we use another processor. so we don't need a source just one processor.

pdureau’s picture

Let's try to move fast on this issue.

So, we agreed each field item must be a single "object" and if we want a collection of them we configure the field as multivalued.

What would be this object ? I am proposing it to have at least 2 field properties:

public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
  $properties['source_id'] = DataDefinition::create('string')
    ->setLabel(new TranslatableMarkup('ID'));
  $properties['source'] = MapDataDefinition::create()
    ->setLabel(new TranslatableMarkup('Data'));
  return $properties;
}

Mapping exactly the current UI Patterns 2 form data structure.

For example, a component source:

source_id: component
source:
  component:
    component_id: 'ui_suite_bootstrap:accordion_item'
    variant_id: null
    slots: {  }
    props: {  }

A block:

source_id: block
source:
  plugin_id: announce_block

A block with configuration:

source_id: block
source:
  plugin_id: 'views_block:content_recent-block_1'
  'views_block:content_recent-block_1':
    id: 'views_block:content_recent-block_1'
    label: 'Recent content'
    label_display: ''
    provider: views
    views_label: 'Recent'
    items_per_page: '5'

An entity field:

source_id: entity_field
source:
  derivable_context: 'field:node:article:status'
  'field:node:article:vid':
    value:
      add_more_button: ''
  'field:node:article:status':
    value:
      add_more_button: ''

Fabien, Christian, Mikael, are you OK with those 2 first field properties? Which other properties do you need? What would be the name of such a field type?

These processors can be configured during the mapping process. This can also help to reduce the mapping if a config field exists.

Interesting but it looks like a distinct issue, no?

christian.wiedemann’s picture

So I renamed the classes and add source_id and source to the storage. The widget only supports component right now. I like it so far. In future, we can provide more generic widget for different source. A complete generic one doesn't make sense from my point of view because a lot of widgets make only sense if they are preconfigred like the right component ID. But a source for simple widgets would be also nice. What is still missing is a Source for this but lets do this in a differnt issue.

christian.wiedemann’s picture

Assigned: Unassigned » pdureau
Status: Active » Needs review
goz’s picture

Status: Needs review » Needs work
just_like_good_vibes’s picture

i haven’t posted the updated code yet, i have a large update to this MR in preparation

just_like_good_vibes’s picture

Status: Needs work » Needs review
just_like_good_vibes’s picture

Title: Field Storage for UI Patterns Configuration » [2.0.3] Field Storage for UI Patterns Configuration
just_like_good_vibes’s picture

Status: Needs review » Needs work

i have created another issue to push some fixes (currently in the MR of this issue) in another MR first.
see #3513653: [2.0.3] Various bugfixes and edgecases when using sources outside of ui_patterns

just_like_good_vibes’s picture

just_like_good_vibes’s picture

Assigned: just_like_good_vibes » christian.wiedemann
Status: Needs work » Needs review

Christian, Fabien (@goz), and Pierre, would you review please?

there may be a last private comment from Pierre, unaddressed :

- why do we use datatype custom, isn't map enough?

goz’s picture

Issue summary: View changes
Status: Needs review » Needs work
StatusFileSize
new2.38 MB

Something is wrong with the last commits, my submission is not stored anymore in field. FYI, i also use last commit from https://www.drupal.org/i/3511027

just_like_good_vibes’s picture

Status: Needs work » Needs review

All good without the component widget, because ui_patterns_ui will provide a better one with customized form.
previous bugs may be fixed, please review :)

christian.wiedemann’s picture

I am fine now. Lets merge. A UI Patterns UI Form Widget will follow soon.

christian.wiedemann’s picture

Status: Needs review » Reviewed & tested by the community
pdureau’s picture

Status: Reviewed & tested by the community » Needs work

Sorry to disturb that late, but do we really need a custom data type (Source) storing the data in JSON?

There are already data type in Drupal Core for such data structure which are (theoretically, we need to check) more performant for decoding/encoding nested PHP arrays, like https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21TypedData...

XB is also using a custom data type based on JSON, but I guess they send the exact data as HTTP Response Body, without the need of unserialize it to PHP arrays

What do you think about that?

goz’s picture

Sad to see widget disappear while it was working in previous commits :(

I think you are right @pdureau, MapItem could do the job BUT we have to be sure it do the job without having to tweak it and it does not seem to be really used

just_like_good_vibes’s picture

sorry for the disappearance, Christian was a bit disturbed by that widget, and thought ui patterns ui could be better, which would be true but would clearly need additional configuration to create that form
and apply it. Maybe we reintroduce?

the custom data type is ok for me, but i will give a try to map, every data type needs to have a chance 🤣

just_like_good_vibes’s picture

pdureau’s picture

but i will give a try to map, every data type needs to have a chance 🤣

Thanks you so much. Can you do some performance tests? If they are more or less the same, let's avoid the introduction of a custom data type.

just_like_good_vibes’s picture

Assigned: just_like_good_vibes » pdureau
Status: Needs work » Needs review

Back at it !
i did the change, even better than expected.

Also i re-introduced the component widget but with a way nicer default mode and i took care of previous comments from Christian about how props were filtered.
now it's a quite super clean default mode for editors, when ui_patterns_ui is not enabled.

just_like_good_vibes’s picture

i forgot to mention that :
- i added a kernel test : it allows to test that the field is working (accepting the value) and the new mapping source also.
- i corrected a few sources that were not tagged as widgets.
- as you can remark, i introduced a few new properties to our component form elements. It allows us better control on how the forms are rendered (wrap into details or not, headings or not, hide/show sources for props, only show some props). The opens an even nicer "API" for other modules when they embed the component related forms (component form, slot form, prop form). ui_patterns_ui will introduce an advanced control on how component forms could look, but that here is different.

christian.wiedemann’s picture

Should we rename only_props to props_filter in the widget?

just_like_good_vibes’s picture

Yes good idea

goz’s picture

Status: Needs review » Needs work
StatusFileSize
new4.04 MB

Thanks to put widget back.
Glad to see we are moving to MapItem, good job !

I still have an issue, but we are almost there !

With my layout paragraph, i have a field storage for components (props & variant).
When i create my paragraph, content is stored correctly.
When i edit my paragraph, preview is good, but saving loose changes.
In database, changes are not saved.

pdureau’s picture

The 2 field widgets have similar and confusing labels:

  • "Component slot source": the exact same label as the field type?
  • "UI Patterns slot source": what is the difference with previous?
just_like_good_vibes’s picture

field type :

"Source (UI Patterns)"

field widget :

- All slot sources (UI Patterns)
- Components only (UI Patterns)

pdureau’s picture

Great. Can you also change the plugin IDs accordingly?

just_like_good_vibes’s picture

Assigned: pdureau » christian.wiedemann
Status: Needs work » Needs review

Guys, i corrected the wording, i hope it fits our needs and reached consensus.

With @goz, we also investigate a strange behavior using layout paragraphs and we corrected a bug :)
list_class in the field type.

it may be ready to be merge right now...

just_like_good_vibes’s picture

Title: [2.0.3] Field Storage for UI Patterns Configuration » [2.0.4] Field Storage for UI Patterns Configuration
Assigned: christian.wiedemann » Unassigned
Status: Needs review » Reviewed & tested by the community

just_like_good_vibes’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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

christian.wiedemann’s picture