From 4efd286638df0dcb6171f145b35a6c65e3240285 Mon Sep 17 00:00:00 2001 From: Elie Habib Date: Fri, 24 Apr 2026 23:58:40 +0400 Subject: [PATCH] fix(energy-atlas): wire 4 panels into App.ts primeTask so they actually fetch (#3386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: `App.ts::primeDataForVisiblePanels` is the sole near-viewport kickoff path for panel `fetchData()` calls. Panel's constructor only calls `showLoading()`; nothing else in the app triggers fetchData on attach. Every panel that does real work has a corresponding `if (shouldPrime('')) primeTask(...)` entry in that table. All 4 Energy Atlas panels were missing their entries: - pipeline-status → PipelineStatusPanel - storage-facility-map → StorageFacilityMapPanel - fuel-shortages → FuelShortagePanel - energy-disruptions → EnergyDisruptionsPanel User-visible symptom: the 4 panels shipped as part of #3366 / #3378 / the Energy Atlas PR chain rendered their headers + spinner but never left "Loading…". Verified all four upstream RPCs return data: - /api/supply-chain/v1/list-pipelines?commodityType= → 100 KB - /api/supply-chain/v1/list-storage-facilities → 115 KB - /api/supply-chain/v1/list-fuel-shortages → 21 KB - /api/supply-chain/v1/list-energy-disruptions → 36 KB and /api/health reports all 5 backing Redis keys as OK with the expected record counts (75 gas + 75 oil + 200 storage + 29 shortages + 52 disruptions). Fix: 4 primeTask entries mirroring the pattern already used for energy-crisis, hormuz-tracker, oil-inventories, etc. Each panel already implements the full fetch path (bootstrap-cache-first, RPC fallback, setCached... back-propagation, error states); the entries just give App.ts a reason to call it. Placement: immediately after oil-inventories, grouping the energy surface together. --- src/App.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/App.ts b/src/App.ts index 106be99cd..9afdfaa13 100644 --- a/src/App.ts +++ b/src/App.ts @@ -40,6 +40,10 @@ import type { BigMacPanel } from '@/components/BigMacPanel'; import type { FuelPricesPanel } from '@/components/FuelPricesPanel'; import type { FaoFoodPriceIndexPanel } from '@/components/FaoFoodPriceIndexPanel'; import type { OilInventoriesPanel } from '@/components/OilInventoriesPanel'; +import type { PipelineStatusPanel } from '@/components/PipelineStatusPanel'; +import type { StorageFacilityMapPanel } from '@/components/StorageFacilityMapPanel'; +import type { FuelShortagePanel } from '@/components/FuelShortagePanel'; +import type { EnergyDisruptionsPanel } from '@/components/EnergyDisruptionsPanel'; import type { ClimateNewsPanel } from '@/components/ClimateNewsPanel'; import type { ConsumerPricesPanel } from '@/components/ConsumerPricesPanel'; import type { DefensePatentsPanel } from '@/components/DefensePatentsPanel'; @@ -324,6 +328,29 @@ export class App { const panel = this.state.panels['oil-inventories'] as OilInventoriesPanel | undefined; if (panel) primeTask('oil-inventories', () => panel.fetchData()); } + // Energy Atlas panels — each self-fetches via bootstrap cache + RPC fallback + // (scripts/seed-pipelines-{gas,oil}.mjs, seed-storage-facilities.mjs, + // seed-fuel-shortages.mjs, seed-energy-disruptions.mjs). Without these + // primeTask wires the panels sit at showLoading() forever because + // Panel's constructor calls showLoading() but nothing else triggers + // fetchData() on attach — App.ts's primeTask table is the sole + // near-viewport kickoff path. + if (shouldPrime('pipeline-status')) { + const panel = this.state.panels['pipeline-status'] as PipelineStatusPanel | undefined; + if (panel) primeTask('pipeline-status', () => panel.fetchData()); + } + if (shouldPrime('storage-facility-map')) { + const panel = this.state.panels['storage-facility-map'] as StorageFacilityMapPanel | undefined; + if (panel) primeTask('storage-facility-map', () => panel.fetchData()); + } + if (shouldPrime('fuel-shortages')) { + const panel = this.state.panels['fuel-shortages'] as FuelShortagePanel | undefined; + if (panel) primeTask('fuel-shortages', () => panel.fetchData()); + } + if (shouldPrime('energy-disruptions')) { + const panel = this.state.panels['energy-disruptions'] as EnergyDisruptionsPanel | undefined; + if (panel) primeTask('energy-disruptions', () => panel.fetchData()); + } if (shouldPrime('climate-news')) { const panel = this.state.panels['climate-news'] as ClimateNewsPanel | undefined; if (panel) primeTask('climate-news', () => panel.fetchData());