()
| 354 | } |
| 355 | |
| 356 | async function render() { |
| 357 | const token = ++state.renderToken; |
| 358 | const { from, to } = currentRange(); |
| 359 | const query = `from=${from}&to=${to}`; |
| 360 | |
| 361 | setRangeSummary(`${shortDay(from)} – ${shortDay(to)}, ${to.slice(0, 4)}`); |
| 362 | document.getElementById('data-through').textContent = `Data through ${shortDay(state.anchor)}`; |
| 363 | |
| 364 | // Deduplicate identical URLs within THIS render only — the four stat tiles |
| 365 | // share one /api/summary. Discarded when the render ends, so refresh refetches. |
| 366 | const inFlight = new Map(); |
| 367 | const request = (path) => { |
| 368 | if (!inFlight.has(path)) inFlight.set(path, api(path)); |
| 369 | return inFlight.get(path); |
| 370 | }; |
| 371 | |
| 372 | await Promise.allSettled(PANELS.map((panel) => drawPanel(panel, request(panel.source(query)), token))); |
| 373 | |
| 374 | if (token === state.renderToken) { |
| 375 | document.getElementById('refreshed-at').textContent = |
| 376 | `Last refreshed ${new Date().toLocaleTimeString('en-US')}`; |
| 377 | document.body.dataset.ready = 'true'; |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | // --------------------------------------------------------------------------- |
| 382 | // Start |
no test coverage detected