From e6078b9c89214797b5aaa4e76b6b39a4dd0fe959 Mon Sep 17 00:00:00 2001 From: naturallaw77 Date: Tue, 8 Sep 2026 22:51:14 +0000 Subject: [PATCH] Simplify Systems Operational, reword Domain Status, blue restart buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restart and retry actions (topbar Reboot, Restart Entire System in the update and rebuild dialogs and the restart confirmation, Retry Update, Try Again) are now blue instead of amber — amber read as an error. Status pills keep their semantic colors (amber = restart required). - The service-modal domain section is no longer a checklist: it is titled "Domain Status" and shows a single green "Domain is active" line with the domain (or the backend's not-configured detail and Configure Domain action when there is no domain yet). No "Step 1" wording. - Systems Operational keeps the complexity hidden: the Router card now shows just a verdict — green "Ports 80 and 443 are open" or red "Ports 80 and 443 are not open" — derived from the same live backend diagnostics. Port-forwarding instructions are gone (onboarding covers them); on the Node-only role the card still explains that ports only matter once BTCPay Server or Lightning Wallet Connections (LNURL) is enabled. --- .../static/css/buttons.css | 23 ++++--- .../static/js/dashboard.js | 67 +++++++------------ .../static/js/service-detail.js | 24 ++++--- 3 files changed, 50 insertions(+), 64 deletions(-) diff --git a/app/sovran_systemsos_web/static/css/buttons.css b/app/sovran_systemsos_web/static/css/buttons.css index c90487d..2276dcd 100644 --- a/app/sovran_systemsos_web/static/css/buttons.css +++ b/app/sovran_systemsos_web/static/css/buttons.css @@ -62,22 +62,23 @@ button:disabled { background: rgba(255, 255, 255, 0.04); } -/* Amber — destructive-ish confirmations (restart, reboot, retry) */ +/* Blue — restart / retry actions (amber reads as an error) */ .btn-amber, .btn-reboot, .btn-restart-amber, .btn-warning { - background: rgba(233, 182, 74, 0.10); - border-color: rgba(233, 182, 74, 0.32); - color: #f2c45e; + background: rgba(120, 174, 237, 0.10); + border-color: rgba(120, 174, 237, 0.35); + color: #a5cbf2; } .btn-amber:hover:not(:disabled), .btn-reboot:hover:not(:disabled), .btn-restart-amber:hover:not(:disabled), .btn-warning:hover:not(:disabled) { - background: rgba(233, 182, 74, 0.18); - border-color: rgba(233, 182, 74, 0.5); + background: rgba(120, 174, 237, 0.18); + border-color: rgba(120, 174, 237, 0.55); + color: #c2dcf8; } .btn-danger { @@ -96,9 +97,9 @@ button:disabled { /* ── Header / topbar buttons ────────────────────────────────────── */ .btn-header-reboot { - background: rgba(233, 182, 74, 0.10); - border: 1px solid rgba(233, 182, 74, 0.32); - color: #f2c45e; + background: rgba(120, 174, 237, 0.10); + border: 1px solid rgba(120, 174, 237, 0.35); + color: #a5cbf2; font-size: 0.77rem; font-weight: 700; padding: 6px 14px; @@ -106,8 +107,8 @@ button:disabled { } .btn-header-reboot:hover:not(:disabled) { - background: rgba(233, 182, 74, 0.18); - border-color: rgba(233, 182, 74, 0.5); + background: rgba(120, 174, 237, 0.18); + border-color: rgba(120, 174, 237, 0.55); } .btn-logout { diff --git a/app/sovran_systemsos_web/static/js/dashboard.js b/app/sovran_systemsos_web/static/js/dashboard.js index fa397fc..803317e 100644 --- a/app/sovran_systemsos_web/static/js/dashboard.js +++ b/app/sovran_systemsos_web/static/js/dashboard.js @@ -208,12 +208,6 @@ /* ── Systems Operational modal ───────────────────────────────── */ - function internalIp() { - var el = document.getElementById("ip-internal"); - var v = el ? el.textContent.trim() : ""; - return (v && v !== "…" && v !== "—") ? v : ""; - } - function step(n, title, sub, value) { return '
' + n + '
' + '
' + title + (sub ? ' · ' + sub + '' : '') + '
' + @@ -250,9 +244,6 @@ else running++; }); - var ip = internalIp(); - var fwd = ip ? ('\u2192 ' + escHtml(ip)) : "forward to this computer"; - var html = ""; /* System status */ @@ -263,32 +254,23 @@ step(3, "Turned off", "", off ? escHtml(offNames.join(", ")) : "None") + '
'; - /* Router ports — repo wording (domain-prereqs.js / server.py). - Node-only role: ports matter only once BTCPay Server or Lightning - Wallet Connections (LNURL) is turned on — until then, no router task. */ + /* Router — a simple open / not-open verdict. How to open the ports is + covered during onboarding, so the modal does not repeat instructions. + Node-only role: ports only matter once BTCPay Server or Lightning + Wallet Connections (LNURL) is turned on. */ if (isNodeRole() && !hasEnabledDomainService(services)) { html += '
' + '
' + icon("g-wifi") + 'Router
' + '
' + icon("g-check") + 'No router setup needed yet
' + - '
Ports 80 and 443 only need to be forwarded on your router if you turn on BTCPay Server or Lightning Wallet Connections (LNURL). If you enable one of them, come back here — this card will show exactly what to do.
' + + '
Ports 80 and 443 only need to be forwarded on your router if you turn on BTCPay Server or Lightning Wallet Connections (LNURL). If you enable one of them, come back here to check your ports.
' + '
'; } else { - html += '
' + - '
' + icon("g-wifi") + 'Router — Ports to Forward
' + - step(1, "Port 80", "TCP — HTTP (redirect to HTTPS)", fwd) + - step(2, "Port 443", "TCP — HTTPS", fwd) + - '
' + icon("g-alert") + 'One router task
' + - '
Set the internal and external port to the same number. You only need to do this once — all your services share these two ports.
' + + html += ''; } - /* Live domain diagnostics (sequential checklist from the backend — - same data the domain-service modals show) */ - html += ''; - /* Who uses these ports (redundant on a Node install with no domain services on — the router note above already covers it) */ if (!isNodeRole() || hasEnabledDomainService(services)) { @@ -300,33 +282,32 @@ $sysBody.innerHTML = html; $sysModal.classList.add("open"); - /* Poll the first configured domain service for its live checklist */ - var checkCard = document.getElementById("sys-check-card"); - var stepsEl = document.getElementById("sys-check-steps"); + /* Poll the first configured domain service and reduce its diagnostics + to one verdict: the ports are open or they are not. */ + var portsCard = document.getElementById("sys-ports-card"); + var portsEl = document.getElementById("sys-ports-status"); var units = DOMAIN_UNITS.filter(function (u) { return services.some(function (s) { return s.unit === u && s.enabled; }); }); - if (!units.length || !checkCard || !stepsEl) return; - checkCard.style.display = ""; + if (!units.length || !portsCard || !portsEl) return; + portsCard.style.display = ""; apiFetch("/api/service-detail/" + encodeURIComponent(units[0])) .then(function (data) { var steps = (data && data.domain_check_steps) || []; - if (!steps.length) { checkCard.style.display = "none"; return; } - var mark = { ok: "\u2705", error: "\u274c", warning: "\u26a0\ufe0f", skipped: "\u23ed\ufe0f" }; - var html2 = ""; - steps.forEach(function (st) { - var m = mark[st.status] || "\u2014"; - var detail = escHtml(st.detail || "").replace(/\n/g, "
"); - html2 += '
' + st.step + '
' + - '
' + m + " " + escHtml(st.label || "") + '
' + - (detail ? '
' + detail + '
' : '') + - '
'; + var portsStep = null; + steps.forEach(function (s) { + if (Number(s.step) === 3 || /ports?\s*80/i.test(s.label || "")) portsStep = s; }); - stepsEl.innerHTML = html2; + if (!portsStep) { portsCard.style.display = "none"; return; } + if (portsStep.status === "ok") { + portsEl.innerHTML = '
Ports 80 and 443 are open
'; + } else { + portsEl.innerHTML = '
Ports 80 and 443 are not open
'; + } }) .catch(function () { - checkCard.style.display = "none"; + portsCard.style.display = "none"; }); } diff --git a/app/sovran_systemsos_web/static/js/service-detail.js b/app/sovran_systemsos_web/static/js/service-detail.js index 41e4551..7f8b1a8 100644 --- a/app/sovran_systemsos_web/static/js/service-detail.js +++ b/app/sovran_systemsos_web/static/js/service-detail.js @@ -725,16 +725,20 @@ async function openServiceDetailModal(unit, name, icon) { }); var stepsHtml = ""; steps.forEach(function(step) { - var iconLabel = "—"; - if (step.status === "ok") iconLabel = "✅"; - else if (step.status === "error") iconLabel = "❌"; - else if (step.status === "warning") iconLabel = "⚠️"; - else if (step.status === "skipped") iconLabel = "⏭️"; var detail = escHtml(step.detail || "").replace(/\n/g, "
"); - stepsHtml += '
' + - '' + iconLabel + ' Step ' + escHtml(String(step.step)) + ': ' + escHtml(step.label || "") + '' + - (detail ? '
' + detail + '
' : '') + - '
'; + if (step.status === "ok") { + // Not a checklist anymore — just note that the domain works. + stepsHtml += '
Domain is active
' + + (detail ? '
' + detail + '
' : ''); + } else { + var iconLabel = "❌"; + if (step.status === "warning") iconLabel = "⚠️"; + else if (step.status === "skipped") iconLabel = "⏭️"; + stepsHtml += '
' + + '' + iconLabel + ' ' + escHtml(step.label || "Domain not configured") + '' + + (detail ? '
' + detail + '
' : '') + + '
'; + } }); var domainActionHtml = ""; @@ -746,7 +750,7 @@ async function openServiceDetailModal(unit, name, icon) { } addSetup('
' + - '
Domain Diagnostic Checklist
' + + '
Domain Status
' + stepsHtml + domainActionHtml + '
');