Overview

In #3484666: Show configuration forms for Block components we enabled block component settings forms in the UI, but they are not yet functional. This issue exists to complete that work and make block settings changes in the UI propagate to the back end including data storage and preview.

Block components have no slots props, but they can have "block settings". These are used to configure the block and (in most cases) affect its output in some way. Examples are the number of levels of hierarchy to show in a menu block, or checkboxes to control which elements are displayed in the site branding block.

Block settings are similar to, but not the same as, SDC props.

Proposed resolution

?

User interface changes

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

longwave created an issue. See original summary.

wim leers’s picture

Title: Implement saving block settings forms » [PP-1] Implement saving block settings forms
Status: Active » Postponed
larowlan’s picture

wim leers’s picture

I'm not opposed to that at all, but @longwave, @jessebaker and others felt that #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. was too broad in scope to be actionable. If you managed to act on it anyway, all the better! 😄

wim leers’s picture

Title: [PP-1] Implement saving block settings forms » Implement saving block settings forms
Status: Postponed » Active

longwave’s picture

Status: Active » Needs work

I learned enough React to be able to hack something together here that seems to work. Block settings are a hybrid of SDC component forms (as they update the model) and page data forms (as they use standard Drupal forms), I think inputBehaviors needs some more refactoring to figure this out to how split this up in a better way.

larowlan’s picture

Ran out of time today, but compared the component inputs form HOC against the block one and I think we should be able to make them one and the same. Because the form state and these input behaviours are locked up in the compiled FE build, any deviation that is per source component is going to make things difficult for contrib (and a layout builder/paragraphs BC layer).
Ideally we can leverage the SimpleComponent/SDCComponent differentiation in #3493941 and then defer any other nuance between Source plugins to pure PHP. That leaves the door open for Layout plugins (LB), paragraph plugin and anything else from contrib

wim leers’s picture

Per @larowlan's latest MR comment.

longwave’s picture

Been going back and forth to try and figure out the best way forward here. The problem is that the SDC version of the form presents field widgets, and these have keys from field widgets, e.g. heading[0][value], which we then map into props. Block forms (and any other non-widget form I guess) just has plain keys, e.g. level. But we can't make assumptions, because there might be complex block forms that have structures that look a bit like widget forms, but aren't - so we do need to distinguish between them somehow - but right now these Form API structures have specific assumptions made about them.

As far as I know there is no requirement to have block forms have dynamic props, we can assume static values. But not sure about other component source plugins, they might still want to support dynamic props?

larowlan’s picture

In https://git.drupalcode.org/project/experience_builder/-/merge_requests/448 I've tried to remove those assumption - but it will likely need to come back in some form by way of transforms in #3467954: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. but ideally it can be controlled from PHP

For #3487484: Save page data form values in application state with support for undo/redo we were able to remove the knowledge of that nesting and let Drupal sort it out - i.e. we store the page values keyed by the name attribute for their respective input (e.g. 'title[0][value]' and then that is transformed back into the nested format Drupal side.

larowlan’s picture

longwave’s picture

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

It's green!

larowlan’s picture

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

This looks ready to me in its current form. There's a followup for the reunification.

wim leers’s picture

Assigned: wim leers » Unassigned
Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests, +Needs documentation

This issue exists to complete that work and make block settings changes in the UI propagate to the back end including data storage and preview.

(Emphasis mine.)

The preview part is working.

The storage part is not. It's only auto-saving (to ephemeral storage), not really saving (to an XB field or the PageTemplate). Which means it's not really stored, nor passing validation.


Besides that, I am concerned about:

  1. the deviation from the previously established terms "explicit inputs" and "implicit inputs": https://git.drupalcode.org/project/experience_builder/-/merge_requests/5... — block settings are explicit inputs for that the "block" component source. As captured by this bit in the issue summary: Block settings are similar to, but not the same as, SDC props.
  2. the (undocumented) meaning of supportsProperties and supportsDynamicProperties: https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...

Perhaps it's worth meeting on Monday morning about this, @longwave, to figure out the naming and docs? Happy to write those together!

effulgentsia’s picture

It's only auto-saving (to ephemeral storage), not really saving (to an XB field or the PageTemplate). Which means it's not really stored, nor passing validation.

How are you determining that without #3497530: Implement the "Publish All" button being done? Are you testing the publish step some other way?

wim leers’s picture

IDK who/when/where this happened but there still is a “Publish” button next to thr “Review changes” dropdown 😅🙈

effulgentsia’s picture

Oh, right, I forgot that button was still there. So originally, that button implemented direct-to-entity-save (without going through autosave), so that we could work on issues having to do with saving entities in parallel with figuring out how we wanted to handle autosaving.

Once we got autosaving working, I think we opened an issue to change this Publish button to not send the entity data in the request body, but instead to just send the autosave key (or the info needed to figure out the autosave key), and the server-side controller to save from the corresponding autosaved data instead of from the request body. However, I forget if we completed that issue.

So, if that is in fact how the Publish button now works, then I do think it makes sense, as either part of this issue or as a followup that can proceed right after this issue is merged, to make sure that block settings get validated and transferred correctly from the autosave data to an entity revision. Because presumably the work to do that would be exactly the same as what will get triggered by the "Publish All" button once that's in.

However, if the Publish button is still working the old way where it's publishing from the request body rather than the autosave data, then I don't think it makes sense to make that old way work with block settings. Because once the "Publish All" button is in, we'll remove the "Publish" button.

effulgentsia’s picture

Issue tags: +sprint

Up until now, the XB team has been following a pseudo-scrum/pseudo-kanban process, but we're now shifting into more conventional scrum. We started a new 2-week sprint last Thursday (Jan 16). I'm tagging our current sprint's issues for visibility.

