Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
Account created on 26 December 2006, over 18 years ago
  • Senior Principal Software Engineer β€” Drupal Acceleration Team at AcquiaΒ  …
#

Merge Requests

More

Recent comments

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Next week.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Ready now, because:

  1. Not yet supported: a JSON schema (prop shape) for the following fields: test_optional__decimal, test_optional__language, test_optional__telephone, test_required__decimal, test_required__language, test_required__telephone
    

    and

    Not yet supported: a JSON schema (prop shape) for the following field properties: test_optional__decimal.value, test_optional__language.language, test_optional__language.value, test_optional__telephone.value, test_required__decimal.value, test_required__language.language, test_required__language.value, test_required__telephone.value
    

    … all of which is entirely reasonable: JSON Schema does not have native ways to express telephone numbers nor language references, and the "decimal" field type requires an adapter to be converted to a (JSON Schema) float. Instances of all other field types are either supported or explicitly ignored.

    BTW: this is now printed using E_USER_DEPRECATED, so that also fixes πŸ“Œ CI: surface the list of field types, field type props and field widgets not yet supported by XB Active . πŸ‘

  2. The explicitly ignored list is \Drupal\experience_builder\ShapeMatcher\JsonSchemaFieldInstanceMatcher::IGNORE_FIELD_TYPES and now also speeds up the matching. They are:
    public const IGNORE_FIELD_TYPES = [
        // The `list` field types allows each field instance to define its own set
        // of possible values. The probability of this exactly matching the explicit
        // inputs for a component is astronomical.
        // If we ever decide to allow this, then the `Choice` constraint must be
        // correctly specified on it. Otherwise, `::toDataTypeShapeRequirement()`
        // does not find any constraints and matches every such field instance
        // against every integer/float.
        'list_float' => ListFloatItem::class,
        'list_integer' => ListIntegerItem::class,
        'list_string' => ListStringItem::class,
        // The `map` field type has no widget, is broken, and is hidden in the UI.
        // @see https://www.drupal.org/node/2563843
        // @see \Drupal\Core\Field\Plugin\Field\FieldType\MapItem
        'map' => MapItem::class,
        // The `password` field type can never contain data that could be reasonably
        // displayed in a component instance.
        // @see \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem
        'password' => PasswordItem::class,
      ];
    

    … which is also entirely reasonable.

  3. Finally, this now gets us to:
      /**
       * The current % of supported field types whose instances can be matched.
       */
      public const COMPLETION = 0.8846153846153846;
    
      /**
       * The current % of supported field type props.
       */
      public const COMPLETION_PROPS = 0.8918918918918919;
    

    … but it really is ~100% for most sites in practice: few sites use the telephone, language or decimal field types for crucial data.

IOW: as of this issue, it's clear that essentially all structured data can be exposed via DynamicPropSources and hence via ContentTemplates! πŸ₯³

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Actually, #18 is wrong, too! πŸ˜…

  • It is about what field properties can be mapped into component instances.
  • But it is not about the component instance form: field instances indeed appear in the content entity form. That means @larowlan was kinda right.
  • Except … that it doesn't really matter (for πŸ“Œ Discover cases where is no 1:1 map between field, prop and widget values Active ), because on the component entity form, all field widgets must work anyway β€” even those whose data cannot be mapped into component instances.

So, it really doesn't belong on 🌱 [META] Expand support to *all* SDC prop shapes, and *all* Active either β€” if anything, it belongs on 🌱 [META] 7. Content type templates β€” aka "default layouts" β€” clarify the tree+props data model Active .

P.S.: eventually those unmatched field instances may end up being usable anyway, thanks to adapters (example: \Drupal\experience_builder\Plugin\Adapter\UnixTimestampToDateAdapter) being used in AdaptedPropSources. But the UX for that is not yet defined.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

I don't see how this actually relates to πŸ“Œ Discover cases where is no 1:1 map between field, prop and widget values Active β€” because that is solely about widgets on the content entity form.

This issue is about shape matching SDC props with field types, and hence show field widgets for those SDC props, which means it's about widgets on the component instance form.

