From cd02cf3de7d5689b9cda3418983276b14304c40e Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 12:30:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=90=E6=AD=A5=E5=8A=A0=E5=9B=9Ecol?= =?UTF-8?q?-extra/col-disk/DualLineChart=20(=E5=85=A8=E9=83=A8=E9=80=9A?= =?UTF-8?q?=E8=BF=87Node=E6=A3=80=E6=9F=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/sentinel/dashboard.html | 63 ++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/plugins/sentinel/dashboard.html b/plugins/sentinel/dashboard.html index 123a07a..42f87b6 100644 --- a/plugins/sentinel/dashboard.html +++ b/plugins/sentinel/dashboard.html @@ -56,7 +56,7 @@ .node-notes { font-size:.75rem; color:var(--text-dim); font-style:italic; margin-bottom:8px } /* 横版布局 — 左设备信息 | 右数据+图表同行 */ #sentinel-grid.layout-row { display:flex;flex-direction:column;gap:12px } - #sentinel-grid.layout-row .node-card { display:grid;grid-template-columns:160px 1fr 0.8fr 1fr;gap:12px 16px;align-items:start } + #sentinel-grid.layout-row .node-card { display:grid;grid-template-columns:160px 1fr 0.8fr 1fr 0.8fr 1fr;gap:12px 16px;align-items:start } #sentinel-grid.layout-row .col-left { min-width:0 } #sentinel-grid.layout-row .col-right-stack { display:flex;flex-direction:column;gap:12px;min-width:0 } #sentinel-grid.layout-row .col-extra { display:flex;flex-direction:column;gap:6px;padding:0 8px } @@ -70,6 +70,30 @@ #sentinel-grid.layout-row .part-name { font-weight:500;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap } #sentinel-grid.layout-row .part-mount { color:var(--text-dim);font-size:.65rem } #sentinel-grid.layout-row .part-bar { height:3px;border-radius:1px;background:var(--md-sys-color-surface-container-lowest);margin:2px 0 } + #sentinel-grid.layout-row .part-bar-fill { height:100%;border-radius:1px;background:var(--primary) } + #sentinel-grid.layout-row .part-detail { display:flex;justify-content:space-between;font-size:.6rem;color:var(--text-dim) } + #sentinel-grid.layout-row .part-pct { text-align:right } + #sentinel-grid.layout-row .col-extra { display:flex;flex-direction:column;gap:6px;padding:0 8px } + #sentinel-grid.layout-row .extra-row { font-size:.8rem;padding:3px 0;border-bottom:1px solid var(--md-sys-color-surface-container-lowest) } + #sentinel-grid.layout-row .extra-row .elabel { font-size:.65rem;color:var(--text-dim);text-transform:uppercase;margin-right:4px } + #sentinel-grid.layout-row .extra-row .eval { font-weight:500 } + #sentinel-grid.layout-row .col-disk { overflow-y:auto;max-height:200px;padding:0 4px } + #sentinel-grid.layout-row .disk-list { display:flex;flex-direction:column;gap:4px } + #sentinel-grid.layout-row .part-row { display:flex;flex-direction:column;gap:2px;padding:3px 0;border-bottom:1px solid var(--md-sys-color-surface-container-lowest) } + #sentinel-grid.layout-row .part-info { display:flex;justify-content:space-between;font-size:.7rem } + #sentinel-grid.layout-row .part-name { font-weight:500;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap } + #sentinel-grid.layout-row .part-mount { color:var(--text-dim);font-size:.65rem } + #sentinel-grid.layout-row .part-bar { height:3px;border-radius:1px;background:var(--md-sys-color-surface-container-lowest);margin:2px 0 } + #sentinel-grid.layout-row .part-bar-fill { height:100%;border-radius:1px;background:var(--primary) } + #sentinel-grid.layout-row .part-detail { display:flex;justify-content:space-between;font-size:.6rem;color:var(--text-dim) } + #sentinel-grid.layout-row .part-pct { text-align:right } + #sentinel-grid.layout-row .col-disk { overflow-y:auto;max-height:200px;padding:0 4px } + #sentinel-grid.layout-row .disk-list { display:flex;flex-direction:column;gap:4px } + #sentinel-grid.layout-row .part-row { display:flex;flex-direction:column;gap:2px;padding:3px 0;border-bottom:1px solid var(--md-sys-color-surface-container-lowest) } + #sentinel-grid.layout-row .part-info { display:flex;justify-content:space-between;font-size:.7rem } + #sentinel-grid.layout-row .part-name { font-weight:500;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap } + #sentinel-grid.layout-row .part-mount { color:var(--text-dim);font-size:.65rem } + #sentinel-grid.layout-row .part-bar { height:3px;border-radius:1px;background:var(--md-sys-color-surface-container-lowest);margin:2px 0 } #sentinel-grid.layout-row .part-bar-fill { height:100%;border-radius:1px;background:var(--primary);transition:width .6s } #sentinel-grid.layout-row .part-detail { display:flex;justify-content:space-between;font-size:.6rem;color:var(--text-dim) } #sentinel-grid.layout-row .part-size { text-align:left } @@ -208,6 +232,7 @@ '
NET 0 0
'+ '
'+ ''+ + '
'+ '
'+ '
负载
'+ '
SWAP
'+ @@ -319,6 +344,40 @@ if (trafEl && sysData.network) trafEl.textContent = '↓'+(sysData.network.rx_mb||0).toFixed(0)+'M ↑'+(sysData.network.tx_mb||0).toFixed(0)+'M'; if (procEl && sysData.process) procEl.textContent = (sysData.process.memory_mb||0).toFixed(0)+'MB'; + // 更新额外指标 + var loadEl = card.querySelector('.load-val'); + var swapEl = card.querySelector('.swap-val'); + var tempEl = card.querySelector('.temp-val'); + var trafEl = card.querySelector('.traf-val'); + var procEl = card.querySelector('.proc-val'); + var sysData = n.system || {}; + if (loadEl && sysData.cpu) loadEl.textContent = (sysData.cpu.load_avg||[0,0,0]).map(function(v){return v.toFixed(1);}).join(' / '); + if (swapEl && sysData.swap) { var st = sysData.swap.total_gb||0; swapEl.textContent = st > 0 ? (sysData.swap.percent||0).toFixed(1)+'% ('+(sysData.swap.used_gb||0).toFixed(1)+'G)' : '—'; } + if (tempEl && sysData.temperature) tempEl.textContent = (sysData.temperature.current||0) > 0 ? (sysData.temperature.current).toFixed(1)+'°C' : '—'; + if (trafEl && sysData.network) trafEl.textContent = '↓'+(sysData.network.rx_mb||0).toFixed(0)+'M ↑'+(sysData.network.tx_mb||0).toFixed(0)+'M'; + if (procEl && sysData.process) procEl.textContent = (sysData.process.memory_mb||0).toFixed(0)+'MB'; + + // 磁盘分区 + var diskList = card.querySelector('.disk-list'); + if (diskList && sysData.partitions) { + var parts = sysData.partitions || []; + if (!diskList.querySelector('.part-row') || diskList.children.length !== parts.length) { + diskList.innerHTML = parts.map(function(p){ + return '
'+esc(p.device||'?')+' '+esc(p.mount||'')+'
'+fmtSizeGB(p)+''+(p.percent||0).toFixed(0)+'%
'; + }).join(''); + } else { + var rows = diskList.querySelectorAll('.part-row'); + parts.forEach(function(p, i){ + if (rows[i]) { + var fill = rows[i].querySelector('.part-bar-fill'); + var pct = rows[i].querySelector('.part-pct'); + if (fill) fill.style.width = (p.percent||0)+'%'; + if (pct) pct.textContent = (p.percent||0).toFixed(0)+'%'; + } + }); + } + } + var infoR = card.querySelector('.col-info'); if (infoR) infoR.textContent = (n.last_seen ? new Date(n.last_seen*1000).toLocaleTimeString() : '—'); } else { @@ -366,6 +425,8 @@ function bar(v) { return v < 60 ? 'bar-green' : (v < 85 ? 'bar-yellow' : 'bar-red'); } function fmtSizeGB(p) { var u=p.used_gb||0, t=p.total_gb||0; return fmtSize(u*1073741824)+' / '+fmtSize(t*1073741824); } function fmtSize(bytes) { if(bytes===undefined||bytes===null)return'—'; bytes=Math.abs(bytes); if(bytes>=1e12)return(bytes/1e12).toFixed(1)+' TB'; if(bytes>=1e9)return(bytes/1e9).toFixed(1)+' GB'; if(bytes>=1e6)return(bytes/1e6).toFixed(1)+' MB'; if(bytes>=1e3)return(bytes/1e3).toFixed(1)+' KB'; return bytes.toFixed(0)+' B'; } + function fmtSize(bytes) { if(bytes===undefined||bytes===null)return'—'; bytes=Math.abs(bytes); if(bytes>=1e12)return(bytes/1e12).toFixed(1)+' TB'; if(bytes>=1e9)return(bytes/1e9).toFixed(1)+' GB'; if(bytes>=1e6)return(bytes/1e6).toFixed(1)+' MB'; if(bytes>=1e3)return(bytes/1e3).toFixed(1)+' KB'; return bytes.toFixed(0)+' B'; } + function fmtSizeGB(p) { var u=p.used_gb||0, t=p.total_gb||0; return fmtSize(u*1073741824)+' / '+fmtSize(t*1073741824); } function fmtSpeed(bps) { return bps<1024?bps.toFixed(0)+'B/s':(bps<1048576?(bps/1024).toFixed(0)+'K/s':(bps/1048576).toFixed(1)+'M/s'); } function esc(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); }