From b7621fad315ab4c5427a3bd85f7b0d0f19dd2d73 Mon Sep 17 00:00:00 2001 From: bloqaudio Date: Sun, 13 Sep 2026 11:15:33 -0500 Subject: [PATCH] web: keep the port detail view live and summarise each port in a tooltip The old dashboard showed a hover tooltip per port with the link state and, for SFP ports, the module and its DOM readings, and rewrote it on every poll. The single-page app replaced it with a click-to-open dialog that was a snapshot: the values did not change while it was open. Build the rows once per port and use them for both: the dialog is re-rendered on every status poll while it is open, and each port in the strip carries the same rows as its title. --- html/app.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/html/app.js b/html/app.js index 5c9c6c33..4f70b668 100644 --- a/html/app.js +++ b/html/app.js @@ -353,7 +353,7 @@ function i18nApply(){ } var S={ - ports:[],n:0,physToLog:[],logToPhys:[],sfpSlot:[],info:{}, + ports:[],n:0,physToLog:[],logToPhys:[],sfpSlot:[],info:{},detail:null, dirty:false,prev:null,prevT:0,rates:[],mtu:[], }; var LINKS=["Down","10M","100M","1000M","500M","10G","2.5G","5G"]; @@ -476,13 +476,14 @@ function toast(msg,cls){ setTimeout(function(){el.remove()},3800); } function modal(title,bodyEl,buttons){ + S.detail=null; $("mtitle").textContent=title; var b=$("mbody");b.innerHTML="";b.appendChild(bodyEl); var f=$("mfoot");f.innerHTML=""; (buttons||[]).forEach(function(bt){f.appendChild(bt)}); $("mback").classList.add("show"); } -function closeModal(){$("mback").classList.remove("show")} +function closeModal(){S.detail=null;$("mback").classList.remove("show")} $("mx").addEventListener("click",closeModal); $("mback").addEventListener("click",function(e){if(e.target===this)closeModal()}); function confirmModal(title,detail,onok){ @@ -606,8 +607,9 @@ function updateStrip(){ el.classList.toggle("up",!!up); if(up)el.style.setProperty("--pc","var("+(LINKC[p.link]||"--s1000")+")"); lb.textContent=!p.enabled?t("c_off"):(p.link>0?LINKS[p.link]:t("c_down")); - el.title=(p.name?p.name+" ":"")+(p.isSFP?"SFP":"RJ45"); + el.title=portRows(p).map(function(r){return r[0]+": "+r[1]}).join("\n"); }); + if(S.detail!=null){var b=$("mbody");b.innerHTML="";b.appendChild(detailTable(S.ports[S.detail]));} } function pU16(v){return parseInt(v,16)&0xffff} @@ -628,9 +630,7 @@ function calRx(val,cal){ +v.getFloat32(8)*Math.pow(val,2)+v.getFloat32(12)*val+v.getFloat32(16); } function dBm(mw){return 10*Math.log10(mw)} -function portDetail(i){ - var p=S.ports[i]; - if(!p)return; +function portRows(p){ var rows=[[t("c_port"),String(p.portNum)],[t("c_type"),p.isSFP?"SFP":"RJ45"]]; if(p.name)rows.push([t("c_name"),p.name]); rows.push([t("p_state"),!p.enabled?t("p_disabled"):(p.link>0?t("p_up")+" "+LINKS[p.link]:t("c_down"))]); @@ -662,11 +662,19 @@ function portDetail(i){ var on=names.filter(function(_,b){return bits&(1<