Fix scan log dismiss button visibility and truncate error messages

Dismiss button is now always visible with a bordered style instead of
hidden-until-JS. Netmiko error messages are truncated to first line
(120 chars) so verbose multi-line errors don't flood the log panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-13 17:31:21 +00:00
parent 121ac18250
commit 93afa9192b
2 changed files with 12 additions and 14 deletions
+10 -13
View File
@@ -419,14 +419,16 @@ var Xr=function(e){if(!(this instanceof Xr))return new Xr(e);this.id="Thenable/1
.scan-log-dismiss { .scan-log-dismiss {
margin-left: auto; margin-left: auto;
background: none; background: none;
border: none; border: 1px solid #30363d;
color: #484f58; border-radius: 4px;
color: #8b949e;
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 13px;
padding: 0 4px; padding: 2px 7px;
line-height: 1; line-height: 1.4;
flex-shrink: 0;
} }
.scan-log-dismiss:hover { color: #8b949e; } .scan-log-dismiss:hover { color: #e6edf3; border-color: #8b949e; }
.spinner { .spinner {
width: 14px; height: 14px; width: 14px; height: 14px;
border: 2px solid rgba(79,142,247,.3); border: 2px solid rgba(79,142,247,.3);
@@ -598,7 +600,7 @@ var Xr=function(e){if(!(this instanceof Xr))return new Xr(e);this.id="Thenable/1
<div class="scan-log-header"> <div class="scan-log-header">
<div class="spinner" id="scanSpinner"></div> <div class="spinner" id="scanSpinner"></div>
<span id="statusText" class="scan-log-summary">Scanning...</span> <span id="statusText" class="scan-log-summary">Scanning...</span>
<button class="scan-log-dismiss" id="scanLogDismiss" onclick="document.getElementById('statusBar').classList.remove('visible')" style="display:none"></button> <button class="scan-log-dismiss" id="scanLogDismiss" onclick="document.getElementById('statusBar').classList.remove('visible')"></button>
</div> </div>
<div class="scan-log-body" id="scanLogBody"></div> <div class="scan-log-body" id="scanLogBody"></div>
</div> </div>
@@ -949,7 +951,6 @@ async function pollStatus() {
progressWrap.classList.add('visible'); progressWrap.classList.add('visible');
statusBar.classList.add('visible'); statusBar.classList.add('visible');
document.getElementById('scanSpinner').style.display = ''; document.getElementById('scanSpinner').style.display = '';
document.getElementById('scanLogDismiss').style.display = 'none';
const pct = s.total > 0 ? Math.round((s.done / s.total) * 100) : 0; const pct = s.total > 0 ? Math.round((s.done / s.total) * 100) : 0;
progressBar.style.width = pct + '%'; progressBar.style.width = pct + '%';
@@ -989,18 +990,14 @@ async function pollStatus() {
).join(''); ).join('');
logBody.scrollTop = logBody.scrollHeight; logBody.scrollTop = logBody.scrollHeight;
if (s.fail > 0) {
// Keep panel open so user can read errors
spinner.style.display = 'none'; spinner.style.display = 'none';
if (s.fail > 0) {
statusText.innerHTML = statusText.innerHTML =
`Scan complete &nbsp;&nbsp; ` + `Scan complete &nbsp;&nbsp; ` +
`<span class="ok-count">✓ ${s.ok}</span>&nbsp;&nbsp;` + `<span class="ok-count">✓ ${s.ok}</span>&nbsp;&nbsp;` +
`<span class="fail-count">✗ ${s.fail} failed</span>`; `<span class="fail-count">✗ ${s.fail} failed</span>`;
dismissBtn.style.display = 'block';
} else { } else {
statusBar.classList.remove('visible'); statusBar.classList.remove('visible');
spinner.style.display = '';
dismissBtn.style.display = 'none';
} }
} }
+2 -1
View File
@@ -112,9 +112,10 @@ def run_scan(dept: str = None, workers: int = 5, login_delay: int = 3):
scan_state["fail"] += 1 scan_state["fail"] += 1
error = result.get("error", "Unknown error") error = result.get("error", "Unknown error")
scan_state["errors"].append({"ip": ip, "error": error}) scan_state["errors"].append({"ip": ip, "error": error})
error_short = error.splitlines()[0][:120]
scan_state["log_lines"].append({ scan_state["log_lines"].append({
"ts": ts, "ok": False, "ts": ts, "ok": False,
"text": f"{ip}{error}", "text": f"{ip}{error_short}",
}) })
scan_all_switches(switches, progress_callback=on_progress, max_workers=workers, login_delay=login_delay) scan_all_switches(switches, progress_callback=on_progress, max_workers=workers, login_delay=login_delay)