configUi editors cannot follow the dashboard language: config:value carries no locale and an untranslated schema #1522
Replies: 2 comments
|
Implemented in #1711, as proposed here: Thanks for the precise write-up; it made the change a four-line one. |
|
Status update: this shipped in v0.24.0, released today. The |
Uh oh!
There was an error while loading. Please reload this page.
configUi editors cannot follow the dashboard language
config:valuecarries no locale, and the schema it sends is the untranslated oneSummary
A plugin that ships a
configUieditor has no way to know which language the dashboardis in, and receives the raw
configSchemarather than the localized one. The resultis an editor stuck in whatever language its author hard-coded — or, at best, guessing from
navigator.language, which is a different thing from the dashboard's setting.This is the same class of problem that
themesolved in #860, and the fix has the sameshape: send it with the handshake.
What happens today
The handshake sends three fields (
dashboard/src/pages/Plugins.tsx, L318–L323):Meanwhile the dashboard localizes everywhere else.
localizePlugin(plugin, i18n.language)(
dashboard/src/utils/localizePlugin.ts) translatesname,descriptionand everyconfigSchema.properties[key].title/.descriptionfrom the manifesti18nblock, andthe generated form uses it (
Plugins.tsx, L1275):So the two config surfaces disagree: the generated form follows the dashboard language,
the
configUiiframe cannot.docs/19-plugin-architecture.mdstates the currentintent plainly —
i18nis "Localized dashboard text per locale (dashboard-only)" — butfor a plugin with a custom editor that means its
i18nblock has no effect at all on thefields the operator actually sees.
Why an editor cannot work around it
The iframe is
sandbox="allow-scripts"withoutallow-same-origin, so it has an opaqueorigin. It therefore cannot:
localStorage(whereopenwa_languagelives) — access throwsSecurityError, and even if it did not, storage is partitioned per origin and theiframe's is
null;What is left is
navigator.language. That is not arbitrary — it is the same fallbackthe dashboard itself uses (
order: ['localStorage', 'navigator']indashboard/src/i18n/index.ts) — so it agrees with the dashboard in every case exceptthe one that matters: an operator who explicitly picked a language different from their
browser's. Which is exactly what someone does when they change the dashboard to English.
The only remaining workaround is a per-plugin language setting in the plugin's own config:
a second place to set something the dashboard already knows, and one the operator has no
reason to expect.
The precedent
themewas added for exactly this reason, and the comment abovePluginConfigUi(
Plugins.tsx, L245–L248) already makes the argument:Replace "theme" with "language" and the paragraph still holds.
Proposed change
Two additions in the handshake:
post({ type: 'config:value', config: configUiSafeConfig(plugin, sessionId), - schema: plugin.configSchema, + schema: localizePlugin(plugin, i18n.language).configSchema, theme: resolvedTheme, + locale: i18n.language, });localizePluginis already imported in that file, and the localized schema is alreadycomputed a few lines away for the generated form.
Two notes on the shape:
localeand the localized schema are both needed. The schema covers field titlesand descriptions;
localecovers the editor's own strings — tab labels, buttons,validation messages — which no schema can carry.
theme:the language control sits behind the modal overlay, so it cannot change while an editor
is open, and reopening re-runs the handshake. (If a live switch is ever wanted, an
additional
config:localemessage would be the natural extension.)Compatibility
Additive on both counts. An editor that ignores
localebehaves exactly as before. Alocalized schema changes only
titleanddescription— the same fields the generatedform already renders from — and falls back to the untranslated values for any plugin
without an
i18nblock, sincelocalizePluginreturns the plugin unchanged when there isno matching override.
Impact
Every plugin with a
configUiis affected, not only ours: today none of them can honourthe dashboard's language, and any
i18nblock they ship is silently ignored for thefields the operator edits. Ours (an Odoo Helpdesk bridge) ships Italian and English and
currently has to expose its own language selector to work around this — which is the part
that feels wrong, since the dashboard already knows the answer.
All reactions