As discussed at #3487284-18: [META] Add explicit end-to-end test coverage for using all core field widgets including multiple cardinalities in the "Page Data" (content entity) form β†’ , that means it belongs under 🌱 [META] Expand support to *all* SDC prop shapes, and *all* Active instead.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

off-topic
@effulgentsia in #10:

Also, renaming "props" to "properties" in the issue title. The "props" short-hand is a React convention, so I think should be reserved for React and component-based technologies that were inspired by React, including SDCs. Drupal field item properties, on the other hand, were inspired by object-oriented conventions, which typically use the unabbreviated word "properties".

Fair! I'll do this going forward. πŸ‘

But … it's far too easy to confuse "props" and "properties". So, I do think we must continue to always disambiguate: the entire XB codebase and docs refers to "field properties" as "field props" (i.e. always with the prefix "field") vs "SDC props" (for props of SDCs specifically) vs "component props" (for props of any component that uses the term "props", which includes JavaScriptComponents aka "code components").
end of off-topic

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

I’d swear this was already working, but I guess not?! πŸ€ͺ

Thanks to the solid test infra + @penyaskito’s excellent issue summary, I believe this is doable for a novice contributor 😊

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

FYI: with this done, I think it's time to re-assess πŸ“Œ ServerClientConversionTrait Active and friends, aka make a decision on whether to keep ClientServerConversionTrait because it is good enough, or whether to transition to something else/better.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

This AFAIK ties into follow-ups opened for πŸ“Œ Add support for Blocks as Components Active that were never followed up on. A quick scan suggests:

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Can we first do πŸ“Œ [PP-1] Refactor GeneratedFieldExplicitInputUxComponentSourceBase and FieldForComponentSuggester to need only SDC's ComponentMetadata, not SDC plugin instances Postponed , so that everything is at least using not SDC plugin instances but just \Drupal\Core\Theme\Component\ComponentMetadata?

After that, I agree the client-side schema stuff is important to generalize! Related: πŸ“Œ Evolve the organically grown `::getClientSideInfo()` into something cohesive Active .

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Related: #3521137-18: Stop storing JSON blobs in XB config entities: improve DX β†’ , which is an outline of how to do something similar for the other field props on the XB field type.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

As a byproduct, the TestDataUtilitiesTrait that @tedbow introduced in πŸ“Œ Convert test cases to use PHP arrays instead of JSON strings where possible Fixed to ease test development pain during initial development of XB, will largely be obsolete β€” that's what I asked for in #13, and which @phenaproxima almost completely finished! 🀩

In fact … since I'm feeling under the weather and my mind doesn't allow me to tackle anything complex right now, I just persevered and refactored it away: TestDataUtilitiesTrait is GONE! No more need to remember to wrap an array in a ::encodeXBData()! πŸ₯³ All thanks to the one crucial insight by @phenaproxima! πŸ‘

So: we'll not only make interacting with XB config less painful for site builders/XB users, but also for us developing XB, and hence improve development velocity slightly :)

P.S.: I'd still don't like that ->getValue(), TRUE has 7 matches in the codebase, but that's far better than the hundreds this MR removed. So, for the sake of iterative progress, didn't expand scope to that. Also: once πŸ“Œ Allow field types to control how properties are mapped to and from storage Needs work lands, XB won't have to work around that flaw in Drupal core anymore. If somebody wants to take that on: see attached PoC patch to get you going.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

FYI: The DX niceties this brought were slightly reduced in πŸ› ComponentTreeHydrated prevents serialization Active out of necessity.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ‘‰οΈπŸ”„

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Is this still relevant, @tedbow?

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

I don't think this being assigned to @lauriii for #34 is highly relevant anymore.

@penyaskito has been leading the effort on the XB team to get as many SDC improvements into core as possible. I see he's got πŸ› Disable additionalProperties in slots, props in SDC json schema Active to RTBC too 🀩πŸ₯³

@penyaskito Could you take on #46 + #47 on the XB side too? πŸ˜‡πŸ™

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Legitimate failure:

Tried to find [href*="components/my-hero/my-hero.css"] in <head> 

