Issue #3621026: Add, edit and delete tenants from the Tenants list

Gives the tenant entity type the forms it never had.

orchestra_tenant declared only a collection link, so the Tenants list reached the per-tenant Retention and Reading forms and nothing else. A realm could arrive only with a config import, a custom module, a recipe or core's single-item import form; its label could be changed only the same way; and removing one meant drush config:delete, which writes to configuration directly. Nothing carries a raw config write back to the entity system, so that command skips OrchestraTenantHooks entirely: the realm's instances, tokens, variables, incidents and scoped workflows are left behind with no tenant to belong to, and drush config:delete orchestra.tenant.default walks past the access handler, the list builder and the predelete guard alike.

So: add-form, edit-form and delete-form links, their routes, a TenantForm for the label, the machine name and the weight, a TenantDeleteForm, and an Add tenant action on the collection.

Two details worth reading:

  • The machine name is offered once and disabled afterwards. Instances, tokens, variables and workflows are stamped with it rather than referencing the tenant, so a renamed tenant would leave everything it owns behind under the old name.
  • The delete route takes _entity_access: orchestra_tenant.delete rather than the _permission its neighbours take, so the access handler's refusal of the default tenant is what answers. With a permission check the form would open for it and fail on submit, inside the predelete guard.

The confirmation counts what it would remove, from the same queries the cascade runs: the process instances in the realm, with their tokens, variables and incidents, and the workflows scoped to it. An empty realm says so instead of counting nothing. The sentence about the action not being undoable comes from the parent rather than being written again, because the site keeps one string table and a second copy of a core string in this catalog would fight core's translation of it.

docs/multi-tenancy.md gains a Managing tenants section, including the drush config:delete caveat, and the thirteen new strings are in translations/fr.po.

Tests

TenantFormTest drives the real forms through the form builder, pressing the action button the way a person does, since an entity form hangs save() and delete() on that button and a submission naming none validates and then does nothing.

  • The add form creates the tenant with its label and weight; the edit form renames it and offers the machine name disabled.
  • The delete confirmation counts two instances and one workflow on a site where a second tenant holds runs of its own, and deletes only the tenant it names.
  • An empty tenant's confirmation says nothing runs in it.
  • The collection carries the add action, asked of the local action manager, since the testing profile renders no action links.

Each was seen to fail without the code: removing getDescription() fails the two confirmation tests, and removing orchestra.links.action.yml fails the action test.

Note for #3621006

That issue's MR touches the same documentation page and says the Tenants list has no form to add or remove one, which stops being true here. Whichever of the two lands second needs that sentence dropped in the rebase.

Merge request reports

Loading