Preserve deleted server history
Retain historical server identities, results, and evidence after deletion. Mark archived entries as Deleted and prevent old work from targeting servers that reuse the same name. Fixes #16.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { pollVisible } from '$ui/poll.js';
|
||||
import ServerIdentity from '$ui/components/ServerIdentity.svelte';
|
||||
import HistoricalServerIdentity from '$ui/components/HistoricalServerIdentity.svelte';
|
||||
import { page } from '$app/stores';
|
||||
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
|
||||
import Breadcrumbs from '$ui/components/primitives/Breadcrumbs.svelte';
|
||||
@@ -13,12 +14,12 @@
|
||||
let error = $state('');
|
||||
let requestNumber = 0;
|
||||
let collection = $derived(detail?.collection);
|
||||
const launching = (server: { state: string }) => ['running', 'awaiting-health'].includes(server.state);
|
||||
const launching = (server: { state: string; server_deleted_at?: string | null }) => !server.server_deleted_at && ['running', 'awaiting-health'].includes(server.state);
|
||||
const needsAttention = (server: { state: string }) => ['failed', 'interrupted', 'warning', 'cancelled'].includes(server.state);
|
||||
const exact = $derived(collection?.mode === 'exact');
|
||||
const currentServers = $derived(detail?.servers.filter(launching) ?? []);
|
||||
const otherLaunches = $derived(detail?.queue.active.filter(active => !detail?.servers.some(server => server.id === active.id)) ?? []);
|
||||
const firstQueued = $derived(detail?.servers.find(server => server.state === 'queued'));
|
||||
const firstQueued = $derived(detail?.servers.find(server => !server.server_deleted_at && server.state === 'queued'));
|
||||
const labels: Record<string, string> = { queued: 'Queued', running: 'Launching', 'awaiting-health': 'Checking readiness', done: 'Ready', warning: 'Needs review', failed: 'Failed', interrupted: 'Interrupted', waiting: 'Waiting for empty server', cancelled: 'Cancelled' };
|
||||
const waitingForPort = (server: CollectionServer) => server.state === 'queued' && (server.stage.startsWith('Waiting for removal') || server.stage.startsWith('Waiting for port'));
|
||||
function stateLabel(server: CollectionServer) {
|
||||
@@ -81,7 +82,7 @@
|
||||
{#each currentServers as server (server.id)}
|
||||
<a class="current-launch" href="/provisioning/{server.id}">
|
||||
<span class="activity" aria-hidden="true"></span>
|
||||
<div><strong>{server.action === 'destroy' ? 'Removing: ' : ''}<ServerIdentity name={server.server} /></strong><p>{server.state === 'awaiting-health' ? 'Checking the container, connection, and expected map.' : server.stage}</p></div>
|
||||
<div><strong>{server.action === 'destroy' ? 'Removing: ' : ''}<HistoricalServerIdentity name={server.server} deletedAt={server.server_deleted_at} /></strong><p>{server.state === 'awaiting-health' ? 'Checking the container, connection, and expected map.' : server.stage}</p></div>
|
||||
<span class="operation-link">Follow progress <span aria-hidden="true">→</span></span>
|
||||
</a>
|
||||
{/each}
|
||||
@@ -100,7 +101,7 @@
|
||||
|
||||
{#if exact && detail.retainedServers.length}
|
||||
<details><summary>{detail.retainedServers.length} retained server{detail.retainedServers.length === 1 ? '' : 's'} (unchanged)</summary>
|
||||
<ul>{#each detail.retainedServers as name}<li><ServerIdentity {name} /> <span class="muted">{name}</span></li>{/each}</ul>
|
||||
<ul>{#each detail.retainedServers as name}<li><HistoricalServerIdentity {name} deletedAt={detail.retainedServerDeletedAt?.[name]} /> <span class="muted">{name}</span></li>{/each}</ul>
|
||||
</details>
|
||||
{/if}
|
||||
<section class="queue" aria-labelledby="queue-title">
|
||||
@@ -111,7 +112,7 @@
|
||||
<a class="server" href="/provisioning/{server.id}">
|
||||
<span class="order" class:ready={server.state === 'done'} aria-hidden="true">{server.state === 'done' ? '✓' : String(index + 1).padStart(2, '0')}</span>
|
||||
<div class="server-content">
|
||||
<div class="server-heading"><strong><ServerIdentity name={server.server} /></strong><Badge variant={needsAttention(server) ? 'danger' : server.state === 'done' ? 'online' : launching(server) ? 'info' : 'neutral'}>{stateLabel(server)}</Badge></div>
|
||||
<div class="server-heading"><strong><HistoricalServerIdentity name={server.server} deletedAt={server.server_deleted_at} /></strong><Badge variant={needsAttention(server) ? 'danger' : server.state === 'done' ? 'online' : launching(server) ? 'info' : 'neutral'}>{stateLabel(server)}</Badge></div>
|
||||
<p class:error={!!server.error}>{server.error ?? (server.state === 'queued' ? queueHint(server) : server.state === 'done' ? server.action === 'destroy' ? server.stage : 'Startup checks passed.' : server.stage)}</p>
|
||||
<div class="server-meta"><span>{server.action === 'destroy' ? 'Remove server' : `Create server · Port ${server.port}`}</span><span>{needsAttention(server) ? 'Review & recover' : 'View operation'} <span aria-hidden="true">→</span></span></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user