Due to this test assuming non-aggregation:

    // Confirm that the iframe loads the SDC CSS.
    cy.getIframe(
      '[data-xb-preview="lg"][data-test-xb-content-initialized="true"][data-xb-swap-active="true"]',
    )
      .its('head')
      .should('not.be.undefined')
      .then((head) => {
        expect(
          head.querySelector(
            'link[rel="stylesheet"][href*="components/my-hero/my-hero.css"]',
          ),
          `Tried to find [href*="components/my-hero/my-hero.css"] in <head> ${head.innerHTML}`,
        ).to.exist;
      });
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

If I was right in #3, then #3485878 should've fixed this too πŸ˜‡

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

@sandip There's a round of feedback on that MR, and there's also πŸ› Create loadAutoSave() helper function Active πŸ˜„

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

BE pieces + automatic-upgrade-path-upon-editing (the only backwards compatibility thing we've ever done, which feels odd, but it's so trivial that it is worth it) removal issue ( πŸ“Œ Remove backwards compatibility with "Text area" prop in code editor, superceded by "Formatted text" Postponed ) look good.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Trivial conflict resolution.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Thanks, @jatingupta40! Not passing tests yet, but a great start!

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ₯³

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ₯³

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

This will eventually end up unblocking πŸ“Œ [PoC] Introduce a `ContentTypeTemplate` config entity Active , because for that (and for performance reasons) we'll need to do that 3rd bullet point.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

RTBC'd with 2 caveats/requests: 1, 2.

If not addressed here, we need a follow-up for especially the latter.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

@sandip If you're interested in doing more of this valuable work: πŸ“Œ Rename `FieldForComponentSuggester` to `StructuredDataSourceSuggester` Active 😊🀞

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Thanks so much, @sandip, this feels way better! πŸ˜„

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Thanks for confirming.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

The content template should not be deleted.

Indeed!

This should make XB to fall back to the default (example) values for those inputs.

Yes, that's what @lauriii proposed in #11 πŸ‘
In my mind, we would just delete the component instance. But … I think what you propose here (and I guess makes more sense indeed! πŸ˜„

So:

  1. I have a ContentTemplate (for article nodes) with a hero component instance whose marquee prop is populated by
    {
      "marquee": {
        "sourceType":"dynamic",
        "expression":"β„ΉοΈŽβœentity:node:article␝field_funny_message␞␟value"
      }
    }
    

    i.e. it fetches the value field property of the field_funny_message field on the article node type.

    This was a DynamicPropSource.

  2. The site builder wants to delete field_funny_message; and it's not reasonable for a ContentTemplate to block that, but the ContentTemplate should also not be deleted.
  3. ContentTemplate::onDependencyRemoval(), checks iterates over all component instance inputs and finds the one that actually depends on this particular field (i.e. on the field.field.node.article.field_funny_message config). It replaces the DynamicPropSource with a StaticPropSource.

    Rough outline of algorithm:

    1. Check if this component requires explicit input ComponentSourceInterface::requiresExplicitInput(). If not: [] (the empty array)
    2. Sanity check: assert that Component::getSource() instanceof GeneratedFieldExplicitInputUxComponentSourceBase β€” only these sources can be populated by fields.
    3. (Untested PoC.) Populate all props with examples (which means: all required ones, plus the optional ones that do have an example).
      $component = Component::load(…);
      $source = $component->getSource();
      assert($source instanceof GeneratedFieldExplicitInputUxComponentSourceBase);
      if (!$component->requiresExplicitInput()) {
        return [];
      }
      
      // @see `type: experience_builder.generated_field_explicit_input_ux`
      $props_with_examples = array_keys(array_filter(
        $source->getSettings()['prop_field_definitions'],
        fn (array $def) => $def['default_value'] !== NULL
      ));
      return array_map(
        fn (string $prop_name) => $source->getDefaultStaticPropSource()->toArray()
        $props_with_examples
      );
      

      πŸ‘† This should return something like

      {
        "marquee": {
          "sourceType":"static:field_item:string",
          "value": "Hello, world!",
          "expression":"β„ΉοΈŽstring␟value"
        }
      }
      

      (You will need to refactor GeneratedFieldExplicitInputUxComponentSourceBase to make certain methods available to ContentTemplate. For alternative implementation inspiration, see GeneratedFieldExplicitInputUxComponentSourceBase::buildConfigurationForm()).

    4. ComponentSourceInterface::validateComponentInput() on the end result
    5. Prior to saving, verify the end result by using \Drupal\experience_builder\Plugin\Validation\Constraint\ValidComponentTreeConstraintValidator::validate()

    IOW: kinda like \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval() :)

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

