diff --git a/internal/check-optional-t-equivalence.mjs b/internal/check-optional-t-equivalence.mjs index e96e2f648..a11a199e5 100644 --- a/internal/check-optional-t-equivalence.mjs +++ b/internal/check-optional-t-equivalence.mjs @@ -135,6 +135,11 @@ const SITES = [ ['plugin-designs/cities-internet/connectivity-list.vue', 'useOptionalT', 'fallback: enLookup'], ['plugin-designs/cities-internet/connectivity-map.vue', 'useOptionalT', 'fallback: enLookup'], ['plugin-designs/cities-internet/data-tables.vue', 'useOptionalT', 'fallback: enLookup'], + // wave 3c — my-upg-100-list (owner: upg100). Both used the humanizeKey fallback and no namespace, + // since callers pass full keys. Each keeps humanizeKey, so a bare host reads the same title-cased + // last segment it always did. + ['plugin-designs/my-upg-100-list/poster-wall.vue', 'useOptionalT', 'humanizeKey(k)'], + ['plugin-designs/my-upg-100-list/upg-100-mfe.vue', 'useOptionalT', 'humanizeKey(k)'], ] // ★ ONE FILE KEEPS TWO BARE useI18n CALLS ON PURPOSE, and the count is asserted rather than waived. // resources-map.vue reads the LOCALE twice (`useI18n().locale.value`) to decide isEnglish and the diff --git a/plugin-designs/my-upg-100-list/poster-wall.vue b/plugin-designs/my-upg-100-list/poster-wall.vue index ee164d4d7..dd3a90885 100644 --- a/plugin-designs/my-upg-100-list/poster-wall.vue +++ b/plugin-designs/my-upg-100-list/poster-wall.vue @@ -39,7 +39,7 @@ * IDEA-POSTER-EXPORT-404-ON-DROPPED-FOLDER-TRADEOFF. */ import { computed, inject, ref } from 'vue' -import { useI18n } from 'vue-i18n' +import { useOptionalT } from '@map/composables/useOptionalT.js' // The page's people-group LIST (library/lists/): every people-group fetch below keeps only its groups. import { applyPeopleGroupList } from '@map/lists/peopleGroupList.js' import PosterWall from '@map/components/poster/PosterWall.vue' @@ -163,8 +163,13 @@ async function fetchListRecords(list) { // Guarded like every other useI18n() here: it throws on a host without vue-i18n. const humanizeKey = (k) => String(k).split('.').pop() .replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/^./, (c) => c.toUpperCase()) -let t = (k) => humanizeKey(k) -try { t = useI18n().t } catch (_) { /* no i18n on this host */ } +// C4 wave 3c: the guard is library/composables/useOptionalT.js now. humanizeKey STAYS as the fallback, +// passed in, so a bare host still reads a title-cased last segment rather than a dotted key. No +// namespace: callers pass FULL keys here, exactly as the raw useI18n().t they used to get. +// ★ ONE BEHAVIOUR GAIN, stated rather than smuggled: the old i18n path was the bare useI18n().t, so on +// a host WITH i18n a missing key rendered the raw dotted key. It now falls through to humanizeKey, the +// same fallback the bare host already got. Nothing that resolves today changes. +const t = useOptionalT('', { fallback: (k) => humanizeKey(k) }) const intro = computed(() => t('messages.upg100WallIntro')) const heading = computed(() => t('messages.upg100WallHeading')) const wallTag = computed(() => t('messages.upg100WallTag')) diff --git a/plugin-designs/my-upg-100-list/upg-100-mfe.vue b/plugin-designs/my-upg-100-list/upg-100-mfe.vue index 04193a21b..eb49228cc 100644 --- a/plugin-designs/my-upg-100-list/upg-100-mfe.vue +++ b/plugin-designs/my-upg-100-list/upg-100-mfe.vue @@ -34,7 +34,7 @@ * whole MFE (both panes) is what gets shared/embedded. */ import { ref, computed, inject, onMounted, onBeforeUnmount } from 'vue' -import { useI18n } from 'vue-i18n' +import { useOptionalT } from '@map/composables/useOptionalT.js' import { buildPaneColumn, PANE_GRID_STYLES } from '@map/layouts/pane-wrapper/pane-wrapper.js' import { useShadowStyles } from '@map/composables/useShadowStyles.js' import ViewSelect from '@map/components/ViewSelect.vue' @@ -50,8 +50,13 @@ import ShareButton from '@map/components/map-controls/ShareButton.vue' // humanises the key so a bare host shows "Select View", never a blank or a raw dotted key. const humanizeKey = (k) => String(k).split('.').pop() .replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/^./, (c) => c.toUpperCase()) -let t = (k) => humanizeKey(k) -try { t = useI18n().t } catch (_) { /* no i18n on this host */ } +// C4 wave 3c: the guard is library/composables/useOptionalT.js now. humanizeKey STAYS as the fallback, +// passed in, so a bare host still reads a title-cased last segment rather than a dotted key. No +// namespace: callers pass FULL keys here, exactly as the raw useI18n().t they used to get. +// ★ ONE BEHAVIOUR GAIN, stated rather than smuggled: the old i18n path was the bare useI18n().t, so on +// a host WITH i18n a missing key rendered the raw dotted key. It now falls through to humanizeKey, the +// same fallback the bare host already got. Nothing that resolves today changes. +const t = useOptionalT('', { fallback: (k) => humanizeKey(k) }) const cfg = inject('profileConfig', ref(null)) const tk = inject('mapboxToken', ref(''))