Overview

follow-up to #3534989: Error if the user tries to publish Code Component without the Global CSS and #3530493: Create UI for selective publishing or discarding of changes

#3530493: Create UI for selective publishing or discarding of changes introduced the problem that you could publish a code component without publishing the global CSS asset. This is a problem because the tailwind classes for the component are saved in the global CSS asset. This can cause problem because the component might not be styled correctly.

In #3534989: Error if the user tries to publish Code Component without the Global CSS added error so the user would just be prompt to select it.

But @laurii suggested

Could we do two things:
Force publishing Global CSS when publishing a component
Automatically select Global CSS in the list when publishing changes to a component

Proposed resolution

determine how we want to handle it

User interface changes

Comments

tedbow created an issue. See original summary.

wim leers’s picture

IMHO we should make the global asset library an enforced config dependency of every code component.

And then use that metadata in the auto-save publish logic, something like:

$all_entities_in_auto_save = $this->autoSaveManager->…
$dependencies_in_auto_save = [];
foreach ($selected_entities_to_publish_in_auto_save as $entity) {
  $dependencies_not_yet_being_published = array_diff($entity->getDependencies(), $selected_entities_to_publish_in_auto_save);
  $dependencies_in_auto_save = [
    ...$dependencies_in_auto_save,
    ...array_intersect($dependencies_not_yet_being_published, $all_entities_in_auto_save),
  ];
}
\Drupal::messenger('You did not select these entities to publish, but they are dependencies of other entities you published, so XB did that for you: %list.");

WDYT?

wim leers’s picture

Assigned: Unassigned » balintbrews

… alternatively: I don't know enough about Tailwind compilation needs, but … would it be possible to make each code component have one AssetLibrary of its own? Then it won't be necessary anymore for N concurrently edited code components to all write to the single global AssetLibrary, and we avoid the race condition, and would completely sidestep this usability challenge, too.

I bet there's a concern about code duplication, and that's why it's in the global? 🤔 Please enlighten me how the Tailwind compilation process works 😊🙏

balintbrews’s picture

#3: That would conceptually take us back to what we had before #3516390: Compile Tailwind CSS globally for code components. You're right, one of the concerns was code duplication. The linked issue's summary is probably worth a read. Tailwind is designed to produce a single CSS asset after scanning any markup that can contain Tailwind utility classes. I suggest we keep this issue focused on the incremental UI change that's proposed. We may need to make bigger changes to the whole process, especially if we want to solve concurrent editing of even different code components, which is something I just realized could pose a problem given the solution we landed in #3516390: Compile Tailwind CSS globally for code components.

balintbrews’s picture

Assigned: balintbrews » Unassigned
wim leers’s picture

We may need to make bigger changes to the whole process, especially if we want to solve concurrent editing of even different code components

💯 — that's what @tedbow and I have been saying.

I read that issue summary. But there's not information in there for me (somebody with zero Tailwind knowledge) to understand the technical details and hence the rationale. Also because the 3-point proposed solution only talks about what's been discussed/proposed, not what was finally implemented.

However, everything in that second point in the proposed resolution does sound like going from 1 to N asset libraries would work fine, with one important tweak to what I wrote above: create one asset library per "Tailwind class name candidate". Which is already the thing being used for deduplication, it's just that that deduplication is currently handled 100% client-side, with write contention on a single resource (the global AssetLibrary).

Let's extrapolate what moving the deduplication from the client side (N → 1 server-stored resource => race condition) to the server side (N -> N server-stored resources => no race condition) this would look like:

  1. We would introduce more asset libraries …So let's name these AssetLibrary config entities _xb_tailwind_*, with * the "Tailwind class name candidates". This would then result in asset libraries experience_builder/asset_library._xb_tailwind_* existing.
  2. Each code component already maintains (stored in source_js) a list of Tailwind class name candidates it needs. That means the JavaScriptComponent config entity can use that information to automatically compute the asset libraries it depends on.
  3. That would mean that the code component hopping_bunny's asset library (experience_builder/astro_island.hopping_bunny) would have get a dependency on:
    1. experience_builder/asset_library._xb_tailwind_FOO
    2. experience_builder/asset_library._xb_tailwind_BAR
  4. And another code component teething_baby's asset library (experience_builder/astro_island.teething_baby) would have get a dependency on:
    1. experience_builder/asset_library._xb_tailwind_BAR
    2. experience_builder/asset_library._xb_tailwind_BAZ
  5. Then, when rendering this component, it would automatically mean that the duplication between the two components (both use the BAR "Tailwind class name candidate") is optimized away by Drupal's asset library system.

If I misinterpreted the pretty high-level Tailwind information in #3516390's issue summary how this actually works, please point out where in that <ol> I went wrong 🙈

balintbrews’s picture

I think we should decide if we want to do the UX improvement in this issue on top of what was done in #3534989: Error if the user tries to publish Code Component without the Global CSS. I think we do, it's a relatively quick incremental change.

Then there's the question of how to potentially re-architect what was done in #3516390: Compile Tailwind CSS globally for code components to support concurrent editing of code components. That's a much bigger scope and discussion in my opinion, and I may prefer to do that after we managed to do the beta release. #6 will definitely be a good starting point for it.

wim leers’s picture

Title: Auto select or publish Global CSS asset when needed to publish JS Code Components » Auto-select or publish global Asset Library when needed to publish Code Components
Component: … to be triaged » Auto-save
Category: Bug report » Task
Issue tags: +Usability

I see. I guess I kinda derailed this issue. 🙈 But it is related, and AFAICT no dedicated issue exists for it?

Happy for the original scope to just land and to have the relevant info for the re-architecting to be surfaced elsewhere 👍

Project: Experience Builder » Drupal Canvas
Version: 0.x-dev » 1.x-dev

Experience Builder has been renamed to Drupal Canvas in preparation for its beta release. You can now track issues on the new project page.