feat(meshcore): add Telemetry dashboard tab via source-agnostic Dashboard#3142
Conversation
…oard (#3139) Builds out the missing destination for "favorited" MeshCore telemetry charts. The favorite-star toggle was already present in MeshCore views (DM contact panels), but there was no MeshCore-side surface that read `telemetryFavorites` back. Reported by @HougeDK in #3139. ## What changed 1. **Dashboard becomes source-agnostic** via a new `DashboardDataSource` abstraction (`src/components/Dashboard/dataSources.ts`). Every Meshtastic-specific assumption now goes through the data-source adapter: - Nodes endpoint (`/api/nodes` vs `/api/sources/:id/meshcore/nodes`) - Node-key extraction (`user.id` vs `publicKey`) - Device-role labelling (`getDeviceRoleName` vs MeshCore advType map) - Solar-overlay default-on type list - Whether the "Add Widget" button is shown (MeshCore: false, since `nodeStatus` / `traceroute` / `hopDistribution` widgets all assume Meshtastic data shapes and protocol concepts) Two adapters ship: `meshtasticDashboardSource` (the default, exactly preserves prior behaviour byte-for-byte) and `meshcoreDashboardSource` (the new one). The Dashboard component accepts the adapter as an optional prop with the Meshtastic default, so the existing App.tsx mount point is unchanged. 2. **New `MeshCoreTelemetryView`** mounts the same `<Dashboard>` with `meshcoreDashboardSource`. Adds a "📊 Telemetry" entry to `MeshCoreSubToolbar` between Direct Messages and Node Info. 3. **`mc_*` label support in `TELEMETRY_LABELS`** — adds entries for every LPP type name from `LPP_TYPE_NAMES` and every `mc_status_*` field from `STATUS_FIELD_MAP`. The label resolver also recognises the `_ch<N>` suffix from #3141 and renders e.g. `mc_battery_volts_ch2` as `Battery (ch2)` without enumerating every type×channel combo. ## Test plan - [x] `npx tsc --noEmit` clean - [x] Full Vitest suite: 5411 / 5411 passing (5395 before + 16 new) - [x] New `dataSources.test.ts` covers the MeshCore adapter shape mapping, role labels, key extraction, and per-source defaults - [x] New `TelemetryChart.test.ts` covers the channel-suffix label resolution - [ ] Manual smoke: open a MeshCore source, navigate to the Telemetry tab, verify favorited charts render and the "Add Widget" button is hidden ## Notable design decisions - **No data-shape forking inside Dashboard internals.** The adapter normalises both sources into the existing `NodeInfo` shape at fetch time, so the hooks and grid don't have to know which kind of node they're holding. Keeps the diff small. - **Custom widgets are gated, not duplicated.** Rather than build a separate `MeshCoreDashboard` component, we hide the four Meshtastic-only widget types via `showCustomWidgets: false` on the MeshCore adapter. If/when MeshCore grows equivalent widgets (e.g. MeshCore-flavoured hop distribution), they get added to the same flag-gated AddWidgetModal flow. Closes part 2 of #3139. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Code Review: MeshCore Telemetry Dashboard FeatureThis is an excellent implementation that successfully adds source-agnostic dashboard functionality to MeshMonitor. The architecture is well-designed and the code quality is high. Here's my detailed analysis: ✅ Architecture & Design ExcellenceSource-Agnostic Abstraction: The Minimal Surface Area Changes: The PR achieves significant functionality expansion (~549 lines) while keeping the Dashboard component changes minimal ( Type Safety: Strong TypeScript usage throughout. The ✅ Implementation QualityMeshCore Data Transformation: The adapter correctly maps MeshCore data to the existing
Channel Suffix Handling: Excellent regex-based label resolution for MeshCore's Permission Integration: Proper permission checking in ✅ Test CoverageComprehensive Testing: New tests thoroughly cover the critical path:
Regression Protection: Tests ensure Meshtastic behavior remains unchanged while validating new MeshCore functionality. ✅ Performance & MaintainabilityQuery Key Scoping: Proper TanStack Query cache scoping by Solar Defaults: Smart per-source solar overlay defaults. MeshCore focuses on LPP sensor types ( Lazy Loading: MeshCore nodes only load when
|
…ish (#3145) Version bump and CHANGELOG entry for 4.6.5. Highlights: - #3143 MQTT Bridge mirror dashboard (read-only Open button on bridge cards; suppresses every TX surface; MqttBridgeManager now exposes the Meshtastic-shaped methods the consolidated /api/poll + /api/connection endpoints expect). - #3142 MeshCore Telemetry dashboard tab via source-agnostic Dashboard. - #3141 MeshCore: preserve LPP channel byte in remote telemetry rows. - #3140 DM: skip PKI flag when keyMismatchDetected. - #3138 docs reorganization. - #3137 unified: merge nodes across sources so labels show in the unified Nodes view. - #3136 mqtt: allow standalone mqtt_bridge as client-proxy target. CLAUDE.md version line updated to 4.6.5. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Closes part 2 of #3139. Adds a destination for MeshCore favorited-telemetry charts. Until this PR, the favorite-star toggle was present in MeshCore views (DM contact panels) but no MeshCore-side surface read `telemetryFavorites` back — the user could star a chart but couldn't see it anywhere afterward.
What changed
1. Dashboard becomes source-agnostic
New `DashboardDataSource` abstraction (`src/components/Dashboard/dataSources.ts`). Every Meshtastic-specific assumption inside the per-source `Dashboard` now goes through the adapter:
Two adapters ship: `meshtasticDashboardSource` (default, exactly preserves prior behaviour) and `meshcoreDashboardSource`. The Dashboard component accepts the adapter as an optional prop with the Meshtastic default, so the existing `App.tsx` mount point at `activeTab === 'dashboard'` is unchanged.
2. New MeshCore Telemetry view
3. `mc_*` labels in `TELEMETRY_LABELS`
Adds entries for every LPP type in `LPP_TYPE_NAMES` and every `mc_status_*` field in `STATUS_FIELD_MAP`. The label resolver also recognises the `_ch` suffix from #3141 and renders e.g. `mc_battery_volts_ch2` as `Battery (ch2)` — so we don't need to enumerate every type×channel combination in the label table.
Test plan
Notable design decisions
Builds on #3141 (LPP channel byte preservation), merged earlier.
🤖 Generated with Claude Code