[Needs design] Library confusingly lists SDC-sourced and Block-sourced Components together

Created on 9 January 2025, 3 months ago

Overview

Quoting @effulgentsia:

XB's current UI of SDCs and Blocks appearing in the same list in the Library panel is confusing. We'll be implementing an improvement to this that separates them into different lists. However, until then, we'd like to limit demo_mode to only SDCs.

โ€” ๐Ÿ“Œ When demo_mode, limit component list to only SDCs, not blocks Active

This issue aims to solve that, to lift the restriction that that issue added.

Proposed resolution

TBD โ€” perhaps designs exist already? If so: please update the title + remove the tag and link to it ๐Ÿ™

User interface changes

TBD

๐Ÿ“Œ Task
Status

Active

Version

0.0

Component

Page builder

Created by

๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

Live updates comments and jobs are added and updated live.
  • Usability

    Makes Drupal easier to use. Preferred over UX, D7UX, etc.

  • Needs screenshots

    The change alters the user interface, so before and after screenshots should be added to document the UI change. Make sure to capture the relevant region only. Use a tool such as Aviary on Windows or Skitch on Mac OS X.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @wim leers
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    See, I knew I vaguely recalled seeing that somewhere! ๐Ÿ˜„ Had no idea how to find it. Thanks, @lauriii! ๐Ÿ™

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom longwave UK

    Ah that makes sense but I also think that all these component listings/groupings should be 100% controllable from the server side, we shouldn't have any hardcoded restrictions - we should be flexible in allowing developers to customise the XB UI from PHP wherever possible. This means that even if the library and top bar have groupings (like the Sections/Components split we have at the moment), the number/names of those groups should be sent from the server.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    This means that even if the library and top bar have groupings (like the Sections/Components split we have at the moment), the number/names of those groups should be sent from the server.

    Agree ๐Ÿ’ฏ, this is the same sort of thing I was trying to say in ๐Ÿ“Œ Implement saving block settings forms Active but I think you've said it better with

    we should be flexible in allowing developers to customise the XB UI from PHP wherever possible

    - ๐Ÿ™Œ

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    @effulgentsia asked me if I have thoughts on how to split up the server-side vs client-side responsibilities here and design the API between them.

    I think this is where having an OpenAPI spec comes in handy. We can use that as the discussion point. I'll open an MR with some changes to demonstrate what @longwave is articulating in #4

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    Proposed a change to the API spec for the components controller that should power this.

    If we agree with this approach we can move to implementation

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom longwave UK

    Some nitpicks but the proposal looks good to me in principle.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL

    I took a stab at writing a more descriptive title based on where the conversation went.

    Also, I thought it might be helpful to be aware that the designs for code components ( ๐ŸŒฑ [Meta] Plan for code components Active ) introduce the term, group. See โœจ Component groups for code components Postponed . Those are what we previously named category in ๐Ÿ“Œ Define built-in components and categorization for components Postponed . We may want to resolve that mismatch first before we choose the property name here. I would vote for renaming groups to categories in the code components world.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #6++ โ€” nice work, @larowlan!

    I find both and fairly confusing. I tried to think out of the box. Thoughts on https://git.drupalcode.org/project/experience_builder/-/merge_requests/5... ?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    During a recent retrospective, the XB team identified that in addition to having a "sprint" tag, it would be helpful to have a short list of other issues that would be the most valuable to work on if/when the ones in the current sprint are all blocked or being worked on by someone else or are outside of someone's area of expertise. I'm going with "sprint candidate" as the tag for that. Often, this will be issues that are likely to be part of the next sprint, so getting them done (or at least started) early would be fantastic.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    By the way, it's not clear to what the different UI locations would be?

    Is it

                          components:
                            label: Components
                            position: library
                            icon: Component1
                            weight: 1
                          global_components:
                            label: Dynamic Components
                            position: header
                            icon: File
                            weight: 2
    

    as in the current MR? i.e. "Components" or "Dynamic Components", nothing else?

    @larowlan says that @effulgentsia pointed out we also need "Extensions", but โ€ฆ extensions don't come from Component config entities nor ComponentSource plugins, so how does that connect?

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    ๐Ÿ“Œ Create extendibility proof of concept that also serves as documentation-by-example Active landed yesterday, but it doesn't yet expose that demo extension through the top bar: that still contains a hardcoded list of extensions.

    The title of this issue is about component sources, but perhaps it's really about populating the entire XB UI top bar menu from the server side? ๐Ÿค”

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    @larowlan says that @effulgentsia pointed out we also need "Extensions", but โ€ฆ extensions don't come from Component config entities nor ComponentSource plugins, so how does that connect?

    I believe this would be referring to the fact that extensions panel will show module provided components in future:

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Ahhhh! Okay, that's way simpler ๐Ÿ˜„

    @effulgentsia, can you confirm #17? ๐Ÿ™

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    I know I've written this somewhere but I can't find it anywhere so I'm writing this again here for context. The different places where components will appear in the UI are the following:

    1. Elements: Provided by Experience Builder
    2. Extensions: Provided by Modules
    3. Dynamic Components: Blocks
    4. Library: SDCs from the Active Theme + JavaScript Code Components

    Each of these UIs have categorization within that category for its components. Here are few screenshots of how these might look like:

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    For terminology, I propose library instead of list. In other words, per #19, we'll have 4 libraries:

    1. ID=elements, label=Elements
    2. ID=extension_components, label=Components
    3. ID=dynamic_components, label="Dynamic Components"
    4. ID=primary_components, label=Components

    Note that per above two different libraries can have the same label. #1 in the above list won't be in XB 1.0: that will come later when a visual component builder gets worked on.

    If we follow the metaphor of Library, as in buildings with books, then libraries don't have positions, they have locations, so I also propose renaming what this MR calls position to location. This would then allow weight to be renamed to position.

    Now here's where things get tricky...

    On a superficial level, there are two locations: the left and the top. Continuing the metaphor with brick-and-mortar libraries, we can think of this as the main library (on the left) and satellite libraries (on the top). The area in the top bar for these satellite libraries is called tools ๐Ÿ“Œ Define the 3 areas the Top Bar will provide Active . So the above could be conceptualized as:

    1. ID=elements, label=Elements, location=tools, position=0
    2. ID=extension_components, label=Components, location=tools, position=1
    3. ID=dynamic_components, label="Dynamic Components", location=tools, position=2
    4. ID=primary_components, label=Components, location=main

    On the surface, the above seems really good in terms of meeting the goals of comment #4: it would allow PHP code to add more libraries to the Tools area and have them show up without needing any change to the React code.

    However, the are two problem with this approach:

    • The UX will need to intersperse other things that aren't component libraries in the Tools area. For example, we'll want a menu for managing Text styles, and we'll want this menu to be to the right of the Elements library and to the left of the Extensions library. Perhaps we could solve this by assigning documented position values for these non-library tools? So, for example, if we assign Text Styles as position=100, then #2 and #3 in the above list could be changed to position=101 and position=102.
    • Within the Extensions menu, there are other things besides the extension_components library. For example, there's also plugins. This probably makes extensions an entirely separate location from tools, since we don't want to place the extension_components library directly in the tools area, but rather inside the Extensions menu that's within the Tools area.

    So that then leaves us with:

    1. ID=elements, label=Elements, location=tools, position=0
    2. ID=extension_components, label=Components, location=extensions
    3. ID=dynamic_components, label="Dynamic Components", location=tools, position=201
    4. ID=primary_components, label=Components, location=main

    With the above, how much value are we even gaining from #1 and #3 being in the same location, if we need out-of-band knowledge about the position values? Would it be more robust to do:

    1. ID=elements, label=Elements, location=elements
    2. ID=extension_components, label=Components, location=extensions
    3. ID=dynamic_components, label="Dynamic Components", location=dynamic_components
    4. ID=primary_components, label=Components, location=main

    But if we do the above, then we're down to a 1:1 relationship between library and location, which means we don't need location at all. We could go back to:

    1. ID=elements, label=Elements
    2. ID=extension_components, label=Components
    3. ID=dynamic_components, label="Dynamic Components"
    4. ID=primary_components, label=Components

    and have the React UI hard-code where each library ID goes. Which I think is what makes the most sense given the UX we want, but it would remove the flexibility desired in comment #4.

    @larowlan, @longwave: Since you were the two most wanting greater flexibility, what are your thoughts on this?

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    I feel pretty strongly that it would be better to be opinionated on the libraries and not allow individual sites to meddle with these. From users perspective, there's a lot of value in having consistency how these are presented to them. For example, this allows us to provide documentation and video materials that are actually meaningful to the end user. If we identify other common needs, we could easily add backend / UI support for additional libraries even if XB doesn't add anything to those libraries by default.

  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    I think #20 is ok, somewhere I saw @lauriii say having it consistent means we can record generic training videos, so that makes sense.

    I think the original goal was to allow modules to have a say in all of this. But I think so long as they can put things in the extensions drawer, that need is met.

    So plus one for moving ahead with #20/ #21

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom longwave UK

    If we're going to hardcode the locations would we also be hardcoding the labels? I'm not sure I see the benefit of adding flexibility for the four labels, we might as well just send only the library ID for each component then we need no metadata at all about the libraries themselves. Users could still relabel them through translations if they really wanted to.

    I still think contrib or custom implementations of XB might want to add additional icons in the top bar, or regroup things in their own way, but perhaps for 1.0 we just disallow that until we have a good use case for it.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom f.mazeikis Brighton

    f.mazeikis โ†’ made their first commit to this issueโ€™s fork.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom f.mazeikis Brighton
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I just asked @lauriii whether module-provided SDCs belong in the bucket he mentioned in #19 (or @effulgentsia's extension_components equivalent in #20). The answer is .

    So that means this is AFAICT the decision tree:

    1. Is the component dynamic (consumes implicit inputs/context or has logic)?
    YES โ‡’ dynamic_components
    NO: Go to 2.
    
    2. Is the component provided by a module?
    YES โ‡’ Go to 2.B
    NO โ‡’ Go to 3.
    
    2.B I the providing module XB?
    YES โ‡’ elements
    NOโ‡’ extension_components
    
    Fallback: โ‡’ primary_components
    
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    This is almost correct. The library should show components only from the active theme. This is different from the current functionality where itโ€™s showing components from all themes. Based on this, the decision tree would be:

    1. Is the component dynamic (consumes implicit inputs/context or has logic)?
    YES โ‡’ dynamic_components
    NO: Go to 2.
    
    2. Is the component provided by a module?
    YES โ‡’ Go to 2.B
    NO โ‡’ Go to 3.
    
    2.B I the providing module XB?
    YES โ‡’ elements
    NOโ‡’ extension_components
    
    3. Is the component provided by the active theme (or its base theme)?
    YES โ‡’ primary_components
    
    Fallback: โ‡’ Component not listed in XB.
    
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #27 doesn't account for "code components" ( ๐ŸŒฑ [Meta] Plan for code components Active ). For those, it's not provided by an extension (module/theme), but by config.

    1. Is the component dynamic (consumes implicit inputs/context or has logic)?
    YES โ‡’ dynamic_components
    NO: Go to 2.
    
    2. Is the component provided by a module?
    YES โ‡’ Go to 2.B
    NO โ‡’ Go to 3.
    
    2.B I the providing module XB?
    YES โ‡’ elements
    NOโ‡’ extension_components
    
    3. Is the component provided by the default theme (or its base theme)?
    YES โ‡’ primary_components
    NO โ‡’ Go to 4.
    
    4. Is the component provided by neither a theme nor a module?
    YES โ‡’ primary_components
    
    Fallback: โ‡’ Component not listed in XB.
    

    Question 4 accounts for that now. ๐Ÿ‘

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Given the decision tree in #27, I think we've got some serious changes to make:

    1. I keep forgetting that the ComponentSource plugin is instantiated per Component config entity! ๐Ÿ˜ฌ

      That's why @f.mazeikis' SingleDirectoryComponent::getLibraryId() implements this correctly ๐Ÿ‘.

      But still, the fundamental problem remains: we want all future component sources to also respect this, and we know this is likely to evolve over time. That'd require all those plugins to be updated; leaving XB product owners less in control over the cohesiveness of the UX.

    2. is not a thing we currently do: neither in HEAD, nor in this MR. I'm fine with it not yet happening here to keep scope tight, but we need to think through the consequences of the current implementation to make it possible.

      Over at ๐Ÿ› Library includes components/blocks that have been disabled Active earlier today, we made it so that the server-side list of Components is the complete set of everything discovered on the site (including ones that are either automatically or manually disabled aka get their status set to false), but the client only receives the relevant subset: the enabled ones.

      This seems different-but-similar: /xb/api/config/component should now only return those Components which belong in one of the 4 libraries, according to the decision tree. (And still only the enabled ones, of course.)

      Loading all Component config entities and instantiating their corresponding ComponentSource plugin is very expensive. Although โ€ฆ right now it doesn't seem to be making a significant difference in my local dev env (HEAD vs current MR). But it definitely eventually will.

    3. โš ๏ธ Changing the default theme (system.theme config's default key-value pair) should then immediately result in the set of components available in the XB UI changing! (Which again is the controller for /xb/api/config/component).
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    BTW, nice, OpenAPI validation has been catching the fact that not all responses contain the necessary library info:

    Body does not match schema for content-type "application/json" for Response [get /xb/api/config/component 200]. [Keyword validation failed: Value must be present in the enum in sdc.olivero.teaser->library]
    

    ๐Ÿ‘

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    To fully address #29, we would need:

    • to query across all Component config entities to find only the relevant ones to return to the client WITHOUT having to instantiate them (both the config entity and the associated source).
    • upon changing the default theme, all affected Component config entities must have their library re-assessed
    • ideally, we'd apply the decision tree in #27 automatically. So then we need to automatically and efficiently be able to answer each of the 5 questions (1, 2, 2.B, 3 and 4 in #28). Let's try:
      1. โŒ Impossible today: we lack this metadata.
        โœ… Easily added though: add a boolean key-value pair to \Drupal\experience_builder\Attribute\ComponentSource, which then every source defines. Every Component config entity already stores its source. From there, it's trivial to map it to the appropriate boolean value.
        โ†’ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...
      2. โŒ Impossible today: we lack this metadata.
        โœ… Easily added though: a new required provider property on the Component config entity, that all component sources must populate.
        โ†’ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...

    Then we can use this metadata in the config entity query โ€ฆ and bam, future performance disaster averted!
    โ†’ https://git.drupalcode.org/project/experience_builder/-/merge_requests/5...

    Still remaining to be done: move the computing of the library ID elsewhere.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I'll tackle

    Still remaining to be done: move the computing of the library ID elsewhere.

    because my head is still in this space from last night. Will assign to @f.mazeikis for review afterwards.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Green! ๐Ÿฅณ That means my proposal in #31 turned out to be viable ๐Ÿ˜Š

    Overhauled the issue summary based on @lauriii's #19, @effulgentsia's #20 and my decision tree in #28, which @lauriii +1'd.
    I also already updated the docs.

    And for the last nice bit: query cacheability.

    Back to @f.mazeikis for reviewing what I changed โ€” note that @f.mazeikis' original SingleDirectoryComponent::getLibraryId() is still present, but now is fully generalized, and fully implements #28's decision tree.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    @f.mazeikis approved, so I'm assuming that means he's happy with the #29 + #31 pivot ๐Ÿ˜Š

  • Pipeline finished with Skipped
    about 1 month ago
    #430778
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia nagwani
  • Status changed to Fixed 15 days ago
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024