Big Picture: act on the locale the host asks for, not just carry it
A host embedding this dashboard with profile-config {"locale":"ar"} got an
entirely English page. The config was threaded correctly and reached the
children; nothing ever turned it into an i18n locale.
WHY THIS COMPOSITE AND NOT ITS SIBLING, which passes the same gate untouched.
Simple Research mounts its children BY TAG, so every child is its own custom
element with its own ProfileLoader — and ProfileLoader is the only thing in the
tree that watches `config.locale || config.lang` and drives the i18n locale from
it. Big Picture BAKES its children in (it imports the .vue files), so there is
no loader anywhere beneath it and nobody was doing that job. The entry does
provide appI18n; it was simply never told which language to use.
So this composite now does what ProfileLoader does for the other one: inject the
i18n instance and drive its locale from the host's lang/locale.
MEASURED with check:host-locale-contract, before and after:
dashboard-plus-grid host 0 of 2121 -> host 32 of 2121
32, not 2121, and the remaining gap has a single known cause: most of this
dashboard's chrome is read through tStatic, which resolves the locale from the
URL and the document and cannot see a locale set at runtime. That fix lives in
library/i18n/index.js, is measured, and is parked behind another agent's landing
in the same file — the measurement also showed it must be backed by a
window-level store rather than module state, because a composite loads several
bundles and each carries its own copy of that module.
This commit is contained in:
parent
d78a42f2df
commit
12b66a9852
7 changed files with 59 additions and 39 deletions
|
|
@ -13,7 +13,7 @@
|
|||
* Same "import the REAL components, no fork" discipline as big-picture: the grid is the exact
|
||||
* people-groups-grid component; the dashboard is the exact research-dashboard component.
|
||||
*/
|
||||
import { reactive, provide, ref, computed } from 'vue'
|
||||
import { reactive, provide, inject, ref, computed, watchEffect } from 'vue'
|
||||
import { SUPPORTED_LOCALES } from '@map/i18n/index.js'
|
||||
import { resolveEmbedBase } from '@map/utils/embedBase.js'
|
||||
import { useSharedMapToken, publishMapToken } from '@map/composables/useSharedMapToken.js'
|
||||
|
|
@ -268,6 +268,14 @@ const hostProvider = computed(() => {
|
|||
// provider holes, and the same shape of defect — a knob the snippet documents, read by nobody.
|
||||
// The composite's OWN chrome still reads English until the i18n layer learns to follow a locale set
|
||||
// at runtime; that change is held behind another agent's landing in the same file and arrives next.
|
||||
// ★ AND SOMEBODY HAS TO ACT ON IT. This composite BAKES its children in rather than mounting them
|
||||
// by tag, so there is no ProfileLoader anywhere beneath it — and ProfileLoader is the only thing in
|
||||
// the tree that turns a config locale into an actual i18n locale (ProfileLoader.vue: it watches
|
||||
// `config.locale || config.lang` and drives appI18n.global.locale). MEASURED with studio's
|
||||
// check:host-locale-contract: this leaf answered 0 Arabic strings against a reference of 1,891 —
|
||||
// not because the catalogue was missing and not because appI18n was absent (index.js provides it),
|
||||
// but because nothing ever told it which language the host asked for. Its sibling composite passes
|
||||
// the same gate untouched, because it mounts children by tag and each child brings its own loader.
|
||||
const hostLang = computed(() => {
|
||||
const l = String(hostConfig.value?.lang || hostConfig.value?.locale || '').split('-')[0].toLowerCase()
|
||||
return SUPPORTED_LOCALES.includes(l) ? l : ''
|
||||
|
|
@ -295,6 +303,9 @@ provide('profileConfig', computed(() => ({
|
|||
...(hostLang.value ? { lang: hostLang.value } : {}),
|
||||
})))
|
||||
|
||||
const appI18n = inject('appI18n', null)
|
||||
watchEffect(() => { if (hostLang.value && appI18n) appI18n.global.locale.value = hostLang.value })
|
||||
|
||||
const sections = [
|
||||
// The research-dashboard leaf SELF-TITLES (its own DashboardTopBar renders a "Research Dashboard"
|
||||
// title bar), so a StackLayout section title here would be a DUPLICATE — the Driver saw "Research
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH" crossorigin="anonymous"></script>
|
||||
<script src="../../dashboard-plus-grid.js" integrity="sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH" crossorigin="anonymous"></script>
|
||||
<script src="../dashboard-plus-grid.js" integrity="sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
4
public/doxa-maps/doxa-maps-spa/manifest.json
generated
4
public/doxa-maps/doxa-maps-spa/manifest.json
generated
|
|
@ -215,7 +215,7 @@
|
|||
"bundle": "dashboard-plus-grid",
|
||||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"output": "doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"integrity": "sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH",
|
||||
"integrity": "sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4",
|
||||
"elements": [
|
||||
"dashboard-plus-grid"
|
||||
],
|
||||
|
|
@ -235,7 +235,7 @@
|
|||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early; remove this line if you set \"provider\":\"maplibre\" -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
"script": "<!-- Mapbox engine, fetched early; remove this line if you set \"provider\":\"maplibre\" -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
15
public/doxa-maps/index.html
generated
15
public/doxa-maps/index.html
generated
File diff suppressed because one or more lines are too long
4
public/doxa-maps/manifest.json
generated
4
public/doxa-maps/manifest.json
generated
|
|
@ -215,7 +215,7 @@
|
|||
"bundle": "dashboard-plus-grid",
|
||||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"output": "doxa-maps/dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"integrity": "sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH",
|
||||
"integrity": "sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4",
|
||||
"elements": [
|
||||
"dashboard-plus-grid"
|
||||
],
|
||||
|
|
@ -235,7 +235,7 @@
|
|||
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early; remove this line if you set \"provider\":\"maplibre\" -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-qpx82oeZ306lvi0Z8J5l/575pzWq3dVBOjHScHpKAaa0bwFTC5QUdT2iv/OQNghH\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
"script": "<!-- Mapbox engine, fetched early; remove this line if you set \"provider\":\"maplibre\" -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-X8mqyYxNYHs04jy6SWtsuHgKdvXLMcoi/gt/Jie0Z6u/E0rFS2JvLE5jjM4bokZ4\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue