fix: remove duplicate JS block causing SyntaxError in dashboard

This commit is contained in:
Majjo
2026-04-18 20:04:08 +02:00
parent ce3361992c
commit 22ee866205

View File

@@ -722,189 +722,6 @@ function closeDetail(){
q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
}
// ---- Shared ----
function filter(listId,filterId){
var f=q(filterId).value.toLowerCase();
q(listId).querySelectorAll('.log-+e).toISOString().slice(11,23)}
function q(id){return document.getElementById(id)}
function loadHistory(){
fetch('/logs').then(function(r){return r.json();}).then(function(a){a.forEach(function(e){addLog(e,false);});});
fetch('/network').then(function(r){return r.json();}).then(function(a){a.forEach(function(e){addNet(e,false);});});
}
function startSSE(){
var es=new EventSource('/events');
es.onopen=function(){q('dot').textContent='● connected';q('dot').className='on';};
es.onerror=function(){q('dot').textContent='● disconnected';q('dot').className='off';};
es.addEventListener('log',function(e){addLog(JSON.parse(e.data),true);});
es.addEventListener('network',function(e){addNet(JSON.parse(e.data),true);});
es.addEventListener('network_update',function(e){updateNet(JSON.parse(e.data));});
}
// ---- Logs ----
function addLog(e,live){
lc++;
var el=document.createElement('div');
el.className='log-row '+(e.level||'I');
el.textContent='['+ts(e.ts)+'] '+(e.level||'I')+' '+(e.tag||'')+': '+(e.msg||'');
el.dataset.t=el.textContent.toLowerCase();
applyLogFilter(el);
q('le').appendChild(el);
if(live&&q('ls').checked)el.scrollIntoView();
upd();
}
function applyLogFilter(el){
var f=q('lf').value.toLowerCase();
el.style.display=(!f||el.dataset.t.includes(f))?'':'none';
}
// ---- Network rows ----
function methodClass(m){return m||'GET';}
function statusSpan(e){
if(!e.done)return '<span class="status-pend">…</span>';
if(e.status&&e.status>=400)return '<span class="status-err">'+e.status+'</span>';
return '<span class="status-ok">'+(e.status||'ok')+'</span>';
}
function sizeStr(bytes){
if(bytes==null)return '';
if(bytes<1024)return bytes+'B';
return (bytes/1024).toFixed(1)+'K';
}
function addNet(e,live){
nc++;
netMap[e.id]=e;
var el=document.createElement('div');
el.className='net-row';
el.id='nr-'+e.id;
el.dataset.t=(e.uri||'').toLowerCase();
el.innerHTML='<span class="badge '+methodClass(e.method)+'">'+(e.method||'?')+'</span>'+
statusSpan(e)+
'<span class="net-uri">'+(e.uri||'')+'</span>'+
'<span class="net-size" id="ns-'+e.id+'">'+(e.resSize!=null?sizeStr(e.resSize):'')+'</span>';
el.onclick=function(){openDetail(e.id);};
applyNetFilter(el);
q('ne').appendChild(el);
if(live&&q('ns').checked)el.scrollIntoView();
upd();
}
function updateNet(e){
netMap[e.id]=Object.assign(netMap[e.id]||{},e);
var row=q('nr-'+e.id);
if(!row)return;
var m=netMap[e.id];
row.innerHTML='<span class="badge '+methodClass(m.method)+'">'+(m.method||'?')+'</span>'+
statusSpan(m)+
'<span class="net-uri">'+(m.uri||'')+'</span>'+
'<span class="net-size" id="ns-'+m.id+'">'+(m.resSize!=null?sizeStr(m.resSize):'')+'</span>';
row.onclick=function(){openDetail(m.id);};
if(detailId===e.id)refreshDetail();
}
function applyNetFilter(el){
var f=q('nf').value.toLowerCase();
el.style.display=(!f||el.dataset.t.includes(f))?'':'none';
}
function filterNet(){
q('ne').querySelectorAll('.net-row').forEach(applyNetFilter);
}
// ---- Detail panel ----
function openDetail(id){
detailId=id;
detailFull=null;
var sum=netMap[id];
if(!sum)return;
q('detail').style.display='flex';
q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
var row=q('nr-'+id);
if(row)row.classList.add('selected');
renderDetailMeta(sum);
q('d-body').textContent='Loading…';
fetch('/network/'+id).then(function(r){return r.json();}).then(function(full){
detailFull=full;
renderDetailMeta(full);
renderBody();
}).catch(function(){q('d-body').textContent='Failed to load details.';});
}
function refreshDetail(){
if(!detailId)return;
var sum=netMap[detailId];
if(!sum)return;
renderDetailMeta(sum);
if(detailFull)renderBody();
}
function renderDetailMeta(e){
var m=e.method||'?';
q('d-badge').className='badge '+methodClass(m);
q('d-badge').textContent=m;
q('d-badge').style.cssText='';
q('d-status').textContent=e.status||(e.done?'ok':'…');
q('d-status').className=e.status&&e.status>=400?'status-err':'status-ok';
q('d-uri').textContent=e.uri||'';
}
function showTab(tab){
detailTab=tab;
q('tab-req').className='tab-btn'+(tab==='req'?' active':'');
q('tab-res').className='tab-btn'+(tab==='res'?' active':'');
renderBody();
}
function toggleHex(){
hexMode=!hexMode;
q('btn-hex').className='tab-btn'+(hexMode?' active':'');
renderBody();
}
function renderBody(){
if(!detailFull){q('d-body').textContent='Loading…';return;}
var b64=detailTab==='res'?detailFull.resBody:detailFull.reqBody;
if(!b64){q('d-body').textContent='(empty)';return;}
var truncated=b64.endsWith('==TRUNCATED==');
if(truncated)b64=b64.slice(0,b64.length-13);
var bytes=b64ToBytes(b64);
var suffix=truncated?'\n\n[truncated at 48 KB]':'';
if(hexMode){q('d-body').textContent=hexDump(bytes)+suffix;return;}
var text=tryUtf8(bytes);
if(text){
var pretty=tryJsonPretty(text);
q('d-body').textContent=(pretty||text)+suffix;
}else{
q('d-body').textContent=hexDump(bytes)+suffix;
}
}
function b64ToBytes(b64){
var bin=atob(b64),bytes=new Uint8Array(bin.length);
for(var i=0;i<bin.length;i++)bytes[i]=bin.charCodeAt(i);
return bytes;
}
function tryUtf8(bytes){
try{
var text=new TextDecoder('utf-8',{fatal:true}).decode(bytes);
var printable=0;
for(var i=0;i<Math.min(text.length,200);i++){var c=text.charCodeAt(i);if(c>=32||c===10||c===13||c===9)printable++;}
return(printable/Math.min(text.length,200))>0.85?text:null;
}catch(e){return null;}
}
function tryJsonPretty(text){
try{return JSON.stringify(JSON.parse(text),null,2);}catch(e){return null;}
}
function hexDump(bytes){
var lines=[];
for(var i=0;i<bytes.length;i+=16){
var chunk=Array.from(bytes.slice(i,i+16));
var hex=chunk.map(function(b){return b.toString(16).padStart(2,'0');}).join(' ');
var asc=chunk.map(function(b){return b>=32&&b<127?String.fromCharCode(b):'.';}).join('');
lines.push(i.toString(16).padStart(8,'0')+' '+hex.padEnd(48)+' '+asc);
}
return lines.join('\n');
}
function copyBody(){
if(!detailFull)return;
var b64=detailTab==='res'?detailFull.resBody:detailFull.reqBody;
if(!b64)return;
if(b64.endsWith('==TRUNCATED=='))b64=b64.slice(0,b64.length-13);
var text=tryUtf8(b64ToBytes(b64))||b64;
navigator.clipboard&&navigator.clipboard.writeText(text);
}
function closeDetail(){
detailId=null;
detailFull=null;
q('detail').style.display='none';
q('ne').querySelectorAll('.net-row').forEach(function(r){r.classList.remove('selected');});
}
// ---- Shared ----
function filter(listId,filterId){
var f=q(filterId).value.toLowerCase();
q(listId).querySelectorAll('.log-row').forEach(function(el){