larowlan’s picture

I've renamed the methods/attribute properties and documented them as follows:

* @param bool $hasExplicitInput
   *   TRUE if the component source generally expects input from the user. This
   *   could be in the form of props for a single directory component or
   *   settings for a block component. Pass FALSE if the component expects no
   *   input from the user. This can be modified on a per-component basis by
   *   implementing the ::componentHasExplicitInput method in the plugin class.
   * @param bool $hasEvaluatedInput
   *   TRUE if the component stores its input in the form of prop-sources. This
   *   input is stored as a combination of a source-type and expression.
   *   Depending on the source-type it may include additional input including a
   *   value or adapter configuration. A source plugin that passes TRUE here is
   *   also assumed to have explicit input. This can be modified on a
   *   per-component basis by implementing the ::componentHasEvaluatedInput
   *   method in the plugin class.
/**
   * Returns TRUE if the component source expects input from the user.
   *
   * @return bool
   *
   * @see \Drupal\experience_builder\Attribute\ComponentSource
   */
  public function componentHasExplicitInput(): bool;

  /**
   * Returns TRUE if the component stores input in the form of prop-sources.
   *
   * @return bool
   *
   * @see \Drupal\experience_builder\Attribute\ComponentSource
   */
  public function componentHasEvaluatedInput(): bool;

And the protected methods on the tree data-type are now componentHasExplicitInput and componentHasEvaluatedInput

I've also added an e2e test and for clicking publish with a block in the body and expanded test coverage in the client conversion test to ensure this is supported both for nodes and patterns.

Looking into the last open item regarding validation now.

larowlan’s picture

Status: Needs work » Needs review

This is ready for another look.
I think we also should consider a general followup to revisit some more uses of 'props' in the codebase including ComponentPropsValues in typed data. I'm happy to keep going on renames here, but it feels like we're getting into out of scope territory and making it harder to review this issue.

longwave’s picture

I think @larowlan's suggested renaming/refactors can be done in followups, but added a minor refactoring of my own to make the JS easier to follow and added some questions/suggestions.

wim leers’s picture

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

#21: #3494859: Rename Component config ComponentSource plugin-specific configuration keys for clarity fixed some of those "props" in the codebase :)

This MR is now looking way better than on Friday. I wanted to review+RTBC+merge, but @longwave's remarks alongside my own observations make me conclude that this is not yet ready to be merged. Two critical comments that I'm curious what y'all think about:

  1. https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
  2. https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...

+1 for renaming ComponentPropsValues in a follow-up issue. Or … perhaps it actually would make help this issue simpler?

AFAICT the #1 thing slowing us down here is XB's SDC-centric naming of low-level infrastructure. If that were refactored away first, it'd allow us to land this MR with more clarity and confidence?


Unless I see comments articulating strongly why not to do that, that's where I'll start my day tomorrow: refactor away the pervasive "props" and "prop sources" in the XB field type. I think that will clear things up a lot.

larowlan’s picture

Assigned: larowlan » Unassigned
Status: Needs work » Needs review
longwave’s picture

Status: Needs review » Reviewed & tested by the community

Fixed the failing test, added a minor comment based on an MR comment, otherwise no further feedback on this - I think it's ready to go.

wim leers’s picture

Assigned: Unassigned » wim leers

I'd like to do the final pass on this; this is the most important/impactful MR of the month AFAICT!

wim leers’s picture

Assigned: wim leers » Unassigned

Please don't think I'm downplaying the quality of this MR. This MR is a huge leap forward! 🤩🥳 But in doing so, I wanted to make sure we kept our eyes aimed at a tighter API surface, a more precise definition of how XB works with components coming from various sources, etc. Because #3499919: [Meta] Plan for in-browser code components is being worked on right now, and will introduce a third component type very soon!

All subsequent refactoring for which this MR surfaces the necessity:

  1. #3493941: Maintain a per-component set of prop expressions/sources
  2. #3500997: Move SDC-specific validation in ValidComponentTreeConstraintValidator and ComponentTreeMeetsRequirementsConstraintValidator into the SDC source pluginhttps://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
  3. #3501281: Reconcile date format handling between client-side transforms and server-side's Evaluator
  4. #3501290: Introduce unit test coverage for both ComponentSource plugins (Block + SDC)
  5. #3500994: Remove references to 'props' outside of SDC - use 'inputs' instead — should also update all references to component prop in /docs/*, and possibly also mark ADR#2 as superseded and write a new one. This issue did the heavy lifting, but without that rename, all docs will remain confusing anyway.

  • wim leers committed 745e4fc4 on 0.x authored by longwave
    Issue #3491978 by larowlan, longwave, wim leers: Implement saving block...
wim leers’s picture

Status: Reviewed & tested by the community » Fixed
wim leers’s picture

Note that most of the issues at the bottom of #27 are essentially a subset of what we'll need for #3467954 — see #3467954-55: META: Evolve XB UI's data model to allow non-SDC components' inputs, DynamicPropSource support, etc. for an overview of what AFAICT are the immediate next steps. — nope, that issue is for the client-side data model, #27 is focused on the server-side data model not being coupled to SDC!

I'll work on bringing clarity to this.

wim leers’s picture

@longwave and I discussed this, and we recalled that #3500152-3: Remove InputBehaviorsBlockSettingsForm and consolidate with input components form is the one he identified as a critical refactoring to pave the path for #3499919: [Meta] Plan for in-browser code components.

larowlan’s picture

wim leers’s picture

Fixed :)

effulgentsia’s picture

Issue tags: -sprint

Status: Fixed » Closed (fixed)

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