The Translate tab never appears on a status, workflow or tenant, because their edit forms declare no local task

Fixes #3624957.

Config translation was never broken for these entities. The schema types each label as translatable, config_translation builds a mapper for each type, the overview route exists, and saving a French override makes the entity answer in French:

language.fr.orchestra.status.under_review: label = "En cours de revue"
$status->label()  (fr config override language)  ->  En cours de revue

What was missing was the way in. Core derives one local task per mapper with the entity's edit form as its base_route (ConfigTranslationLocalTasks::getDerivativeDefinitions()), and that derivative is present — config_translation.local_tasks:entity.orchestra_status.config_translation_overview is in the definition list. But a tab bar only renders when the base route itself carries a local task, the one that becomes the default tab. Core entity types declare it; these did not, so the derived tab had nowhere to appear.

Before: getLocalTasksForRoute('entity.orchestra_status.edit_form') returned []. After: three tabs each, the Translate tab included — plus the devel and entity_clone tabs that were also being derived with nowhere to render.

Placement follows route ownership

Entity Route owner Declaration
orchestra_tenant the engine (orchestra.routing.yml) orchestra.links.task.yml
orchestra_workflow the modeler orchestra.links.task.yml, beside the four tabs already there and with the same "renders nowhere without a modeler" consequence
orchestra_status orchestra_ui orchestra_ui.links.task.yml

The status is headless in the engine on purpose — OrchestraUiHooks::entityTypeAlter() attaches its forms, list builder and link templates — so declaring its tab beside an entity that ships without a UI would point at a route that does not exist on a headless site.

orchestra_remote is deliberately excluded: its label is an operator's name for a server they configured, read only in the remote form, two status messages and the remote list.

Test

StatusAdminRouteTest is widened rather than joined by a new class: it already installs config_translation and asserts the translate route exists, so asserting the tab reaches it is the same rule one step further.

Proven to bite by mutation:

with the fix          1/1 classes passed
tab declaration removed   0/1 classes passed
restored              1/1 classes passed

Merge request reports

Loading
Loading