This one seems simple enough :) I think tests are even overkill for this.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

This is well on its way β€” and a whole range of tests fail thanks to recent test infrastructure additions, which makes sense: \Drupal\Tests\experience_builder\Kernel\Plugin\ExperienceBuilder\ComponentSource\JsComponentTest::testRenderJsComponent()'s current expectations expect no cache tags; this changes that! πŸ₯³

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

add cache busting strings

Do you mean: a query string that includes the current time? Does that mean you're saying you're getting a cached response from the server side? If so: then this would actually be a server-side bug (cache tags, baby!).

Which β€¦ makes me actually jump to thinking this is just a duplicate of πŸ› Components sourced from JsComponent are missing source component cacheable metadata Active 😬 And I wouldn't have spotted that because I'm testing with settings.local.php containing

$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['cache']['bins']['page_cache'] = 'cache.backend.null';

πŸ™ˆ

@mayur-sose Can you test this again with #3522217 applied? πŸ™

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

#10: can you rephrase? I don't understand. πŸ˜…

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Thanks for confirming, @mayur-sose! πŸ˜ŠπŸ™

P.S.: When a bug report did not need fixes, we should not mark it . πŸ€“

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

@akhil babu in #5:

Rather than adding '/' to paths that dont start with it, we should add validation to the entity form fields

πŸ’―

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Signaling this requires FE-only changes.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ“Œ Support props that can use wysiwyg widgets Active is in now, which makes this much nicer to work on and more valuable to finish :)

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ₯³

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Merge this on the client side with the existing list of auto-saves

Does that client-side issue already exist?

Can we get the title updated to reflect what the scope is?

NW per @larowlan's https://git.drupalcode.org/project/experience_builder/-/merge_requests/9...

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

#19: @deepakkm: Please see my response at πŸ› Entity saved with autosaved data is not respected Active , can you please clarify it?

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Plus, as @larowlan argued: why is this even a bug? Isn't this a feature?

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

The title is very ambiguous. Tried to clarify it. Can you confirm it is correct?

However, when we search for 'Untitled Page,' we only get one result, which should not be the case.

Your wording implies there should be >1 result, but AFAICT there should be 0?

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Confirmed with @lauriii that it's fine to consider #3518201 and #3518203 as "nice-to-haves".

Assigning to myself to ensure I follow through with issues for hardening against the "red retry" boxes in @lauriii's screenshot in #11.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Making #31's follow-ups findable.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Argh, can't merge because package-lock.json was just updated in πŸ“Œ Compile Tailwind CSS globally for code components Active . Can you do that, @bnjmnm? πŸ™

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Aiming for RTBC since it was so very close in #27 already!

Removing tag, that's now going to be handled in πŸ“Œ Document use cases where XB's field widgets don't 1:1 match how they would work in a twig theme Active .

daterange_default detour

