fix(energy-atlas): wire 4 panels into App.ts primeTask so they actually fetch (#3386)

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('<key>')) 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.
This commit is contained in:
Elie Habib
2026-04-24 23:58:40 +04:00
committed by GitHub
parent ce797da3a4
commit 4efd286638

View File

@@ -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());