Bugs: clear compare params on tab change, recover channel live messages after a 429,
observer copy link keeps only region params, route table no longer navigates on region
change with nothing selected, map borders memo on data identity, live overview can't
resurrect a failed query, French relative times, no language write on first visit,
0/0 node locations hidden outside the map, path/signal stats use the shared retry rule.
i18n: node/packet/mesh/observer strings that were still hardcoded after #62.
Cleanup: formatUtc, ACTION_BUTTON_CLASS, observer-stats, useWindowedStats, observer-id;
observer pages use StatCard/Card/Field/Segmented/SearchBar/SelectDropdown; one details
chrome on the stats tabs; comment and translations-guide trims; localStorage stub for
Node 26 in the test setup.
Lands the stacked web PRs #75, #79, #80, #81, #83, #85, #87, #89, #92, #95 and #99 in one squash. Server counterparts #166-#176 are merged. Remaining review items follow in a fix PR.
Airtime telemetry is on-air seconds, so chart it as a percent of elapsed time.
Add channel busy, packets heard, SNR heard and payload type charts from the
new per-observer activity endpoint; hidden until the server has it.
- footer read 'v0.1' forever; it's injected from package.json at build
time now
- region picker shows 'Failed to load' instead of an eternal Loading
when /iatas errors
- selecting text in a modal and releasing over the backdrop no longer
closes it (close requires the press to start on the backdrop)
- Escape in a dropdown inside the mobile filter sheet closes just the
dropdown, not the whole sheet
- Shift+Tab right after a modal opens wraps to the last control instead
of escaping the focus trap
- formatCount rolls 999,999 over to 1M instead of printing 1000k
- TABS list moved to lib/constants so AppShell only exports components
* feat: replace getScopeStats with getScopes and update related tests
bug: lastSeen/sentAt was set to string instead of number by mistake
* feat: update timestamp handling and formatting across components
- WS messages carry epoch ms now instead of ISO strings
- new Timestamp component (relative/absolute), used in RouteTable and RouteDetailPanel
- IataChip and ScopeTag chips
- TraceDetailPanel and TraceList for trace drill-down
- tests updated for the timestamp change
- LoadingPill shows loading/error state in MapView, NodeTable and ObserverTable
- new useInfinitePages hook shares the pagination logic between them
- patchNodeSummary/patchObserverSummary now keep references stable
- tests for loading states, observer updates and infinite paging