← back to Dw Domain Viewer
Add 'Re-check all sites' control — re-probes fleet health, refreshes dots (no restart)
7aaf8849777b1c46dd131591c462c2182ae99044 · 2026-07-28 08:17:33 -0700 · Steve Abrams
Files touched
Diff
commit 7aaf8849777b1c46dd131591c462c2182ae99044
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jul 28 08:17:33 2026 -0700
Add 'Re-check all sites' control — re-probes fleet health, refreshes dots (no restart)
---
public/index.html | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 11 deletions(-)
diff --git a/public/index.html b/public/index.html
index 7724fc2..ef69a11 100644
--- a/public/index.html
+++ b/public/index.html
@@ -16,6 +16,11 @@
#rail h1 small { color:var(--dim); font-weight:400; }
#q { width:100%; padding:7px 10px; border-radius:7px; border:1px solid var(--line); background:var(--bg); color:var(--txt); outline:none; }
#q:focus { border-color:var(--accent); }
+ #recheck { width:100%; margin-top:8px; padding:7px 10px; border-radius:7px; border:1px solid var(--line); background:var(--bg); color:var(--txt); cursor:pointer; font-size:13px; }
+ #recheck:hover:not(:disabled) { border-color:var(--accent); color:var(--accent); }
+ #recheck:disabled { opacity:.6; cursor:progress; }
+ #recheck.busy { color:var(--accent); }
+ #lastcheck { display:block; margin-bottom:6px; color:var(--dim); }
#list { flex:1; overflow-y:auto; padding:6px; }
.item { display:flex; align-items:center; gap:8px; padding:6px 9px; border-radius:7px; cursor:pointer; color:var(--txt); user-select:none; }
.item:hover { background:#1e2530; }
@@ -47,9 +52,10 @@
<header>
<h1>designerwallcoverings.com <small id="count"></small></h1>
<input id="q" type="search" placeholder="Filter sites…" autocomplete="off">
+ <button id="recheck" title="Re-run the health check on every site (no restart — just re-probes reachability)">↻ Re-check all sites</button>
</header>
<div id="list"></div>
- <div id="foot">click a site → renders in the right panel (unified admin pw auto-applied) · dot: <span style="color:#3fbf6f">up</span> / <span style="color:#d9a53a">auth-gated</span> / <span style="color:#d95555">down or pw rejected</span></div>
+ <div id="foot"><span id="lastcheck"></span>click a site → renders in the right panel (unified admin pw auto-applied) · dot: <span style="color:#3fbf6f">up</span> / <span style="color:#d9a53a">auth-gated</span> / <span style="color:#d95555">down or pw rejected</span></div>
</div>
<div id="main">
<div id="bar">
@@ -109,6 +115,40 @@ document.getElementById('reload').onclick = () => { if (current) frame.src = '/s
document.getElementById('newtab').onclick = () => { if (current) window.open('https://' + current, '_blank', 'noopener'); };
q.oninput = render;
+const recheck = document.getElementById('recheck');
+const lastcheck = document.getElementById('lastcheck');
+
+// Re-run the health probe across every site and refresh the dots. This is a
+// re-CHECK, not a restart — it only re-tests reachability, so it's safe to click
+// anytime. Guarded against double-fires: the probe takes ~60-90s for 172 sites.
+let checking = false;
+async function loadStatus() {
+ if (checking) return;
+ checking = true;
+ recheck.disabled = true;
+ recheck.classList.add('busy');
+ recheck.textContent = '↻ Checking…';
+ try {
+ const sres = await fetch('/api/status');
+ if (!sres.ok) throw new Error('status HTTP ' + sres.status);
+ const st = await sres.json();
+ for (const s of st) status[s.domain] = s;
+ render();
+ const up = st.filter(s => s.up).length;
+ lastcheck.textContent = `checked ${up}/${st.length} up · ${new Date().toLocaleTimeString([], { hour:'numeric', minute:'2-digit', second:'2-digit' })}`;
+ } catch (e) {
+ // Aborted mid-flight (tab closed / server restarted) must not surface as an
+ // unhandled rejection; the list already rendered, dots are best-effort.
+ lastcheck.textContent = 'check failed — click ↻ to retry';
+ } finally {
+ checking = false;
+ recheck.disabled = false;
+ recheck.classList.remove('busy');
+ recheck.textContent = '↻ Re-check all sites';
+ }
+}
+recheck.onclick = loadStatus;
+
(async () => {
try {
const dres = await fetch('/api/domains');
@@ -120,16 +160,7 @@ q.oninput = render;
count.textContent = '(load failed — reload)';
return;
}
- // Health dots load after the list — probes take ~60-90s for 180 domains. A fetch
- // aborted mid-flight (tab closed, server restarted) must not surface as an
- // unhandled rejection; the list already rendered, dots are best-effort.
- try {
- const sres = await fetch('/api/status');
- if (!sres.ok) throw new Error('status HTTP ' + sres.status);
- const st = await sres.json();
- for (const s of st) status[s.domain] = s;
- render();
- } catch (e) { /* dots stay grey; next reload retries */ }
+ loadStatus();
})();
</script>
</body>
← af1ed5d fleet green pass: certs+443 for 4 vendor landings, 8 dead DN
·
back to Dw Domain Viewer
·
(newest)