Fix Gateway events table layout, merge Disk stats, color Runtime values by threshold
This commit is contained in:
@@ -598,7 +598,7 @@ function heroSlotsMarkup(prefix, slots) {
|
||||
}
|
||||
function setHeroStat(prefix, key, { value, percent, detail, tone } = {}) {
|
||||
const valueEl = document.querySelector(`#${prefix}-${key}-value`), fillEl = document.querySelector(`#${prefix}-${key}-fill`), detailEl = document.querySelector(`#${prefix}-${key}-detail`);
|
||||
if (valueEl) valueEl.textContent = value ?? "\u2014";
|
||||
if (valueEl) { valueEl.textContent = value ?? "\u2014"; valueEl.className = `system-hero-value${tone ? ` ${tone}` : ""}`; }
|
||||
if (fillEl) { fillEl.style.width = `${Math.max(0, Math.min(100, percent ?? 0))}%`; fillEl.className = `system-hero-fill${tone ? ` ${tone}` : ""}`; }
|
||||
if (detailEl) detailEl.textContent = detail || "";
|
||||
}
|
||||
@@ -632,7 +632,7 @@ function renderHeroPanel(prefix, health, { sixthSlot = "throughput" } = {}) {
|
||||
else setHeroStat(prefix, "swap", { value: "\u2014", detail: "cgroup swap stats unavailable" });
|
||||
if (health.disk) {
|
||||
const overAssigned = health.disk.assignedLimitBytes && health.disk.percent > 100;
|
||||
const diskDetail = health.disk.assignedLimitBytes ? `${formatBytes(health.disk.usedBytes)} used of ${formatBytes(health.disk.assignedLimitBytes)} assigned` : `${formatBytes(health.disk.usedBytes)} used \u00b7 ${formatBytes(health.disk.availableBytes)} free`;
|
||||
const diskDetail = health.disk.assignedLimitBytes ? `${formatBytes(health.disk.usedBytes)} used of ${formatBytes(health.disk.assignedLimitBytes)} assigned \u00b7 ${formatBytes(health.disk.availableBytes)} free on host` : `${formatBytes(health.disk.usedBytes)} used \u00b7 ${formatBytes(health.disk.availableBytes)} free`;
|
||||
setHeroStat(prefix, "disk", { value: `${health.disk.percent.toFixed(1)}%`, percent: Math.min(100, health.disk.percent), tone: overAssigned ? "critical" : tone(health.disk.percent), detail: diskDetail });
|
||||
}
|
||||
else setHeroStat(prefix, "disk", { value: "\u2014", detail: "Disk stats unavailable" });
|
||||
@@ -764,9 +764,11 @@ async function renderSystemStatus(panel) {
|
||||
{ ok: sec.acmeEmailConfigured, label: "ACME_EMAIL", detail: sec.acmeEmailConfigured ? "Configured." : "Not set \u2014 certificate issuance will proceed without a registration contact." },
|
||||
].map(row => `<div class="health-tile"><span class="status-dot ${row.ok ? "running" : "idle"}"></span><span class="health-tile-copy"><strong>${row.label}</strong><small>${row.detail}</small></span></div>`).join("");
|
||||
if (storage) {
|
||||
// Host disk capacity (free/total) now lives on the Runtime hero panel's Disk stat detail
|
||||
// line instead of duplicating it here -- this breakdown stays scoped to what Site Gateway
|
||||
// itself is storing (Sites, Backups, Certificates, Logs, Database).
|
||||
const rows = Object.entries(store.breakdown || {}).map(([key, bytes]) => `<div class="health-tile"><span class="status-dot running"></span><span class="health-tile-copy"><strong>${key[0].toUpperCase()}${key.slice(1)}</strong><small>${formatBytes(bytes)}</small></span></div>`).join("");
|
||||
const capacity = store.capacity ? `<div class="health-tile"><span class="status-dot ${store.capacity.availableBytes / store.capacity.totalBytes > 0.1 ? "running" : "idle"}"></span><span class="health-tile-copy"><strong>Disk</strong><small>${formatBytes(store.capacity.availableBytes)} free of ${formatBytes(store.capacity.totalBytes)}</small></span></div>` : "";
|
||||
storage.innerHTML = rows + capacity || '<p class="quiet-state">Storage usage unavailable.</p>';
|
||||
storage.innerHTML = rows || '<p class="quiet-state">Storage usage unavailable.</p>';
|
||||
}
|
||||
if (restartButton) { restartButton.disabled = !policy.restartAvailable; if (restartStatus) restartStatus.textContent = policy.reason || (policy.policyName ? `Restart policy: ${policy.policyName}.` : ""); }
|
||||
} catch { /* Status widgets keep their last-known values if a refresh call fails. */ }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<title>Site Gateway</title>
|
||||
<meta name="description" content="Host sites, proxy services, and manage HTTPS from one simple dashboard.">
|
||||
<link rel="icon" type="image/png" href="/site-gateway-icon-approved.png">
|
||||
<link rel="stylesheet" href="/styles.css?v=0.16.56">
|
||||
<link rel="stylesheet" href="/styles.css?v=0.16.57">
|
||||
</head>
|
||||
|
||||
<!-- ================================================================
|
||||
@@ -451,6 +451,6 @@
|
||||
<div id="toast" class="toast" role="status"></div>
|
||||
<div id="update-banner" class="update-banner hidden" role="status"><span>A new version of Site Gateway is available.</span><div class="update-banner-actions"><button id="update-banner-refresh" class="button primary">Refresh</button><button id="update-banner-dismiss" class="text-button">Dismiss</button></div></div>
|
||||
<!-- App scripts: core (app.js) then extended views/admin (features.js) -->
|
||||
<script src="/app.js?v=0.16.56" defer></script><script src="/features.js?v=0.16.56" defer></script><script src="/select-enhance.js?v=0.16.56" defer></script>
|
||||
<script src="/app.js?v=0.16.57" defer></script><script src="/features.js?v=0.16.57" defer></script><script src="/select-enhance.js?v=0.16.57" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -256,10 +256,11 @@ header{align-items:flex-end}
|
||||
.upstream-copy.idle{color:var(--warning)}
|
||||
.event-table-wrap{max-height:min(52vh,620px);overflow:auto;margin-top:var(--space-4)}
|
||||
.event-table-wrap .event-table thead th{position:sticky;top:0;background:var(--panel);z-index:1}
|
||||
.event-table th:nth-child(1),.event-table td:nth-child(1){width:15%;white-space:nowrap}
|
||||
.event-table th:nth-child(2),.event-table td:nth-child(2){width:11%;white-space:nowrap}
|
||||
.event-table th:nth-child(3),.event-table td:nth-child(3){width:14%;white-space:nowrap}
|
||||
.event-table th:nth-child(1),.event-table td:nth-child(1){width:190px;white-space:nowrap}
|
||||
.event-table th:nth-child(2),.event-table td:nth-child(2){width:110px;white-space:nowrap}
|
||||
.event-table th:nth-child(3),.event-table td:nth-child(3){width:140px;white-space:nowrap}
|
||||
.event-table th:nth-child(4),.event-table td:nth-child(4){white-space:normal;overflow-wrap:anywhere}
|
||||
@media(max-width:900px){.event-table th:nth-child(1),.event-table td:nth-child(1){width:150px}}
|
||||
.event-table td .status-dot{margin-right:6px;vertical-align:-1px}
|
||||
.activity-mark.bad{background:rgba(var(--danger-rgb),.12);color:var(--danger)}
|
||||
.feature-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-bottom:18px}
|
||||
@@ -848,6 +849,7 @@ select{appearance:none!important;-webkit-appearance:none!important;background-re
|
||||
.readiness-panel,.log-activity{background:transparent;border:0;padding:0}
|
||||
.readiness-panel .panel-heading,.log-activity .panel-heading{margin:20px 0 0;padding:18px 20px;border:1px solid var(--line);border-bottom:0;border-radius:var(--radius-2xl) 15px 0 0;background:var(--panel)}
|
||||
.log-activity .event-filters{margin:0;padding:0 20px 15px;border-left:1px solid var(--line);border-right:1px solid var(--line);background:var(--panel)}
|
||||
.log-activity .event-table-wrap{border-top:0;border-radius:0 0 15px 15px;margin-top:0}
|
||||
.log-activity .diagnostic-list{border:1px solid var(--line);border-radius:0 0 15px 15px;background:var(--panel);overflow:auto}
|
||||
.log-activity .event-row{gap:var(--space-4);padding:18px 20px;align-items:center}
|
||||
.log-activity .event-row .status-dot{flex:0 0 8px}
|
||||
@@ -1009,6 +1011,8 @@ select{appearance:none!important;-webkit-appearance:none!important;background-re
|
||||
.system-hero-stat{min-width:0;display:flex;flex-direction:column;gap:6px}
|
||||
.system-hero-label{color:var(--muted);font-size:var(--font-size-sm);font-weight:650;text-transform:uppercase;letter-spacing:.04em}
|
||||
.system-hero-value{font-size:1.5rem;font-weight:800;line-height:1.1}
|
||||
.system-hero-value.warning{color:var(--warning)}
|
||||
.system-hero-value.critical{color:var(--danger)}
|
||||
.system-hero-bar{height:6px;border-radius:var(--radius-full);background:rgba(var(--bg-rgb),.4);overflow:hidden}
|
||||
.system-hero-fill{height:100%;border-radius:var(--radius-full);background:var(--green);transition:width .4s ease}
|
||||
.system-hero-fill.warning{background:var(--warning)}
|
||||
|
||||
Reference in New Issue
Block a user