Improve application responsiveness and background processing

This commit is contained in:
2026-10-04 19:56:06 -04:00
parent 1392a082da
commit ed004ddbcf
70 changed files with 1324 additions and 345 deletions
+22 -9
View File
@@ -4,6 +4,7 @@
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { pollVisible } from '$ui/poll.js';
import { fetchCampaigns } from '$ui/campaigns.js';
import { confirmAction } from '$ui/confirm.js';
import { serverTitle } from '$ui/server-labels.js';
import HistoricalServerIdentity from '$ui/components/HistoricalServerIdentity.svelte';
@@ -48,6 +49,8 @@
}
let loadError = $state('');
let limit = $state(25);
let historyTotal = $state(0);
let loadSequence = 0;
let deployments = $state<Deployment[]>([]);
let loading = $state(true);
let rollingBack = $state<string | null>(null);
@@ -67,15 +70,25 @@
void goto(url, { replaceState: true, noScroll: true, keepFocus: true });
}
async function loadCampaigns(): Promise<void> {
async function loadCampaigns(signal?: AbortSignal): Promise<boolean> {
const sequence = ++loadSequence;
try {
const res = await fetch('/api/campaigns');
if (!res.ok) throw new Error('Could not refresh campaigns.');
deployments = (await res.json()).deployments; loadError = '';
} catch (error) { loadError = (error as Error).message; }
finally { loading = false; }
const [history, active] = await Promise.all([
fetchCampaigns<Deployment>({ q: serverFilter, view: 'history' }, limit, signal),
fetchCampaigns<Deployment>({ q: serverFilter, active: 'true' }, Infinity, signal)
]);
if (sequence !== loadSequence || signal?.aborted) return true;
deployments = [...active.deployments, ...history.deployments]; historyTotal = history.total; loadError = '';
return true;
} catch (error) {
if (sequence === loadSequence && !signal?.aborted) loadError = (error as Error).message;
return false;
} finally { if (sequence === loadSequence && !signal?.aborted) loading = false; }
}
onMount(() => pollVisible(loadCampaigns, 5000));
$effect(() => {
void limit; void serverFilter;
return pollVisible(loadCampaigns, 15000);
});
function isActive(d: Deployment): boolean {
return d.servers.some((s) => !s.server_deleted_at && (s.restart_state === 'pending' || s.restart_state === 'failed'));
@@ -145,7 +158,7 @@
subtitle="Track file campaigns, server activation, and rollbacks."
/>
{#if loadError}<div class="ui-error" role="alert">{loadError}<Button size="sm" onclick={loadCampaigns}>Retry</Button></div>{/if}
{#if loadError}<div class="ui-error" role="alert">{loadError}<Button size="sm" onclick={() => loadCampaigns()}>Retry</Button></div>{/if}
{#if loading}
<div class="loading">Loading…</div>
{:else}
@@ -195,7 +208,7 @@
{/each}
{/if}
</section>
<ListFooter total={history.length} bind:limit onchange={() => saveContext()} label="campaigns" />
<ListFooter total={historyTotal} bind:limit onchange={() => saveContext()} label="campaigns" />
{/if}
</div>