From 7553790b5a6a84e2e8ad21235e9ff5d8b5599936 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 8 Mar 2026 11:47:19 +0100 Subject: [PATCH] fix: keep log panel persistent and scrollable after sync completes - Remove auto-reload after job completion - Re-enable button and refresh stats in-place via /status fetch - Increase log panel max-height to 600px, add resize:vertical - Add IDs to stat cells for targeted DOM updates Co-Authored-By: Claude Sonnet 4.6 --- webui.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/webui.py b/webui.py index 49d8086..287c6de 100644 --- a/webui.py +++ b/webui.py @@ -340,7 +340,7 @@ h2{margin:0 0 16px;font-size:1.1rem} .row{display:flex;gap:12px;flex-wrap:wrap;align-items:center} .alert{padding:12px 16px;border-radius:6px;margin-bottom:12px} .alert-warn{background:#fff3cd;border:1px solid #ffc107;color:#664d03} -#output{background:#1a1a2e;color:#d0d0e0;border-radius:8px;padding:16px;font-family:monospace;font-size:.85rem;min-height:60px;max-height:420px;overflow-y:auto;margin-top:16px;display:none} +#output{background:#1a1a2e;color:#d0d0e0;border-radius:8px;padding:16px;font-family:monospace;font-size:.85rem;min-height:80px;max-height:600px;overflow-y:auto;margin-top:16px;display:none;resize:vertical} #output .ln{padding:1px 0} #output .ln.ok{color:#6ee7b7} #output .ln.err{color:#fca5a5} @@ -361,6 +361,19 @@ tr:last-child td{border-bottom:none} """ _SCRIPT = r""" +async function refreshStats() { + try { + const r = await fetch('/status'); + if (!r.ok) return; + const s = await r.json(); + const set = (id, val) => { const el = document.getElementById(id); if (el) el.innerHTML = val; }; + set('stat-pull', s.last_pull ? s.last_pull : '—'); + set('stat-push', s.last_push ? s.last_push : '—'); + set('stat-pending', s.pending_count ?? '?'); + set('stat-status', s.vault_status ?? '?'); + } catch(e) {} +} + async function doSync(endpoint, label) { const btn = event.currentTarget; btn.disabled = true; @@ -383,8 +396,10 @@ async function doSync(endpoint, label) { div.className = 'ln done'; div.textContent = ev.message || 'Done.'; panel.appendChild(div); + panel.scrollTop = panel.scrollHeight; src.close(); - setTimeout(() => location.reload(), 1800); + btn.disabled = false; + refreshStats(); return; } const div = document.createElement('div'); @@ -476,11 +491,11 @@ async def dashboard():

Vault Status

{warn} -
-
{badge}
-
{pending}
-
{pull_html}
-
{push_html}
+
+
{badge}
+
{pending}
+
{pull_html}
+
{push_html}