@bnjmnm must've been testing with the (optional) daterange module installed and hence ran into a one-line logic bug introduced by πŸ› Component transforms need to be per sourceType, not per component prop Active . To get past that, he defined an empty client-side transform for the daterange_default widget, which then resulted in it being claimed to be working in \Drupal\Tests\experience_builder\Kernel\EcosystemSupport\FieldWidgetSupportTest, which then undermined the value/meaningfulness of that test … because it doesn't actually work (and I spent ~30 minutes debugging and trying to get it to work, which is why there's now a detailed analysis of where it goes wrong) πŸ˜…
To avoid that information to go to waste: ✨ [later phase] Support `daterange_default` field widget in component instance form Postponed .

Manual testing

Works great! 🀩

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Based on work by @bnjmnm and I in πŸ“Œ Support props that can use wysiwyg widgets Active .

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Let's document this while it's still fresh in your head 😊

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Will investigate tomorrow what issues this needs. I expected πŸ“Œ Improve server-side error handling Active to have handled the /xb/api/v0/config/component case at the very least 😬

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

πŸ› Cannot delete JS components due to component depending on them Active might solve most of this.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

"components disappearing" ==

  • block β†’ the block plugin disappearing from a module
  • sdc β†’ the SDC disappearing from a module
  • js β†’ should not be possible thanks to config dependencies

So I placed the component on a page, deleted the component from the code base, cleared caches, and reloaded XB.

Hm, that seems fine then. That's equivalent to the SDC disappearing.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

How is this different from πŸ› Canvas and hover preview out of sync after drag-drop and publish Active ? That issue summary literally also refers to "hover":

Expected Result: The new background color (bg-blue-500) should be visible both in the Canvas and on hover.

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

@tedbow: Please:

  1. also enable CSS + JS aggregation for \Drupal\Tests\experience_builder\Functional\XbPageVariantTest to ensure we have pure BE test coverage (because I doubt the end-to-end tests test the live site, they AFAIK only test the XB editing UX)
  2. do a final round of manual testing with a code component that has an auto-save entry, and verify that this also works as the anonymous user.
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί
πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Will review this tomorrow πŸ‘ Meanwhile, it'd be great to have @f.mazeikis' question answered β€” funny enough I was forced to ask the same at #3517941-12: [META] Robust component instance error handling β†’ , independently of this! πŸ˜…

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

But: how did you make that component crash during rendering? It seems like you deleted an SDC, code component or a block plugin, instead of triggering one of the 6 failure modes described at the top of this issue?

Oh, perhaps you tested this by doing what @f.mazeikis also guessed over at #3519168-37: Handle components provided by ComponentSources disappearing ungracefully β€” enables deleting JS components that are in use β†’ , i.e. by deleting a Component config entity by force?

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

It looks like the library and the props forms fail to render because of the component is erroring. That is at least equally important with not crashing the whole preview. Is there an issue for that already?

No!

But: how did you make that component crash during rendering? It seems like you deleted an SDC, code component or a block plugin, instead of triggering one of the 6 failure modes described at the top of this issue?

If so: what you did is actually not related to this issue, because this issue is focused squarely on rendering of component instances never failing. AFAICT πŸ› Cannot delete JS components due to component depending on them Active should fix both symptoms. If it doesn't, I'll file issues under 🌱 [META] Production-ready client-side data model + internal HTTP API Active .

until we have designs to not have to spend time on implement a temporary solution.

Well … the point of the issue summary's sequencing (which you approved) is to do ✨ [PP-4] Present all component instances that fail to render using toasts Active using Radix UI toasts to spend zero time on a temporary solution β†’ , but to allow the design team to be better informed when designing this.

It would be great if the component was wrapped with the HTML comment so that it would be possible to see what is the name of the component in XB.

That's a trivial change to \Drupal\experience_builder\Element\RenderSafeComponentContainer::handleComponentException(), which is why it was built that way πŸ‘ However, why not just add a data-component-id attribute in addition to the current data-component-uuid?

  public static function handleComponentException(\Throwable $e, string $componentContext, bool $isPreview, string $componentUuid): array {
    \Drupal::logger('experience_builder')->error(\sprintf('%s occurred during rendering of component %s in %s: %s', $e::class, $componentUuid, $componentContext, $e->getMessage()));
    if ($isPreview) {
      return [
        '#type' => 'container',
        '#attributes' => [
          'data-component-uuid' => $componentUuid,
        ],
        '#markup' => new TranslatableMarkup('Component failed to render, check logs for more detail.'),
      ];
    }
    return [
      '#type' => 'container',
      '#attributes' => ['data-component-uuid' => $componentUuid],
      '#markup' => new TranslatableMarkup('Oops, something went wrong! Site admins have been notified.'),
    ];
  }
Production build 0.71.5 2024