diff --git a/meshview/templates/reach.html b/meshview/templates/reach.html index 2fd9542..36b53a8 100644 --- a/meshview/templates/reach.html +++ b/meshview/templates/reach.html @@ -75,6 +75,21 @@ font-size: 0.9rem; } +.reach-gateway-panels { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin-top: 10px; +} + +.reach-gateway-panel { + overflow-x: auto; +} + +.reach-gateway-table { + min-width: 0; +} + .reach-table th, .reach-table td { vertical-align: top; @@ -116,6 +131,12 @@ .reach-muted { color: rgba(255, 255, 255, 0.62); } + +@media (max-width: 600px) { + .reach-gateway-panels { + grid-template-columns: 1fr; + } +} {% endblock %} {% block body %} @@ -170,22 +191,39 @@ -
- - - - - - - - - - - - - - -
GatewayHeard PacketsTotal PacketsReach
Loading packets...
+
+
+ + + + + + + + + + + + + +
GatewayHeardReach
Loading packets...
+
+
+ + + + + + + + + + + + + +
GatewayHeardReach
Loading packets...
+
@@ -258,15 +296,23 @@ async function loadReachReport(nodeId = reachNodeId) { reachNodeId = Number(nodeId); const packetCountEl = document.getElementById("reach-packet-count"); const gatewayCountEl = document.getElementById("reach-gateway-count"); - const bodyEl = document.getElementById("reach-packet-body"); + const bodyEls = [ + document.getElementById("reach-packet-body-left"), + document.getElementById("reach-packet-body-right"), + ]; const bucketBodyEl = document.getElementById("reach-bucket-body"); const selectedNodeEl = document.getElementById("reach-node-id"); + const setGatewayTables = html => { + bodyEls.forEach(el => { + el.innerHTML = html; + }); + }; selectedNodeEl.textContent = reachNodeId; packetCountEl.textContent = "..."; gatewayCountEl.textContent = "..."; bucketBodyEl.innerHTML = 'Loading statistics...'; - bodyEl.innerHTML = 'Loading packets...'; + setGatewayTables('Loading packets...'); try { const [packetData] = await Promise.all([ @@ -281,7 +327,7 @@ async function loadReachReport(nodeId = reachNodeId) { if (packets.length === 0) { gatewayCountEl.textContent = "0"; bucketBodyEl.innerHTML = 'No packets found.'; - bodyEl.innerHTML = 'No packets found.'; + setGatewayTables('No packets found.'); return; } @@ -341,22 +387,26 @@ async function loadReachReport(nodeId = reachNodeId) { `; }).join(""); - bodyEl.innerHTML = gatewayRows.length - ? gatewayRows.map(row => ` + const renderGatewayRows = rows => rows.length + ? rows.map(row => ` ${escapeHtml(gatewayLabel(row.nodeId, nodesById))} ${row.heardCount} - ${packets.length} ${row.percent.toFixed(1)}% `).join("") - : 'No gateways heard these packets.'; + : 'No gateways heard these packets.'; + const splitIndex = Math.ceil(gatewayRows.length / 2); + bodyEls[0].innerHTML = renderGatewayRows(gatewayRows.slice(0, splitIndex)); + bodyEls[1].innerHTML = gatewayRows.length > 1 + ? renderGatewayRows(gatewayRows.slice(splitIndex)) + : 'No additional gateways.'; } catch (err) { console.error("Failed to load reach report:", err); packetCountEl.textContent = "!"; gatewayCountEl.textContent = "!"; bucketBodyEl.innerHTML = 'Failed to load statistics.'; - bodyEl.innerHTML = 'Failed to load report.'; + setGatewayTables('Failed to load report.'); } } @@ -368,8 +418,10 @@ document.addEventListener("DOMContentLoaded", async () => { if (!nodeId) { document.getElementById("reach-bucket-body").innerHTML = 'Enter a valid node ID or select a node.'; - document.getElementById("reach-packet-body").innerHTML = - 'Enter a valid node ID or select a node.'; + document.getElementById("reach-packet-body-left").innerHTML = + 'Enter a valid node ID or select a node.'; + document.getElementById("reach-packet-body-right").innerHTML = + 'Enter a valid node ID or select a node.'; return; }