- Discover packets decoded: DISCOVER_REQ/DISCOVER_RESP render real fields
(type-filter roles, tag, node-to-node request SNR) instead of a raw dump.
- Neighbor lines on the map: On/Selected/Off control draws links between nodes
and their known neighbors.
- Live packet flow: a play button animates packets hop-to-hop between repeaters
in real time (off by default).
- node-types: new /stats/node-types endpoint + useNodeTypes; donutOption
replaces the "Coming soon" card with a live donut
- stats endpoints take iatas[] instead of a single iata, so multi-IATA
regions filter instead of falling back to all (drops useStatsIata)
- radio presets keep the node/observer split via stacked presetBarsOption
- drop client-side telemetry ms-normalization (backend now emits epoch ms
on both paths); charts pick delta-vs-raw counters off the response interval
- MeshTab: range-driven charts lead, all-time charts follow; KPI window
from overview.windowHours instead of a hardcoded 24h
- ci: docker-publish builds a :dev image on dev-branch pushes
/channels ignores the plural iatas param, so the sidebar was always
global no matter the region — and opening another region's channel
showed an empty panel because the messages endpoint IS region-filtered.
Single-IATA regions filter properly now; multi-IATA stays global until
the backend grows parseIATAs there (ticket).
Integrate the stats feature onto main: live mesh KPIs, observations
time-series, payload/node-type donuts, top-nodes/observers leaderboards,
radio presets, scope stats, and per-observer telemetry (battery, airtime,
noise, queue, receive errors) with 1h/6h/24h bucketing.
- adapt to the multi-IATA region model (useRegion -> single iata for /stats/*)
- rename stats getScopes -> getStatsScopes (avoids /scopes name-list collision)
- donut legend kept right but scrollable + truncating so it never clips
- balanced mesh grid; observer empty-state for telemetry-less observers
- normalize telemetry t to ms (raw path emits seconds, bucketed emits ms)
- add echarts 5.5.1; lazy-load StatsOverview chunk
* 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
- usePackets pulls a bigger first page (INITIAL_PACKET_PAGE_SIZE)
- ModalOverlay + useFocusTrap, used by NodeDetailOverlay and PacketAnalyzerOverlay
- PathData popovers for path resolutions; ObserverIcon and Tooltip
- tests for packet structure and the focus trap; tidied types in api.ts/enums.ts