fix(hub): color host status summary metrics green/red and bust css cache
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -695,7 +695,6 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.host-status-summary-text {
|
.host-status-summary-text {
|
||||||
color: var(--muted);
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -704,6 +703,27 @@ button:disabled {
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.host-status-summary-text.bad {
|
||||||
|
color: var(--red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-summary-host,
|
||||||
|
.host-summary-sep {
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-metric-tone.ok,
|
||||||
|
.host-metric-val.ok {
|
||||||
|
color: var(--green);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-metric-tone.bad,
|
||||||
|
.host-metric-val.bad {
|
||||||
|
color: var(--red);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.host-status-bar {
|
.host-status-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -161,18 +161,56 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hostStatusSummaryText(data) {
|
function hostMetricSummaryHtml(label, percent) {
|
||||||
if (!data || !data.ok) return (data && data.msg) || "状态不可用";
|
const p = Number(percent);
|
||||||
|
if (!Number.isFinite(p)) {
|
||||||
|
return esc(label) + " —";
|
||||||
|
}
|
||||||
|
const tone = hostMetricLevel(p);
|
||||||
|
return (
|
||||||
|
esc(label) +
|
||||||
|
' <span class="host-metric-tone ' +
|
||||||
|
tone +
|
||||||
|
'">' +
|
||||||
|
p +
|
||||||
|
"%</span>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderHostStatusSummary(data, el) {
|
||||||
|
if (!el) return;
|
||||||
|
if (!data || !data.ok) {
|
||||||
|
el.className = "host-status-summary-text bad";
|
||||||
|
el.textContent = (data && data.msg) || "状态不可用";
|
||||||
|
return;
|
||||||
|
}
|
||||||
const cpu = data.cpu || {};
|
const cpu = data.cpu || {};
|
||||||
const mem = data.memory || {};
|
const mem = data.memory || {};
|
||||||
const disk = data.disk || {};
|
const disk = data.disk || {};
|
||||||
const parts = [];
|
const parts = [];
|
||||||
const host = String(data.hostname || "").trim();
|
const host = String(data.hostname || "").trim();
|
||||||
if (host) parts.push(host);
|
if (host) {
|
||||||
if (cpu.percent != null) parts.push("CPU " + cpu.percent + "%");
|
parts.push('<span class="host-summary-host">' + esc(host) + "</span>");
|
||||||
if (mem.percent != null) parts.push("内存 " + mem.percent + "%");
|
}
|
||||||
if (disk.percent != null) parts.push("硬盘 " + disk.percent + "%");
|
if (cpu.percent != null) parts.push(hostMetricSummaryHtml("CPU", cpu.percent));
|
||||||
return parts.join(" · ") || "—";
|
if (mem.percent != null) parts.push(hostMetricSummaryHtml("内存", mem.percent));
|
||||||
|
if (disk.percent != null) parts.push(hostMetricSummaryHtml("硬盘", disk.percent));
|
||||||
|
el.className = "host-status-summary-text";
|
||||||
|
el.innerHTML = parts.length
|
||||||
|
? parts.join(' <span class="host-summary-sep">·</span> ')
|
||||||
|
: "—";
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHostMetricVal(el, percent) {
|
||||||
|
if (!el) return;
|
||||||
|
const p = Number(percent);
|
||||||
|
el.classList.remove("ok", "bad");
|
||||||
|
if (!Number.isFinite(p)) {
|
||||||
|
el.textContent = "—";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.textContent = p + "%";
|
||||||
|
el.classList.add(hostMetricLevel(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
let hostStatusPanelInited = false;
|
let hostStatusPanelInited = false;
|
||||||
@@ -208,7 +246,7 @@
|
|||||||
const netUp = document.getElementById("host-net-up");
|
const netUp = document.getElementById("host-net-up");
|
||||||
const netDown = document.getElementById("host-net-down");
|
const netDown = document.getElementById("host-net-down");
|
||||||
panel.classList.remove("hidden");
|
panel.classList.remove("hidden");
|
||||||
if (summaryText) summaryText.textContent = hostStatusSummaryText(data);
|
renderHostStatusSummary(data, summaryText);
|
||||||
if (!data || !data.ok) {
|
if (!data || !data.ok) {
|
||||||
if (dot) dot.className = "host-status-dot bad";
|
if (dot) dot.className = "host-status-dot bad";
|
||||||
if (name) {
|
if (name) {
|
||||||
@@ -244,14 +282,14 @@
|
|||||||
setHostMetricBar(document.getElementById("host-cpu-fill"), cpu.percent);
|
setHostMetricBar(document.getElementById("host-cpu-fill"), cpu.percent);
|
||||||
setHostMetricBar(document.getElementById("host-mem-fill"), mem.percent);
|
setHostMetricBar(document.getElementById("host-mem-fill"), mem.percent);
|
||||||
setHostMetricBar(document.getElementById("host-disk-fill"), disk.percent);
|
setHostMetricBar(document.getElementById("host-disk-fill"), disk.percent);
|
||||||
if (cpuVal) cpuVal.textContent = cpu.percent != null ? cpu.percent + "%" : "—";
|
setHostMetricVal(cpuVal, cpu.percent);
|
||||||
|
setHostMetricVal(memVal, mem.percent);
|
||||||
|
setHostMetricVal(diskVal, disk.percent);
|
||||||
if (cpuSub) cpuSub.textContent = cpu.count ? cpu.count + " 核" : "";
|
if (cpuSub) cpuSub.textContent = cpu.count ? cpu.count + " 核" : "";
|
||||||
if (memVal) memVal.textContent = mem.percent != null ? mem.percent + "%" : "—";
|
|
||||||
if (memSub) {
|
if (memSub) {
|
||||||
memSub.textContent =
|
memSub.textContent =
|
||||||
fmtHostBytes(mem.used_bytes) + " / " + fmtHostBytes(mem.total_bytes);
|
fmtHostBytes(mem.used_bytes) + " / " + fmtHostBytes(mem.total_bytes);
|
||||||
}
|
}
|
||||||
if (diskVal) diskVal.textContent = disk.percent != null ? disk.percent + "%" : "—";
|
|
||||||
if (diskSub) {
|
if (diskSub) {
|
||||||
diskSub.textContent =
|
diskSub.textContent =
|
||||||
fmtHostBytes(disk.used_bytes) + " / " + fmtHostBytes(disk.total_bytes);
|
fmtHostBytes(disk.used_bytes) + " / " + fmtHostBytes(disk.total_bytes);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
||||||
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
||||||
<link rel="stylesheet" href="/assets/app.css?v=20260612-archive-ai-chat" />
|
<link rel="stylesheet" href="/assets/app.css?v=20260613-host-status-tone" />
|
||||||
<link rel="stylesheet" href="/assets/dashboard.css?v=20260612-dash-monitor-count" />
|
<link rel="stylesheet" href="/assets/dashboard.css?v=20260612-dash-monitor-count" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -653,6 +653,6 @@
|
|||||||
<script src="/assets/dashboard.js?v=20260612-dash-monitor-count"></script>
|
<script src="/assets/dashboard.js?v=20260612-dash-monitor-count"></script>
|
||||||
<script src="/assets/ai_review_render.js?v=3"></script>
|
<script src="/assets/ai_review_render.js?v=3"></script>
|
||||||
<script src="/assets/time_close_ui.js?v=2"></script>
|
<script src="/assets/time_close_ui.js?v=2"></script>
|
||||||
<script src="/assets/app.js?v=20260613-host-status-threshold"></script>
|
<script src="/assets/app.js?v=20260613-host-status-tone"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user