Only allow deleting Code Components if there's 0 usages

Created on 13 June 2025, about 2 months ago

Overview

Quoting @catch and I from #3528723-10: Component::onDependencyRemoval() should be an uninstall validator if the dependency being removed is a module or theme :

Reviewed this together with @catch.

The behavior in HEAD is that a code component (JavaScriptComponent) that is in use in e.g. 1 article and 1 page can still be deleted. It requires a little bit of shenanigans though: you have to open a content entity in XB that does not contain an instance of that code component!

If such an instance is present, you do get a nice error message/confirmation dialog:

On all other content entities (i.e. any with an XB component tree but without this particular code component), the deletion will proceed unceremoniously 😅 ⇒ It's far too easy to shoot yourself in the foot right now!

The changes in this MR remove the "shoot yourself in the foot" case for:

  • uninstalling modules providing block plugins
  • uninstalling themes/modules providing SDCs

👍

BUT concerns remain regarding code components — because this MR doesn't change anything (intentionally!) for those.

@catch and I agreed that:

  1. A confirmation dialog like the above should ALWAYS appear
  2. It should inform the user of how many entities/revisions would be impacted
  3. It should inform the user that if they proceed all existing content will look broken.

IOW: allow it only for developers who really know what they're doing, but present the consequences as explicitly as possible.

This strikes the middle ground of desire for reliability+consistency (@catch and I) vs pragmaticness when developing code components (@lauriii's concern).

In the future, if Drupal core gets a "developer mode", we could adjust the behavior based on that — see Add a Production/Development Toggle To Core Needs work .

+

After some more brainstorming with @catch, we think we thought of an alternative approach that actually is better still:

  1. add a soft_deleted: true|false config entity property to JavaScriptComponent, which defaults to false
  2. make the delete operation either:
    1. : actually delete (as is the case today)
    2. : set soft_deleted: true (🆕)
  3. make XB in all its API responses pretend this config entity does not exist
  4. … then just respect all config dependency management as per usual

This approach would mean that the associated Component config entity would still exist, the JS code-on-disk powering it would also still exist, and hence all existing usages of this code component would continue to work exactly as before.

P.S.: yet another alternative approach could be that we make JavaScriptComponent implement VersionedConfigEntityInterface (new since ~2 weeks) to keep the underlying config entity around, and only allow 2 versions: whichever one is the active one, plus a special deleted/trashed version that gets treated everywhere in XB as if it doesn't exist. That way, we would not have to delete

Proposed resolution

Discuss the nuances, but prevent the deleting JavaScriptComponent config entities to comply with config management best practices. We now have usage data, versioned config entity types, etc. — multiple additional pieces of infrastructure that should enable a better UX.

User interface changes

📌 Task
Status

Active

Version

0.0

Component

Theme 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.

Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024