Commit Graph
61 Commits
Author SHA1 Message Date
MrAlders0n 6b0486f3f4 Gate the neighbour graph to a region and size labels by busyness 2026-07-11 22:11:16 -04:00
MrAlders0n 991f501f7c Use a dropdown for the analytics sections on mobile 2026-07-11 20:52:58 -04:00
MrAlders0n bbe404f0c3 Wrap the analytics sub-header so the range stays on-screen on mobile 2026-07-11 20:16:28 -04:00
MrAlders0n 45669d7c26 Focus the neighbour graph into an ego view on click 2026-07-11 19:53:41 -04:00
MrAlders0n 25bd3ce30e Add a neighbour graph under the renamed Analytics tab 2026-07-11 18:56:58 -04:00
MrAlders0n 92806faaa4 map: colour a selected node's neighbour lines by obs count and freshness 2026-07-08 09:33:57 -04:00
MrAlders0n 5462c08662 map: dim other nodes to spotlight a selected node and its neighbours 2026-07-08 08:41:00 -04:00
MrAlders0n 26e83e0884 nodes: let the mobile detail panel minimize without deselecting 2026-07-07 23:50:21 -04:00
MrAlders0n 8294312ab2 map: fade the live-mode node flash in sync with its packet trail 2026-07-07 23:50:21 -04:00
MrAlders0n dc64382837 map: fade live-mode node markers more so overlaps stay see-through 2026-07-07 23:24:29 -04:00
MrAlders0n 03d7a375a3 map: persist clustering + node-type, default neighbor lines to selected 2026-07-07 23:14:39 -04:00
MrAlders0n c41fe359a6 map: fade live-mode clusters more so dense ones stay see-through 2026-07-07 23:07:53 -04:00
MrAlders0n 105e68ec04 map: rework live mode — packet dot, dashed trail, per-hop flash 2026-07-07 22:49:48 -04:00
MrAlders0n a0736545d8 map: shoot a comet along each packet's route in live mode 2026-07-06 08:13:03 -04:00
MrAlders0n b5e2e5dcac map: live mode dims nodes, flashes each packet's route 2026-07-06 08:00:33 -04:00
MrAlders0n e50501879a feat: discover renderers, neighbor map lines, live packet flow
- 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).
2026-07-05 22:08:54 -04:00
MrAlders0n ad7b485913 feat: traces vs pings
feat: SNR for trace path in list
feat: known niehgbour count
2026-06-13 23:51:09 -04:00
MrAlders0n df9f4a07ad stats: node-types donut, multi-IATA filtering, preset split
- 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
2026-06-11 13:34:11 -04:00
MrAlders0n 9c93dac0f6 stats: bench the node-types donut until a real endpoint exists
The donut counted types among the top-10 nodes only, so the center
read '10 NODES' as if the region had ten nodes, and its center text
never sat quite right (ECharts titles anchor the main text, the
subtext hangs below). There's no /stats/node-types endpoint to feed it
properly yet (ticket filed), so the card shows 'Coming soon' and the
donut builder goes away rather than lingering as dead code.
2026-06-10 08:44:13 -04:00
MrAlders0n d1ff74cc1f stats: anchor the donut center text on the pie's exact center
textAlign/textVerticalAlign make left/top the anchor point, so the
value+label block centers on (35%, 50%) geometrically instead of the
hand-tuned top offset that drifted with card size.
2026-06-10 08:26:47 -04:00
MrAlders0n 4d6d76e451 round out the review fixes: chunk reload, spiderfy reset, search debounce
- a failed lazy chunk now offers 'reload' (React.lazy caches the
  rejection, so remounting could never recover Map/Stats)
- an open spiderfy fan closes on region/type-filter change instead of
  showing leaves from the previous dataset
- map settings persistence moved out of the setState updater
- observer search debounces 250ms and shows 'Search failed' instead of
  'No matches' on errors
- packet-detail staleTime drops to 30s so a reopened analyzer picks up
  new observations
