mirror of
https://github.com/MeshCore-Beacon/beacon-web.git
synced 2026-10-28 19:22:38 +00:00
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
This commit is contained in:
1 parent
ed9741ea63
commit
be072bb42c
23 files changed
+1934
-291
No files matched your search
@@ -3,6 +3,16 @@ import type { CursorPage, PacketSummary, PacketDetail, IataCode, RegionSummary,
|
||||
import type { ChannelSummary, ChannelMessage } from "../features/channels/types";
|
||||
import type { ObserverSummary, Observer, AdvertObservation } from "../features/observers/types";
|
||||
import type { NodeSummary, Node, NodeObservation, NodeNeighbor } from "../features/nodes/types";
|
||||
import type {
|
||||
StatsOverview,
|
||||
ObservationPoint,
|
||||
PayloadBreakdownItem,
|
||||
TopNode,
|
||||
TopObserver,
|
||||
RadioPreset,
|
||||
ScopeStats,
|
||||
ObserverTelemetry,
|
||||
} from "../features/stats/types";
|
||||
|
||||
// typed fetch wrapper with query params
|
||||
|
||||
@@ -239,4 +249,46 @@ export function getNodeNeighbors(nodeId: string): Promise<NodeNeighbor[]> {
|
||||
return request(`/nodes/${nodeId}/neighbors`);
|
||||
}
|
||||
|
||||
// stats endpoints. `iata` is a single code (undefined = all regions); the /stats/* endpoints filter
|
||||
// by one IATA only, unlike the comma-separated `iatas` used elsewhere.
|
||||
|
||||
export function getStatsOverview(iata?: string): Promise<StatsOverview> {
|
||||
return request("/stats/overview", { iata });
|
||||
}
|
||||
|
||||
export function getStatsObservations(iata?: string, since?: number): Promise<ObservationPoint[]> {
|
||||
return request("/stats/observations", { iata, since });
|
||||
}
|
||||
|
||||
export function getPayloadBreakdown(iata?: string, since?: number): Promise<PayloadBreakdownItem[]> {
|
||||
return request("/stats/payload-breakdown", { iata, since });
|
||||
}
|
||||
|
||||
export function getTopNodes(iata?: string, limit = 10): Promise<TopNode[]> {
|
||||
return request("/stats/top-nodes", { iata, limit });
|
||||
}
|
||||
|
||||
export function getTopObservers(iata?: string, since?: number, limit = 10): Promise<TopObserver[]> {
|
||||
return request("/stats/top-observers", { iata, since, limit });
|
||||
}
|
||||
|
||||
export function getRadioPresets(iata?: string): Promise<RadioPreset[]> {
|
||||
return request("/stats/radio-presets", { iata });
|
||||
}
|
||||
|
||||
// renamed from getScopes to avoid colliding with the /scopes name list; this is the /stats/scopes
|
||||
// aggregate (packet/observer/node counts), reported globally regardless of the active region.
|
||||
export function getStatsScopes(): Promise<ScopeStats[]> {
|
||||
return request("/stats/scopes");
|
||||
}
|
||||
|
||||
export function getObserverTelemetry(
|
||||
observerId: string,
|
||||
range: string,
|
||||
interval?: string,
|
||||
afterId?: number,
|
||||
): Promise<ObserverTelemetry> {
|
||||
return request(`/observers/${observerId}/telemetry`, { range, interval, afterId });
|
||||
}
|
||||
|
||||
export { ApiError };
|
||||
Reference in new issue
Block a user