Add accurate three-state coloring to the Certificates page Upstream column

This commit is contained in:
2026-09-20 11:06:43 -04:00
parent 0685f4ee84
commit a199806554
5 changed files with 7 additions and 5 deletions
+1 -2
View File
@@ -271,10 +271,9 @@ function renderCertificates() {
const cert = row.cert, item = row.readiness;
const dnsOk = item ? item.dns.healthy : null;
const tlsOk = item ? ["healthy", "warning", "critical", "not-configured"].includes(item.tls.status) : null;
const upstreamOk = item ? (!item.upstream || item.upstream.status === "healthy") : null;
const dnsCell = item ? `<span class="status-dot ${dnsOk ? "running" : "error"}"></span>${dnsOk ? "Resolved" : "Failed"}` : `<span class="status-dot idle"></span>—`;
const tlsCell = item ? `<span class="status-dot ${tlsOk ? "running" : "error"}"></span>${escapeHtml(item.tls.status.replaceAll("-", " "))}` : `<span class="status-dot idle"></span>—`;
const upstreamCell = item ? (item.upstream ? `<span class="status-dot ${upstreamOk ? "running" : "error"}"></span>${item.upstream.httpStatus ?? "no response"}` : `<span class="status-dot idle"></span>Not configured`) : `<span class="status-dot idle"></span>`;
const upstreamCell = !item ? `<span class="status-dot idle"></span>—` : !item.upstream || item.upstream.status === "unmonitored" ? `<span class="status-dot idle"></span>Monitoring paused` : item.upstream.status === "pending" ? `<span class="status-dot idle"></span>Check pending` : item.upstream.status === "healthy" ? `<span class="status-dot running"></span>${item.upstream.httpStatus}` : `<span class="status-dot bad"></span>${escapeHtml(item.upstream.error || "Unavailable")}`;
const statusLabel = cert.status === "mismatch" ? "Domain mismatch" : cert.status.charAt(0).toUpperCase() + cert.status.slice(1);
return `<tr class="cert-table-row" data-index="${index}" tabindex="0"><td><strong>${escapeHtml(cert.domain)}</strong><br><small class="muted">${escapeHtml(cert.kind)} · ${escapeHtml(cert.source)}</small></td><td><span class="status-dot ${cert.status === "healthy" ? "running" : cert.status === "pending" ? "idle" : "error"}"></span>${escapeHtml(statusLabel)}</td><td>${cert.expiresAt ? `${cert.daysRemaining} days` : "—"}</td><td>${escapeHtml(cert.issuer || "—")}</td><td>${dnsCell}</td><td>${tlsCell}</td><td>${upstreamCell}</td></tr>`;
}).join("") : '<tr><td colspan="7" class="quiet-state">No HTTPS domains are configured.</td></tr>';
+2 -2
View File
@@ -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.53">
<link rel="stylesheet" href="/styles.css?v=0.16.54">
</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.53" defer></script><script src="/features.js?v=0.16.53" defer></script><script src="/select-enhance.js?v=0.16.53" defer></script>
<script src="/app.js?v=0.16.54" defer></script><script src="/features.js?v=0.16.54" defer></script><script src="/select-enhance.js?v=0.16.54" defer></script>
</body>
</html>
+1
View File
@@ -52,6 +52,7 @@ h2{letter-spacing:-.025em}
.status-dot.running{background:var(--green);box-shadow:0 0 0 4px rgba(var(--green-rgb),.1)}
.status-dot.disabled{background:var(--danger);box-shadow:0 0 0 4px rgba(var(--danger-rgb),.09)}
.status-dot.error,.status-dot.idle{background:var(--warning);box-shadow:0 0 0 4px rgba(var(--warning-rgb),.09)}
.status-dot.bad{background:var(--danger);box-shadow:0 0 0 4px rgba(var(--danger-rgb),.09)}
/* Hosted Site / Proxy Host cards, card menu, and the toggle switch */
.site-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:18px}