- leaving Stats clears its statsTab/observerId/range URL params
- ws types now match the wire (batteryMv omitted not null, scopes can
  be null, lastObservationId isn't sent today); drop the unused
  microToDeg shim now that nothing imports it
2026-06-10 07:08:13 -04:00
MrAlders0n ad4e68f817 packets: highlight timer leak, analyzer close desync, dead code
- fresh-row highlights leaked under a steady stream (each new batch
  cancelled the previous batch's clear timer); per-batch timers in a
  small useFreshHashes hook now
- closing the analyzer drops ?hash and the row selection, so the same
  row reopens on the next click and a closed analyzer stays closed
  after reload/share
- sf=path / sf=payload from the URL fall back to hash search (only
  field matchesFilters implements; the UI options were already disabled)
- remove the summary preview line no backend path ever populates
- channel message rows key on packetHash (live WS messages carry no id)
2026-06-10 07:03:16 -04:00
MrAlders0n aec59225f0 observers: derive online/offline from lastStatusAt recency
The WS observerStatus event never says offline (the backend only
derives it at REST read time, 5-minute window) and the list never
refetches, so badges stayed green all session once an observer went
quiet. Status is now re-derived on a tick from lastStatusAt — the WS
patch keeps the timestamp fresh — using the same 5-minute rule as the
server.
2026-06-10 07:03:16 -04:00
MrAlders0n a78b735bb2 routes: keep paging when client-side region filtering starves the table
A multi-IATA region filters globally-paged rows client-side, and scroll
was the only trigger for the next page — an empty or too-short filtered
list could never fire it, so routes deeper in the cursor stream were
unreachable ('No routes' with routes that exist). Pull pages until the
region has a screenful or the cap calls it sparse.
2026-06-10 07:03:16 -04:00
MrAlders0n d5deb1e042 stats: node types back to a donut (3 categories), fix leaderboard labels
The donut suits node types after all — few slices, and the total reads
better in the ring than on three bars. The center text is a title block
with textAlign center now, which ECharts actually centers (the old
graphic text anchored its left edge at the ring's x and clipped);
TitleComponent registered in the tree-shaken setup. Payload types stays
a bar chart.

Leaderboard names (top nodes/observers, radio presets) are left-aligned
at the card edge and ellipsized instead of running off the grid's left
side.
2026-06-10 06:59:49 -04:00
MrAlders0n 12d5056e20 map: insert brand-new nodes from their nodeUpdate event
The WS patch only updated nodes already in the paged cache, and with
staleTime Infinity nothing ever refetched — a node that came up after
page load could never appear on the map. The event carries a full
summary, so unknown nodes are appended to the cache directly. The
Nodes table keeps patch-only behavior since its cache is filter-scoped.
2026-06-10 06:59:49 -04:00
MrAlders0n 39756bc0d1 nodes/map: trust the API's decimal-degree coordinates
microToDeg guessed microdegrees from integer values, but api/nodes.go
has always sent *float64 degrees — so a node sitting at an exact whole
degree got divided by 1e6 and rendered at the equator. Drop the shim
from the geojson builder, the nodes table and the detail panel, and fix
the ws.ts comment that repeated the wrong premise.

Also key neighbor rows by id+iata: the neighbors endpoint returns one
row per (neighbor, iata), so id alone collides for nodes heard in
several regions (live React duplicate-key error).
2026-06-10 06:59:49 -04:00
MrAlders0n 115f6a83cc stats: replace the type donuts with vertical bar charts
The payload-types donut was buckling: 10+ slivers, a scrollable legend
with truncated names, and a center total that clipped at narrower
widths. Bars label every category inline, show counts on top, and the
total moved into the card header. Node types gets the same treatment
for consistency.

Also fix charts starting on the fallback palette when a saved theme
loads: themeId is already the saved id before the CSS vars land, so
useChartColors now keys on a paletteRev that bumps on every applyTheme.
2026-06-10 06:46:13 -04:00
MrAlders0n 714b32fd22 fix back/forward tab navigation and the packet-list gap on tab return
The active tab was state seeded from ?tab once, so back/forward moved
the URL without moving the UI. The URL is the source of truth now, and
unknown ?tab values fall back to Packets instead of a blank pane.

Packets history also healed wrong: while the tab is unmounted its WS
handler is down, and staleTime Infinity meant the gap never closed.
Mounting now resets to a fresh first page. Same for lag notices, which
used to invalidate (and sequentially replay) up to 20 cached pages —
together with the ws reconnect notice this covers outage recovery too.
2026-06-10 06:39:12 -04:00
MrAlders0n 7e07669f33 stats: fix live KPI counters never updating
useLiveOverview keyed its setQueryData on the whole RegionFilter object
while the overview query keys on the regionKey string, so every WS bump
silently missed the cache and the counters only moved on the 60s
refetch. Also drop pending counts when the region changes so old-region
increments don't bleed into the new KPIs.
2026-06-10 06:30:32 -04:00
MrAlders0n aabbe404a0 stats: memoize telemetry points so charts stop redrawing every render
The fresh [] fallback minted a new array each render while telemetry
loaded, which rebuilt all five chart options and forced a full ECharts
teardown (notMerge). Also silence the intentional themeId dep warning
in useChartColors.
2026-06-09 23:16:04 -04:00
MrAlders0n 08d50be490 Track devserver.sh and finish the tower -> beacon rename
scripts/ was caught by a stray .gitignore entry, so the npm start/stop
helpers pointed at a file fresh clones never got. Also sweep the last
tower-* references out of comments, compose and the map test fixture.
2026-06-09 23:16:04 -04:00
MrAlders0n add53ba7e7 feat(stats): observer-list search queries all observers server-side
Search the /observers name endpoint (region-scoped) instead of filtering
the loaded top-15, so any observer is findable. Top observers remain the
default list; search results show name + IATA + status.
2026-06-09 22:30:05 -04:00
MrAlders0n 45103692d1 feat(stats): center donut label, observer list search, observer→stats link
- center the payload/node-type donut center value+label in the ring
- add a name search box to the Stats → Observer list
- add a Statistics button on the Observers detail panel that opens
  Stats → Observer preselected to that observer
2026-06-09 22:15:28 -04:00
MrAlders0n be072bb42c feat(stats): add Mesh + Observer stats tab with ECharts
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
2026-06-09 22:02:27 -04:00
MrAlders0n ed9741ea63 feat: standardize trace view to be the same as packets view, etc 2026-06-09 20:37:57 -04:00
MrAlders0n 83c30ca236 Sync to features from server 2026-06-08 22:35:06 -04:00
MrAlders0n 84f235a3b4 Mobile support refactor and cleanup 2026-06-08 10:18:17 -04:00
MrAlders0n b8b1f5f27d Feat/scopes routes traces (#7)
* 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
2026-06-07 00:19:54 -04:00
MrAlders0n 8e2696b95a feat: loading pill for map and tables
- 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
2026-06-05 22:59:52 -04:00
MrAlders0n 81bdeec16b feat: implement paginated node fetching and add related tests 2026-06-05 20:23:17 -04:00
MrAlders0n eb50f310db feat: decrypted channel messages, scopes in ws 2026-06-05 17:22:37 -04:00
MrAlders0n 47c1813471 feat: added path resolution to traces 2026-06-05 09:24:21 -04:00
MrAlders0n 1208413b6e feat: add scopes 2026-06-05 08:49:36 -04:00
MrAlders0n 43ab0dbb3f feat: added region support (#3) 2026-06-04 22:26:05 -04:00
MrAlders0n 4b8109262b feat: packet analyzer overlay, shared modals with focus trap
- 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
2026-06-04 20:22:28 -04:00
MrAlders0n 811c11db52 Feat/map openfreemap (#2)
* initial map page

* Nodes plotted and map in good shape to be merged
2026-05-31 15:15:06 -04:00
MrAlders0n 4ed88b1be6 Cleaning up UI 2026-05-29 23:18:23 -04:00
MrAlders0n dc719b3428 minor bug fix 2026-05-29 20:47:01 -04:00
MrAlders0n eb961c0c92 Fixed the scrollbar anchoring and some bug fixes 2026-05-29 20:21:59 -04:00