fix(dashboard): F-U-013 add Refresh + 5s auto-refresh toggle on queues overview

Queue depths change continuously; the page was a load-time snapshot
with no way to update without a hard refresh. Dead-letters has a
Refresh button; queues didn't.

Add:
- A Refresh button that re-fires loadQueues() (and shows "Refreshing…"
  while in-flight).
- An "Auto-refresh every 5s" checkbox. setInterval lifecycle is
  managed via onDestroy so navigating away cancels cleanly.

Queue-detail page is unchanged in this commit; same pattern can be
applied there in a follow-up.

AUDIT.md anchor: F-U-013 (overview list; detail page deferred).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-07 21:08:28 +02:00
parent 6298c7d21c
commit 6d35eaad92

View File

@@ -3,11 +3,17 @@
import { page } from '$app/state';
import { api, ApiError, type App, type QueueSummary } from '$lib/api';
import { onDestroy } from 'svelte';
let slug = $derived(page.params.slug ?? '');
let app = $state<App | null>(null);
let queues = $state<QueueSummary[]>([]);
let loading = $state(false);
let error = $state<string | null>(null);
/// F-U-013: queue depths change continuously. The page used to be a
/// page-load snapshot with no way to update without a hard refresh.
let autoRefresh = $state(false);
let autoRefreshHandle: ReturnType<typeof setInterval> | null = null;
async function loadApp() {
try {
@@ -29,6 +35,23 @@
}
}
function setAutoRefresh(on: boolean) {
autoRefresh = on;
if (autoRefreshHandle) {
clearInterval(autoRefreshHandle);
autoRefreshHandle = null;
}
if (on) {
autoRefreshHandle = setInterval(() => {
void loadQueues();
}, 5000);
}
}
onDestroy(() => {
if (autoRefreshHandle) clearInterval(autoRefreshHandle);
});
$effect(() => {
void slug;
void loadApp();
@@ -47,6 +70,20 @@
Per-app durable queues. Producers call <code>queue::enqueue(name, msg)</code>;
consumers register a <code>queue:receive</code> trigger. v1.1.9.
</p>
<!-- F-U-013: refresh + auto-refresh toggle. -->
<div class="toolbar">
<button type="button" onclick={() => loadQueues()} disabled={loading}>
{loading ? 'Refreshing…' : 'Refresh'}
</button>
<label class="auto-refresh">
<input
type="checkbox"
checked={autoRefresh}
onchange={(e) => setAutoRefresh((e.currentTarget as HTMLInputElement).checked)}
/>
Auto-refresh every 5s
</label>
</div>
</header>
{#if error}