Add consistent Restart button to watcher overview#61
Conversation
The Service and Zoekt rows in the dashboard overview always show a Restart button when running, but the Watcher row had no action button when active. This adds a Restart button matching the same pattern and consolidates the version-mismatch restart to use the same function. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Review: PR #61 — Add consistent Restart button to watcher overview
The motivation is solid — consistency between Service, Zoekt, and Watcher rows is a clear UX improvement. The consolidation of stopAndRestartWatcher into overviewRestartWatcher is the right direction. However, there are two bugs that need fixing before merge.
Bug 1 — Orphaned #version-alert-status span (dead HTML + dead CSS)
The version-alert template still injects the status span, but overviewRestartWatcher never writes to it:
// public/index.html ~line 444 (updated branch)
actionsEl.innerHTML = `
<button class="btn-primary" onclick="overviewRestartWatcher(this)">Restart Watcher</button>
<span class="version-alert-status" id="version-alert-status"></span>`; // ← never populatedAnd the CSS at line 40 (.version-alert-status) is also now unused.
The old stopAndRestartWatcher used this span to show progress ("Waiting for watcher to stop...", etc.). Now that status is encoded in the button text, the span should be removed from the template. The CSS rule can be removed too if nothing else references it.
Bug 2 — Button label resets to wrong text for the version-alert case
overviewRestartWatcher always resets to 'Restart' on error/timeout:
setTimeout(() => { btn.textContent = 'Restart'; btn.disabled = false; }, 5000);But the version-mismatch alert button is labelled 'Restart Watcher'. After any failure, that button will permanently read 'Restart' instead of 'Restart Watcher'.
One fix: capture the original label before mutating it:
async function overviewRestartWatcher(btn) {
const originalText = btn.textContent;
btn.disabled = true;
btn.textContent = 'Restarting...';
// ...
// In error/timeout paths:
setTimeout(() => { btn.textContent = originalText; btn.disabled = false; }, 5000);
}Minor — /api/watcher/stop response not checked
The stop call's response is never checked for non-2xx status. If the stop endpoint errors, the code falls through to waitForWatcherState(false) and silently times out instead of surfacing the error. This was also present in the old stopAndRestartWatcher, so not a regression, but worth fixing while touching this code.
Test coverage
The test plan is manual-only. No new automated tests — acceptable for a UI-only change in this codebase's current state, but the error/timeout paths in particular are easy to miss manually. Consider adding at least one test for the error branch if there's an existing JS test harness.
Summary: Two confirmed bugs (orphaned span, label reset). Please fix before merging.
…onse - Remove unused #version-alert-status span and its CSS rule since overviewRestartWatcher uses button text for progress feedback - Capture original button text so error/timeout resets restore the correct label (e.g. "Restart Watcher" vs "Restart") - Check /api/watcher/stop response status and surface errors instead of silently falling through to the timeout path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
action-btn-warn) to the watcher overview row, matching the existing pattern for Service and ZoektoverviewRestartWatcherfunction, removing the oldstopAndRestartWatcherTest plan
🤖 Generated with Claude Code