Draft: Resolve "Symmetric translation: component instance version updates must propagate to all translations"

Closes #3591596

What this MR does

Makes the component instance update pipeline translation-aware. When updateComponentInstances() detects a version change and reconciles the current language's inputs, it now propagates that reconciliation to every other translation of the host entity.

Three commits, each building on the previous:

  1. Shared infrastructureTranslationInputReconciler (pure-functional reconciliation: remove orphaned inputs, add defaults for new props, preserve existing translated values) + TranslatableComponentTreeEntityInterface (entity-type-agnostic translation access) + TranslationUpdateScopeInterface (symmetric vs future asymmetric strategy).

  2. Content entitiesPage implements the interface via TranslatableComponentTreeContentEntityTrait. ComponentSourceManager::propagateToTranslations() runs after a successful update: iterates all translation languages, reconciles each, and handles auto-save conflicts (reconciliation applied on top of existing auto-saves).

  3. Config entitiesComponentTreeConfigEntityBase implements the interface via TranslatableComponentTreeConfigEntityTrait, using language config overrides. Refactors propagateToTranslations() to use the interface methods instead of content-entity-specific getTranslation(). Config entity overrides skip adding required-prop defaults (they fall back to the base config).

Testing steps

  1. Create a Page with a JS component, add a Spanish translation with translated prop values.
  2. Modify the JS component (add/remove a prop), save.
  3. Open the Page for editing — verify the Spanish translation's inputs are reconciled (new prop has default, deleted prop is gone, existing values preserved).
  4. Repeat with a ContentTemplate: create one with a translated config override, modify the component, verify the override is cleaned up.

Notes for reviewers

  • The propagateToTranslations() refactoring (commit 3) touches the content entity code path too — existing content entity tests confirm no regression.
  • shouldAddRequiredPropDefaults() was added to the scope interface because config entity overrides don't need required-prop defaults (the base config fallback provides them). The @see on the method points to where this is used.
  • docs/data-model.md section 3.5 updated with a paragraph on translation propagation.
Edited by Christian López Espínola

Merge request reports

Loading