Skip to content

Commit cdd4065

Browse files
committed
fix(dashboard): auto-clear invalidate status messages
1 parent e7444f3 commit cdd4065

2 files changed

Lines changed: 29 additions & 9 deletions

File tree

internal/wait0/dashboard/controller_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,10 @@ func TestDashboardPageContainsCSRFToken(t *testing.T) {
338338
if len(m) != 2 {
339339
t.Fatalf("csrf token not found in dashboard page")
340340
}
341+
if !strings.Contains(w.Body.String(), "setInvalidateStatus(") {
342+
t.Fatalf("expected status helper wiring in dashboard page")
343+
}
344+
if !strings.Contains(w.Body.String(), "invalidateStatusClearMs: 8000") {
345+
t.Fatalf("expected status auto-clear config in dashboard page")
346+
}
341347
}

internal/wait0/dashboard/template.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,11 @@ var dashboardTemplate = template.Must(template.New("dashboard").Parse(`<!doctype
189189
invalidationEnabled: {{if .InvalidationEnabled}}true{{else}}false{{end}},
190190
csrfToken: '{{.CSRFToken}}',
191191
maxPoints: 120,
192+
invalidateStatusClearMs: 8000,
192193
};
193194
194195
const history = [];
196+
let invalidateStatusTimer = null;
195197
196198
const byId = (id) => document.getElementById(id);
197199
@@ -295,9 +297,7 @@ var dashboardTemplate = template.Must(template.New("dashboard").Parse(`<!doctype
295297
296298
async function submitInvalidate(ev) {
297299
ev.preventDefault();
298-
const status = byId('invalidate-status');
299-
status.className = 'status muted';
300-
status.textContent = 'Submitting...';
300+
setInvalidateStatus('status muted', 'Submitting...', false);
301301
302302
const payload = {
303303
paths: splitList(byId('paths').value),
@@ -315,17 +315,31 @@ var dashboardTemplate = template.Must(template.New("dashboard").Parse(`<!doctype
315315
});
316316
const body = await res.json().catch(() => ({}));
317317
if (res.ok) {
318-
status.className = 'status ok';
319-
status.textContent = JSON.stringify(body, null, 2);
318+
setInvalidateStatus('status ok', JSON.stringify(body, null, 2), true);
320319
refreshStats();
321320
return;
322321
}
323-
status.className = 'status err';
324-
status.textContent = JSON.stringify(body, null, 2);
322+
setInvalidateStatus('status err', JSON.stringify(body, null, 2), true);
325323
} catch (err) {
326-
status.className = 'status err';
327-
status.textContent = String(err);
324+
setInvalidateStatus('status err', String(err), true);
325+
}
326+
}
327+
328+
function setInvalidateStatus(className, text, autoClear) {
329+
const status = byId('invalidate-status');
330+
if (!status) return;
331+
if (invalidateStatusTimer) {
332+
clearTimeout(invalidateStatusTimer);
333+
invalidateStatusTimer = null;
328334
}
335+
status.className = className;
336+
status.textContent = text;
337+
if (!autoClear) return;
338+
invalidateStatusTimer = setTimeout(() => {
339+
status.className = 'status muted';
340+
status.textContent = '';
341+
invalidateStatusTimer = null;
342+
}, cfg.invalidateStatusClearMs);
329343
}
330344
331345
function initInvalidationForm() {

0 commit comments

Comments
 (0)