From 1153556f47966df5a48efccca35f3c7ca2c97eb6 Mon Sep 17 00:00:00 2001 From: vjrj Date: Sun, 2 Aug 2026 00:27:58 +0200 Subject: [PATCH] =?UTF-8?q?revert(maps):=20deshacer=20el=20arreglo=20del?= =?UTF-8?q?=20mapa=20gris=20=E2=80=94=20empeoraba=20staging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Desplegado en staging, el "montar el control de capas una sola vez" resultó peor que el bug que arreglaba: /fires seguía en gris Y además la portada y /zones —que sí pintaban— se quedaron también sin teselas. Con la clave real, el control acaba montándose después de que el mapa ya esté montado, y entonces no se le añade ninguna capa base. O sea que la carrera no se arregla retrasando el montaje: solo cambia de sitio. Staging revertido a la imagen anterior y comprobado que vuelve a estar como estaba (portada 36 teselas, /zones 18, /fires 0). Se conserva todo lo aprendido, que es lo que vale: el bug se reproduce en local poniendo una clave de Google en settings-ci.json (15 teselas sin clave, 0 con ella), NO es cosa del navegador sin pantalla, y e2e/tests/fires-map.spec.js lo deja como test.fixme para que aparezca en cada ejecución. El arreglo bueno pasa por decidir el conjunto de capas base ANTES de montar el mapa. --- e2e/tests/fires-map.spec.js | 46 +++++++++++++++------- imports/ui/components/Maps/DefMapLayers.js | 32 +++------------ 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/e2e/tests/fires-map.spec.js b/e2e/tests/fires-map.spec.js index 5ebaede..92ec5dd 100644 --- a/e2e/tests/fires-map.spec.js +++ b/e2e/tests/fires-map.spec.js @@ -1,18 +1,36 @@ import { test, expect } from '@playwright/test'; import { waitForMap } from '../support/app.js'; -// El mapa de /fires es la página principal del sitio y se quedaba EN GRIS en -// staging: ni teselas, ni fuegos, ni suscripción por viewport, con el -// "Actualizando…" eterno. Se había dado por un artefacto del navegador sin -// pantalla; no lo era. El control de capas se montaba con dos capas base y, al -// resolverse la clave de Google, se le añadían tres más — y en esa segunda -// pasada react-leaflet se dejaba por el camino la capa base marcada. +// ⛔ BUG ABIERTO: el mapa de /fires se queda EN GRIS cuando hay clave de Google +// Maps configurada — ni teselas, ni fuegos, ni suscripción por viewport, con el +// "Actualizando…" eterno. Es lo que se ve en staging. // -// Solo se veía en despliegues CON clave de Google. Por eso settings-ci.json -// lleva una clave falsa: para que esta suite recorra el mismo camino que -// staging y producción. +// Lo que SÍ está establecido (2026-08-01): +// +// 1. NO es el navegador sin pantalla. El mismo Playwright headless pinta la +// portada y /zones de staging, y pinta /fires perfectamente contra un +// servidor local sin clave. La nota del plan que lo achacaba a eso es falsa. +// 2. Depende de la clave de Google. Basta con poner una clave (aunque sea +// falsa) en settings-ci.json para reproducirlo en local: 15 teselas sin +// clave, 0 con ella. Por eso settings-ci.json lleva una: para que esto se +// vea aquí y no solo en staging. +// 3. El control de capas se monta con dos capas base y, al resolverse la clave, +// se le añaden tres de Google. En esa segunda pasada react-leaflet se deja +// por el camino la capa base marcada. +// 4. Montar el control UNA sola vez, esperando a la clave, arregla el caso +// local pero ROMPE staging todavía más: allí la portada y /zones —que +// funcionaban— se quedan también sin teselas, porque entonces el control +// aparece después de que el mapa ya esté montado. Probado en staging, +// revertido: no basta con mover el momento del montaje. +// +// El arreglo bueno pasa por que el conjunto de capas base esté decidido ANTES de +// montar el mapa (resolver la clave más arriba, o que GoogleMutantLayer sepa no +// hacer nada sin clave). +// +// Quedan como test.fixme para que salgan como pendientes en cada ejecución en +// vez de desaparecer en una nota. Quitar el .fixme al arreglarlo. test.describe('mapa de fuegos activos', () => { - test('paints its tiles', async ({ page }) => { + test.fixme('paints its tiles', async ({ page }) => { await page.goto('/fires'); await waitForMap(page); @@ -20,7 +38,7 @@ test.describe('mapa de fuegos activos', () => { expect(await page.locator('.leaflet-tile').count()).toBeGreaterThan(0); }); - test('offers every base layer and keeps the checked one', async ({ page }) => { + test.fixme('offers every base layer and keeps the checked one', async ({ page }) => { await page.goto('/fires'); await waitForMap(page); @@ -33,7 +51,7 @@ test.describe('mapa de fuegos activos', () => { expect(await page.locator('.leaflet-tile').count()).toBeGreaterThan(0); }); - test('subscribes to the fires of the current viewport', async ({ page }) => { + test.fixme('subscribes to the fires of the current viewport', async ({ page }) => { await page.goto('/fires'); await waitForMap(page); @@ -42,13 +60,11 @@ test.describe('mapa de fuegos activos', () => { expect(names).toContain('activefiresunionmyloc'); }); - test('does not get stuck on "Actualizando…"', async ({ page }) => { + test.fixme('does not get stuck on "Actualizando…"', async ({ page }) => { await page.goto('/fires'); await waitForMap(page); await page.waitForTimeout(5000); - // El texto aparece mientras la suscripción no está lista; quedarse ahí es - // justo el síntoma del mapa gris. await expect(page.getByText('Actualizando...', { exact: false })).toHaveCount(0); }); }); diff --git a/imports/ui/components/Maps/DefMapLayers.js b/imports/ui/components/Maps/DefMapLayers.js index cc76919..022f298 100644 --- a/imports/ui/components/Maps/DefMapLayers.js +++ b/imports/ui/components/Maps/DefMapLayers.js @@ -13,45 +13,23 @@ const { BaseLayer } = LayersControl; const defOpacity = 0.7; -// Cuánto se espera a que Google conteste antes de montar el control solo con -// OpenStreetMap. Si el script de Google no llega (sin red hacia Google, una -// extensión que lo bloquea, un despliegue sin clave), el mapa tiene que salir -// igual: las capas de Google son un extra. -const GMAPS_WAIT_MS = 5000; - class DefMapLayers extends Component { constructor(props) { super(props); this.state = { - gkey: null, - // El control de capas se monta UNA vez, con la lista de capas ya cerrada. - // Añadirle capas después —que es lo que pasaba al resolverse la clave de - // Google— hacía que react-leaflet se dejara por el camino la capa base - // marcada, y el mapa se quedaba en gris: sin teselas, sin fuegos y con el - // "Actualizando…" eterno. Solo se veía en despliegues CON clave de Google - // (staging y producción), nunca en desarrollo, que no la tiene. - ready: false + gkey: null }; } componentDidMount() { - this.mounted = true; - const settle = (key) => { - if (!this.mounted || this.state.ready) return; - this.setState({ gkey: key || null, ready: true }); - }; - Gkeys.load((err, key) => settle(key)); - this.waitTimer = setTimeout(() => settle(null), GMAPS_WAIT_MS); - } - - componentWillUnmount() { - this.mounted = false; - clearTimeout(this.waitTimer); + const self = this; + Gkeys.load((err, key) => { + self.setState({ gkey: key }); + }); } render() { const { t } = this.props; - if (!this.state.ready) return null; const osmgraylayer = (