Cross-cutting · Multi-language content authoring
Every customer-facing entity carries a per-language record for its translatable fields, and the editors expose languages as wizard steps — the default language marked with an asterisk — so content is authored once per language in the same form.
| Area | Cross-cutting |
| Routes | cms.proposals.new · cms.categories.new · cms.mofs.index · marketing.campaigns.new · marketing.activity-campaigns.new · cms.multicentre-proposals.new · configuration.centers.new · crm.commerces.new · configuration.extra-attributes.new |
| Centre modules | always available |
| Staff levels | as per the host screen |
| Models | language |
| UI label | error.all-translation-fields.required |
| Coverage | 4 use cases · 1 happy · 4 failure |
Known issues (1)
- 🟠 Medium — Secondary-language content is not enforced
How it works
Nine *-language models exist (proposal, category, mof, campaign, activity-campaign, center, commerce, extra and multicentre), all keyed on the centre’s configured languages with one marked default. The campaign editor’s steps getter is the clearest example: it sorts languages with the default first and appends * to its label. Enforcement is inconsistent — the multicentre-proposal editor checks every language before submitting and blocks with error.all-translation-fields.required, while most other editors only validate the default language, so a proposal can be published with an untranslated secondary language. The centre form also supports bulk uploadTranslations.
Use cases
Why someone opens this (4)
- A bilingual centre publishing a proposal in both languages from one form.
- Adding a third language to an existing centre and filling in the gaps.
- Bulk-uploading a translation file instead of editing strings one by one.
- Making sure a group-wide multicentre proposal is complete in every language before it goes out.
Path map
flowchart LR F(["Multi-language content authoring"]):::feat F --> H1["Proposal authored in two languages"]:::ok F -.-> X1["Incomplete translations enforced"]:::bad F -.-> X2["Incomplete translations unenforced"]:::bad F -.-> X3["Translation upload fails"]:::bad F -.-> X4["Default language not set"]:::bad classDef feat fill:#8c5a3c,stroke:#8c5a3c,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Proposal authored in two languages
- Centre has two languages configured, one default.
- User fills the default-language step (marked
*) and then the second step.- The
*-languagerecords are saved alongside the entity.- The app serves each user the content for their language.
Failure paths
Incomplete translations (enforced)
Cause — A language missing a translatable field on a multicentre proposal.
What happens —
_validateProposalTranslationFieldsblocks submit witherror.all-translation-fields.required.
Incomplete translations (unenforced)
Cause — A secondary language left blank on an ordinary proposal, campaign or category.
What happens — Not validated — the record saves and the app falls back or shows an empty field. The most consequential inconsistency in this area.
Translation upload fails
Cause — Malformed locale file on the centre form.
What happens —
try/catch (err)with no translated message.
Default language not set
Cause — Centre saved without
defaultLanguage.What happens — Blocked by the centre model’s presence rule with
required+configuration.center.default-language.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Proposal authored in two languages
- ⛔ Incomplete translations (enforced)
- ⛔ Incomplete translations (unenforced)
- ⛔ Translation upload fails
- ⛔ Default language not set
Implementation
app/models/proposal-language.jsapp/models/category-language.jsapp/models/mof-language.jsapp/models/campaign-language.jsapp/models/activity-campaign-language.jsapp/models/center-language.jsapp/models/commerce-language.jsapp/models/extra-language.jsapp/models/language.jsapp/components/nf-wizard.jsapp/components/nf-wizard-tab.js
Translation keys (3)
Key English error.all-translation-fields.requiredAll translatable fields must be translate configuration.center.languageLanguage configuration.center.default-languageDefault language
Related
- Same area — CSV import engine · Data export engine (email delivery) · Filter & segment builder component · File upload, gallery & image modal · Realtime updates (Pusher) · Role & module permission layer · Error presentation & API error mapping · Product analytics & error monitoring
- Shares data with — Store create & edit · Activity editor (loyalty mechanics, rules & targeting) · Activity campaigns (programme grouping) · Proposal list & publication workflow · Proposal editor (content, coupon, push, AI images) · App button manager (MOFs) · Multicentre proposals · Centre editor (modules, app config, integrations)
Generated from doc/feature-inventory.json · id xc-multilanguage · commit 276788ca6