Two labels resolved once and stayed in the boot language
upg100 measured both, and both were created by today's i18n fixes — mine and the batch's. A computed
only re-runs when a REACTIVE dependency changes; tStatic reads a plain window global. So these resolved
at first render and never moved again, while every label around them followed the switch.
· big-picture.vue — heading depended on config.value.title, which does not change when the host
changes language. It now reads hostLang, which is reactive and already drives setRuntimeLocale, and
PASSES it to tStatic so the right catalogue is read. useI18n is not available here: this bundle
installs no i18n, which is why the whole element reads through tStatic.
· DashboardResearchFilters.vue — the live-search chip, same shape. research-dashboard DOES install
i18n (index.js:83), so this takes vue-i18n's reactive locale ref, reads it to re-run and passes it
for the lookup.
Both land on check-frozen-labels' documented clean shape — an explicit locale argument — rather than
hiding tStatic behind a helper that would satisfy the gate while leaving the label frozen.
The heading also moved BELOW hostLang, so the dependency it now relies on is declared above it rather
than four hundred lines later.
Verified: check:sfc-parse PASS; check-frozen-labels (studio/landing58) reports exactly these two sites
today, and the shape they move to is its own "pinned" self-test case.
This commit is contained in:
parent
b5178381d2
commit
9d13bef3fb
2 changed files with 20 additions and 2 deletions
|
|
@ -70,7 +70,7 @@ const accent = computed(() => config.value.accent || '#8b5cf6')
|
|||
// `title` still wins — that is what the config key is for — but an absent one now resolves through
|
||||
// the catalogue rather than through a literal. The English wording is unchanged: this is the
|
||||
// shepherd's standing rule that translating EXISTING wording is not a product decision.
|
||||
const heading = computed(() => config.value.title || tStatic('dashboard.bp_title') || 'Big Picture — Unified Research Dashboard')
|
||||
|
||||
// ★ THE LOCALE THE HOST ASKED FOR, AND THE ONE ELEMENT ON THE PAGE THAT CAN ACT ON IT.
|
||||
// MEASURED with check:host-locale-contract: this leaf drew 0 Arabic characters for
|
||||
// profile-config {"locale":"ar"} against 273 for the same page reached with ?lang=ar. Its siblings
|
||||
|
|
@ -86,6 +86,17 @@ const hostLang = computed(() => {
|
|||
})
|
||||
watchEffect(() => { if (hostLang.value) setRuntimeLocale(hostLang.value) })
|
||||
|
||||
// ★ THE LOCALE IS PASSED, NOT ASSUMED, AND THAT IS WHAT KEEPS THIS LIVE. tStatic resolves through
|
||||
// getRuntimeLocale() at CALL time, but a computed only calls again when a REACTIVE dependency changes —
|
||||
// and config.value does not change when the host switches language. So this heading resolved once and
|
||||
// stayed in the boot language while everything around it moved (upg100 measured it; check:frozen-labels
|
||||
// catches the shape). hostLang IS reactive, so reading it both re-runs this computed and tells tStatic
|
||||
// which catalogue to read. useI18n is not an option here: this bundle installs no i18n (index.js), which
|
||||
// is why the whole element reads through tStatic in the first place.
|
||||
const heading = computed(() => config.value.title
|
||||
|| tStatic('dashboard.bp_title', hostLang.value || undefined)
|
||||
|| 'Big Picture — Unified Research Dashboard')
|
||||
|
||||
// ★ RTL IS A DIRECTION, NOT A TRANSLATION — the half this element was still missing.
|
||||
// Its three sibling composites (dashboard-plus-grid, research-map-plus-grid) and the grid itself all
|
||||
// reflect `dir` onto their custom-element host; this one did not, so a host asking for Arabic got
|
||||
|
|
|
|||
|
|
@ -36,12 +36,14 @@
|
|||
* mapped to this dashboard's facet keys). Nothing here is dashboard-specific beyond that map.
|
||||
*/
|
||||
import { inject, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
import SearchFilterHeader from '@map/components/search/SearchFilterHeader.vue'
|
||||
import { getPrayerLevel, LABELS as PRAYER_LABELS } from '@map/colors/prayer-progress.js'
|
||||
import { useTreeLegendLabels } from '../../composables/useTreeLegendLabels.js'
|
||||
|
||||
const { locale } = useI18n()
|
||||
const bus = inject('selectionBus', null)
|
||||
const dash = inject('dashboardData', null)
|
||||
const cfg = inject('dashboardConfig', {})
|
||||
|
|
@ -205,7 +207,12 @@ const activeChips = computed(() => {
|
|||
// in code would get both wrong even with a translated word. It was simply never wired, so ten
|
||||
// locales rendered an English label beside localized facet chips. tStatic takes no params, so
|
||||
// {term} is filled here rather than by the catalogue.
|
||||
if (term) out.push({ name: '__search__', label: (tStatic('dashboard.search_live') || 'Search: {term}').replace('{term}', term) })
|
||||
// ★ locale.value is READ so this computed re-runs on a language switch, and PASSED so tStatic reads
|
||||
// the catalogue the reader just chose. Without it the chip resolved once and stayed in the boot
|
||||
// language beside chips that had moved — a frozen label, which check:frozen-labels now catches.
|
||||
// research-dashboard installs i18n (index.js:83), so useI18n resolves here; big-picture does not,
|
||||
// which is why its sibling fix pins the locale from hostLang instead.
|
||||
if (term) out.push({ name: '__search__', label: (tStatic('dashboard.search_live', locale.value) || 'Search: {term}').replace('{term}', term) })
|
||||
return out
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue