From 9b85b1c36d1e4fea4bc29e691ac3227222abf42c Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Wed, 30 Sep 2026 12:34:25 +0000 Subject: [PATCH] Region Dashboards: the country's poster card sits centred under its toggle, and its Show on map brings the country map back into view --- .../regions-dashboard/region-dashboards.vue | 20 +- public/dx-maps/doxa-maps-spa/manifest.json | 12 +- public/dx-maps/manifest.json | 12 +- .../region-dashboards/index.html | 2 +- .../regions-dashboard/regions-dashboard.js | 204 +++++++++--------- .../regions-dashboard/regions-list/index.html | 2 +- .../regions-dashboard/regions-mfe/index.html | 2 +- 7 files changed, 135 insertions(+), 119 deletions(-) diff --git a/plugin-designs/regions-dashboard/region-dashboards.vue b/plugin-designs/regions-dashboard/region-dashboards.vue index 55c9c5b42..291e1cc6a 100644 --- a/plugin-designs/regions-dashboard/region-dashboards.vue +++ b/plugin-designs/regions-dashboard/region-dashboards.vue @@ -254,9 +254,12 @@ const POSTER_WALL_TAG = 'country-posters-map' const POSTER_WALL_KEYS = ['apiBaseUrl', 'prayBaseUrl', 'tokenUrl', 'dataSource', 'locale', 'lang', 'languageCode', 'isDark', 'provider', 'embedBaseUrl'] const postersOpen = ref(false) const postersHost = ref(null) +// One wall per country, and per dashboard: the id scopes the wall's "Show on map" event to this one. +const posterWallId = (iso3) => `${instanceId.value || 'region-dashboards'}-poster-${String(iso3).toLowerCase()}` function posterWallConfig(iso3) { const c = cfg.value || {} - const out = { profile: 'country-poster-wall', countries: [iso3], instanceId: `rd-country-poster-${iso3.toLowerCase()}`, assetsBase: resolveAssetsBase(c) } + // columns:1 — one card, centred under the toggle by .rd-posters__wall (a two-column grid left it off to one side). + const out = { profile: 'country-poster-wall', countries: [iso3], columns: 1, instanceId: posterWallId(iso3), assetsBase: resolveAssetsBase(c) } for (const k of POSTER_WALL_KEYS) if (c[k] != null && c[k] !== '') out[k] = c[k] if (!out.languageCode && languageCode.value) out.languageCode = languageCode.value return out @@ -288,6 +291,17 @@ watch(() => selectedCountry.value?.code, () => { postersOpen.value = false if (postersHost.value) postersHost.value.replaceChildren() }) +// The card's "Show on map": the country is already this view's subject, so it brings the map above back into +// view. Only this dashboard's own wall (its instanceId) answers here; clearing the toggle (listId null) does not. +const POSTER_WALL_EVENT = 'doxa-country-posters:show-on-map' +function onPosterShowOnMap(e) { + const d = e?.detail || {} + const iso3 = selectedCountry.value?.code + if (!iso3 || !d.listId || d.instanceId !== posterWallId(iso3)) return + const el = mapEl.value && mapEl.value.$el + const still = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches + if (el && el.scrollIntoView) el.scrollIntoView({ block: 'center', behavior: still ? 'auto' : 'smooth' }) +} // The subject line — a country if one was clicked, else the region, else everything. const subject = computed(() => { @@ -751,6 +765,7 @@ watch(languageCode, () => { loadRegions() }) onMounted(async () => { window.addEventListener(SELECT_EVENT, onSelect) + window.addEventListener(POSTER_WALL_EVENT, onPosterShowOnMap) if (URL_SYNC) window.addEventListener('popstate', onPopState) // The hash can only be resolved to a subject once the regions are known, so it is applied // after the fetch rather than on mount — otherwise a deep link silently lands on the chooser. @@ -762,6 +777,7 @@ onMounted(async () => { onBeforeUnmount(() => { window.removeEventListener(SELECT_EVENT, onSelect) + window.removeEventListener(POSTER_WALL_EVENT, onPosterShowOnMap) if (URL_SYNC) window.removeEventListener('popstate', onPopState) }) @@ -1000,7 +1016,7 @@ useShadowStyles( '.rd-posters__toggle:focus-visible{ outline:2px solid #2563eb; outline-offset:2px; }' + '.rd-posters__toggle svg{ width:12px; height:12px; fill:currentColor; transform:rotate(180deg); }' + '.rd-posters__toggle[aria-expanded="true"] svg{ transform:none; }' + - '.rd-posters__wall{ margin-top:12px; }' + + '.rd-posters__wall{ margin-top:12px; width:100%; max-width:520px; align-self:center; }' + // ★ ON PHONES THE MAPS ARE HALF AGAIN AS TALL AS THEY ARE WIDE (height = 1.5 x width), all regions, a region // and a country. A square was asked for first, then proved too small to use a people-group popup in. // RegionCountryMap keeps DX Life's cloned 1/2 portrait under 768px for its other consumer (the country diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index 93b17bd20..d929b9ec6 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -1126,7 +1126,7 @@ "bundle": "regions-dashboard", "scriptUrl": "./regions-dashboard/regions-dashboard.js", "output": "dx-maps/regions-dashboard/regions-dashboard.js", - "integrity": "sha384-mycS9ngShQxZA4avXGlkjA4/s8NFBiFelrwFvrHu7sbiybLui4fy7i5+xIkF/lPx", + "integrity": "sha384-DGlK4bNue+R5evCOfwEURiQtyoMIn6q+ZWiq8/aKwt1DGEi0XfKeAZ/n/GNHPQfC", "elements": [ "regions-dashboard" ], @@ -1149,8 +1149,8 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -1166,7 +1166,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1182,8 +1182,8 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] diff --git a/public/dx-maps/manifest.json b/public/dx-maps/manifest.json index 93b17bd20..d929b9ec6 100644 --- a/public/dx-maps/manifest.json +++ b/public/dx-maps/manifest.json @@ -1126,7 +1126,7 @@ "bundle": "regions-dashboard", "scriptUrl": "./regions-dashboard/regions-dashboard.js", "output": "dx-maps/regions-dashboard/regions-dashboard.js", - "integrity": "sha384-mycS9ngShQxZA4avXGlkjA4/s8NFBiFelrwFvrHu7sbiybLui4fy7i5+xIkF/lPx", + "integrity": "sha384-DGlK4bNue+R5evCOfwEURiQtyoMIn6q+ZWiq8/aKwt1DGEi0XfKeAZ/n/GNHPQfC", "elements": [ "regions-dashboard" ], @@ -1149,8 +1149,8 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -1166,7 +1166,7 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1182,8 +1182,8 @@ "scriptUrl": "./regions-dashboard/regions-dashboard.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] diff --git a/public/dx-maps/regions-dashboard/region-dashboards/index.html b/public/dx-maps/regions-dashboard/region-dashboards/index.html index 1218fe86a..c15d8f102 100644 --- a/public/dx-maps/regions-dashboard/region-dashboards/index.html +++ b/public/dx-maps/regions-dashboard/region-dashboards/index.html @@ -76,7 +76,7 @@ - + - + - +