Add traceroute-inferred links to map and detail panel#366
Add traceroute-inferred links to map and detail panel#366SimmerV merged 5 commits intoMeshAddicts:developfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds traceroute-derived topology links to the map/link layers and extends the node details panel to surface traceroute-adjacent nodes and make table node names navigable.
Changes:
- Infer and render traceroute-based links (amber) alongside neighbor/heard-by links, with neighbor links intended to take priority when both exist.
- Extend the node details panel with a “Traceroute Links” section and make node names in tables clickable for navigation.
- Compact details panel layout (single-line fields, shortened location with full address on hover) and update the legend to include traceroute links.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
frontend/src/pages/map/detailsHtml.ts |
Adds traceroute link section, clickable node labels, ID normalization, and traceroute link GeoJSON builder. |
frontend/src/pages/map/detailsDom.ts |
Adds wiring to handle clicks on data-select-node elements in injected HTML. |
frontend/src/pages/map/MapLegend.tsx |
Adds legend entry for amber traceroute links. |
frontend/src/pages/Map.tsx |
Fetches traceroutes, merges traceroute links into link layers across modes, and wires details-panel node navigation. |
Comments suppressed due to low confidence (1)
frontend/src/pages/Map.tsx:1414
- In the OpenLayers (OSM) provider path, selected-node rendering still draws only neighbor lines (green) and does not draw traceroute-inferred links, even though traceroutes are now passed into buildNodeDetailsHtml. If traceroute links are intended to appear in "Selected Node" mode for both providers, consider adding traceroute line rendering here (and using the same amber color / neighbor-edge dedupe as the Mapbox path).
const { html } = buildNodeDetailsHtml({
node: nodeLike,
liveNodes: nodes,
displayName,
elsewhereLinks: config?.mesh?.elsewhere_links,
traceroutes: traceroutesRef.current,
});
setDetailsPanelContent({
title: node.longname ?? "",
subtitle: node.shortname ?? "",
html,
onNodeSelect: (targetId) => {
const targetNode = nodes[targetId];
if (!targetNode?.map_position) return;
void handleNodeDetails({
id: targetId,
shortname: targetNode.shortname,
longname: targetNode.longname,
last_seen: targetNode.last_seen,
position: [targetNode.map_position[0], targetNode.map_position[1]] as Coordinate,
online: Boolean(targetNode.online),
neighbors: targetNode.neighbors,
});
},
});
// Draw neighbor lines
node.neighbors?.forEach((neighbor) => {
const nnode = nodes[neighbor.id];
if (!nnode?.map_position) return;
const points: Coordinate[] = [node.position, nnode.map_position];
for (let i = 0; i < points.length; i++) {
points[i] = transform(points[i], "EPSG:4326", "EPSG:3857");
}
const featureLine = new Feature({ geometry: new LineString(points) });
const vectorLine = new Vector({});
vectorLine.addFeature(featureLine);
const vectorLineLayer = new VectorLayer({
source: vectorLine,
style: new Style({
fill: new Fill({ color: "#66FF66" }),
stroke: new Stroke({ color: "#66FF66", width: 4 }),
}),
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }), | ||
| liveNodes, | ||
| ); |
There was a problem hiding this comment.
In "mynode" mode, traceroute links are built without passing neighborEdgeKeys, so traceroute-inferred edges that overlap existing neighbor edges will still be emitted. This breaks the stated priority of neighbor data over traceroute data and can render duplicate/ambiguous links; consider reusing collectNeighborEdgeKeys(liveNodes) here and passing it as the third argument to buildTracerouteLinkFeatureCollection.
| }), | ||
| liveNodes, | ||
| ); |
There was a problem hiding this comment.
Selected-node link rendering builds traceroute links without providing neighborEdgeKeys, so any traceroute segment that matches an existing neighbor edge will still be drawn (neighbor priority/deduplication won’t apply in this mode). Pass the same neighbor edge key set used elsewhere (e.g., collectNeighborEdgeKeys(liveNodes)) to buildTracerouteLinkFeatureCollection to suppress overlapping traceroute edges.
| return (raw >>> 0).toString(16).toLowerCase(); | ||
| } | ||
| let s = String(raw).trim(); | ||
| if (/^\d+$/.test(s) && s.length > 6) { |
There was a problem hiding this comment.
normNodeId treats any digit-only string with length > 6 as a decimal ID and converts it to hex. This will mis-normalize legitimate hex node IDs that happen to be digits-only (including zero-padded 8-char IDs like "00123456"), causing traceroute edges to fail to match liveNodes/neighborEdgeKeys and potentially linking the wrong nodes. Consider only applying the decimal-string conversion when the string length is greater than the expected hex width (e.g., > 8 for 32-bit node IDs), or otherwise making the decimal-vs-hex distinction explicit.
| if (/^\d+$/.test(s) && s.length > 6) { | |
| // Treat as decimal only if it's digit-only and longer than the max 32-bit hex width (8 chars) | |
| if (/^\d+$/.test(s) && s.length > 8) { |
Summary