From 520973c1d7f490e7bd0a0faf147b0393cb9efcf5 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Tue, 29 Sep 2026 20:55:27 +0000 Subject: [PATCH] One country-sheet definition: the Regions tab's poster was still teal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit exp's second read of 1ab8524cf found a real defect on the demo path, and a census of the tree found the cause was worse than the symptom. THE SYMPTOM: the Regions tab printed a TEAL country poster and logged a warn, while Country Posters printed the same country HUED. That is precisely the "two different posters for one country" the hue change exists to refuse. THE CAUSE: regions-list.vue:73 imported a plugin-local copy, src/country-sheet-print.js, byte-identical to library/packet/countrySheet.js except for the region key. The region forwarding was added to the LIBRARY file, so countryRegionColor(undefined) returned the old flat teal and warned. ★ AND THE LIBRARY FILE HAD NO IMPORTERS AT ALL. Its own comment claimed two consumers -- the country-poster wall and -- and a census found NEITHER was true: regions-list imported the local copy, and country-poster-wall.vue:94 defines its own inline countrySheet that calls generateCountrySheet directly (passing the whole record, which is why THAT path was correctly hued). So the module was an orphan wearing a comment that said otherwise, and the region key was added where nothing read it. A move that was never finished, and the duplicate stayed invisible until one copy was edited. regions-list now imports the library module, the copy is deleted, and the comment says what is true. Not re-copied: a duplicate of that file is indistinguishable from it until one side is edited, and then it is a silent divergence. CHAIN VERIFIED TO SOURCE, since the hue is only right if the region survives every hop: POSTER_BY_ISO3 holds country-posters.json records, which all carry a region; localisedPoster SPREADS the record in both its branches, so the key survives a locale switch; postersFor passes it; makeCountrySheet forwards it. ARTIFACT PROOF: the region forwarding in the rebuilt regions-dashboard bundle goes from 1 occurrence to 2, and POSTER_REGIONS plus the full region-name list are present in it. The no-poster fallback branch in postersFor still builds an object without a region, deliberately: it has no sheet to draw, and it already carries unsupportedReason. NOTE ON HISTORY, not rewritten: f6a3f85a2 is titled "Rebuild the three consumers…" but it also carries SOURCE changes -- the ink .pin-num-bg in the shared renderer and the warn-once in posterSheets.js. The title understates it. It is pushed, so it stands; recorded here instead. --- library/packet/countrySheet.js | 18 +++++-- .../regions-dashboard/regions-list.vue | 2 +- .../src/country-sheet-print.js | 47 ------------------- 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 | 2 +- .../regions-dashboard/regions-list/index.html | 2 +- .../regions-dashboard/regions-mfe/index.html | 2 +- 9 files changed, 32 insertions(+), 67 deletions(-) delete mode 100644 plugin-designs/regions-dashboard/src/country-sheet-print.js diff --git a/library/packet/countrySheet.js b/library/packet/countrySheet.js index 895a878ab..8bd7c09d3 100644 --- a/library/packet/countrySheet.js +++ b/library/packet/countrySheet.js @@ -1,9 +1,21 @@ /** * countrySheet.js — a country's map sheet, GENERATED in the browser at the click. * - * SHARED (@map/packet/countrySheet.js). Two consumers: the regions dashboard's country-poster wall - * and the standalone element. It was plugin-local while the regions list was its - * only caller; it moved here when the element became the second, rather than being copied. + * SHARED (@map/packet/countrySheet.js). Its caller is the regions dashboard's regions-list. + * + * ⚠ THE MOVE HERE WAS NEVER FINISHED, and it cost a real defect. This module's comment used to claim + * two consumers -- the country-poster wall and -- and a CENSUS of the tree found + * it had NONE: nothing imported it at all. regions-list kept importing a byte-identical plugin-local + * copy (src/country-sheet-print.js), and country-poster-wall.vue defines its own inline countrySheet + * that calls generateCountrySheet directly. So this file was an ORPHAN wearing a comment that said + * otherwise. + * That mattered the moment the country poster's hue became data-driven: the region key was added + * HERE, where nothing read it, while the copy regions-list actually imported went on building + * `country` without a region -- so countryRegionColor(undefined) returned the old flat teal and + * warned. The same country then printed HUED from Country Posters and TEAL from the Regions tab, + * which is exactly the "two different posters for one country" the hue change exists to refuse. + * The copy is deleted and regions-list imports this. Do not re-copy it: a duplicate of this file is + * indistinguishable from it until one of them is edited, and then it is a silent divergence. * * The print standard is generate, store only previews: no country sheet is shipped, and none should * be. MEASURED before this existed: data/posters holds 28 .html sheets and all 28 are ZONES, while diff --git a/plugin-designs/regions-dashboard/regions-list.vue b/plugin-designs/regions-dashboard/regions-list.vue index 207ba80af..834c882ef 100644 --- a/plugin-designs/regions-dashboard/regions-list.vue +++ b/plugin-designs/regions-dashboard/regions-list.vue @@ -70,7 +70,7 @@ import PosterWall from '@map/components/poster/PosterWall.vue' import RegionSectionCard from '@map/components/regions/RegionSectionCard.vue' import posterData from '@map/data/country-posters.json' import { createPeopleGroupRecords } from '@map/lists/peopleGroupRecords.js' -import { makeCountrySheet } from './src/country-sheet-print.js' +import { makeCountrySheet } from '@map/packet/countrySheet.js' import { resolveAssetsBase } from '@map/utils/embedBase.js' import { onBeforeUnmount } from 'vue' import { cyrillicHeading } from '@map/styles/portedGlobals.js' diff --git a/plugin-designs/regions-dashboard/src/country-sheet-print.js b/plugin-designs/regions-dashboard/src/country-sheet-print.js deleted file mode 100644 index dfba0f571..000000000 --- a/plugin-designs/regions-dashboard/src/country-sheet-print.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * country-sheet-print.js — a country's map sheet, GENERATED in the browser at the click. - * - * The print standard is generate, store only previews: no country sheet is shipped, and none should - * be. MEASURED before this existed: data/posters holds 28 .html sheets and all 28 are ZONES, while - * emit-countries.mjs writes only country-posters.json, whose `sheet` field is a PAPER SIZE ('3x3') - * rather than a filename. So a packet's page-1 lift for a country asked for posters/country-.html - * and got a 404 for all 175 of them. This draws it instead. - * - * Same shape as my-upg-100-list's zone sheet (data/zone-sheet-print.js), deliberately, so the two - * surfaces cannot draw the "same" sheet two ways: - * - * const sheet = makeCountrySheet({ records, assetsBase: () => base }) - * usePosterPrints({ …, sheet }) // (item, format) -> html - * - * - * The country case is simpler than the zone case: generateCountrySheet resolves the zone and its - * geometry from the country entry itself, so there is no assignment step to keep in sync. - */ - -/** - * @param {object} o - * records (selector) => Promise the shared provider; this asks it for ONE country - * assetsBase () => string where boundaries/ is served from - * @returns {(item, format) => Promise} the sheet's HTML, or '' when it cannot be drawn - */ -export function makeCountrySheet({ records, assetsBase }) { - return async function countrySheet(item, format) { - const iso3 = item && item.iso3 - if (!iso3) return '' // a selection or a row without a country: no sheet - // Lazy, like the zone sheet: the generator and the boundary loader are only pulled when a - // reader actually prints, so they stay out of every wall's initial download. - const { generateCountrySheet } = await import('@map/packet/posterSheets.js') - const [{ ISO3_NAME }, rows] = await Promise.all([ - import('@map/data/iso3-name.js'), - records({ type: 'country', values: [iso3] }), - ]) - if (!rows || !rows.length) return '' // nothing to pin: fall through rather than draw an empty country - return generateCountrySheet({ - country: { id: item.id, iso3, label: item.label, count: item.count }, - records: rows, - assetsBase: assetsBase(), - ISO3_NAME, - format, - }) - } -} diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index 67b80cfbc..e543130ff 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-p9e5TCkHgc6IGbryhjNe8+a0jDxOpbtvsu7eAY13u0wu+jlgq3+xNExBJwHnRu4H", + "integrity": "sha384-nCFpvbHr3gglmmJGJPLczrt46mexoJsFlx84acnlNo9HkTCQcXllsJY9ZL2azGpV", "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 67b80cfbc..e543130ff 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-p9e5TCkHgc6IGbryhjNe8+a0jDxOpbtvsu7eAY13u0wu+jlgq3+xNExBJwHnRu4H", + "integrity": "sha384-nCFpvbHr3gglmmJGJPLczrt46mexoJsFlx84acnlNo9HkTCQcXllsJY9ZL2azGpV", "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 0dac0f192..b6c1118b0 100644 --- a/public/dx-maps/regions-dashboard/region-dashboards/index.html +++ b/public/dx-maps/regions-dashboard/region-dashboards/index.html @@ -70,7 +70,7 @@ - + - + - +