new destruction flow
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import RoundTelemetry from '$ui/components/RoundTelemetry.svelte';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
import DestroyServerModal from '$ui/components/DestroyServerModal.svelte';
|
||||
import { statusByServer, uiNow } from '$ui/stores/servers.js';
|
||||
import type { RosterPlayer, Health, RconEndpoint, RconFailure } from '$ui/stores/servers.js';
|
||||
import { elapsedSince } from '$ui/duration.js';
|
||||
@@ -90,9 +90,7 @@
|
||||
let diagnosing = $state(false);
|
||||
let rconProbe = $state<RconProbeResult | null>(null);
|
||||
let probingRcon = $state(false);
|
||||
let destroying = $state(false);
|
||||
let destroyError = $state<string | null>(null);
|
||||
let destroyWarnings = $state<string[]>([]);
|
||||
let destroyOpen = $state(false);
|
||||
let activeTab = $state<'roster' | 'logs' | 'inventory' | 'diagnostics' | 'history'>('roster');
|
||||
|
||||
async function loadServer(): Promise<void> {
|
||||
@@ -207,35 +205,6 @@
|
||||
rconProbe = { ok: false, reason: 'send-error', detail: (err as Error).message };
|
||||
} finally { probingRcon = false; }
|
||||
}
|
||||
async function destroyThisServer(): Promise<void> {
|
||||
if (destroying || !name) return;
|
||||
const confirmed = confirm(
|
||||
`Destroy ${name}?\n\nThis stops the container, deletes the Komodo deployment, ` +
|
||||
`removes the host directory, and removes this server?s campaign details. Server deployment history is retained. Cannot be undone.`
|
||||
);
|
||||
if (!confirmed) return;
|
||||
destroying = true; destroyError = null; destroyWarnings = [];
|
||||
try {
|
||||
const res = await fetch(`/api/servers/${encodeURIComponent(name)}`, { method: 'DELETE' });
|
||||
const body = (await res.json()) as { ok: boolean; error?: string; warnings?: string[] };
|
||||
if (!body.ok) {
|
||||
destroyError = body.error ?? 'destroy failed';
|
||||
destroyWarnings = body.warnings ?? [];
|
||||
destroying = false;
|
||||
return;
|
||||
}
|
||||
if (body.warnings && body.warnings.length > 0) {
|
||||
destroyWarnings = body.warnings;
|
||||
setTimeout(() => goto('/'), 1500);
|
||||
return;
|
||||
}
|
||||
await goto('/');
|
||||
} catch (err) {
|
||||
destroyError = (err as Error).message;
|
||||
destroying = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Tab config — Diagnostics gets a warning badge when there's an issue.
|
||||
let tabs = $derived([
|
||||
{ id: 'roster', label: 'Roster', badge: effectiveRoster?.length ?? null },
|
||||
@@ -246,6 +215,8 @@
|
||||
]);
|
||||
</script>
|
||||
|
||||
<DestroyServerModal bind:open={destroyOpen} {name} players={effectivePlayers} />
|
||||
|
||||
{#if server}
|
||||
<div class="server-page" style="view-transition-name: server-{name.replace(/[^a-z0-9_-]/gi, '-')};">
|
||||
<!-- Hero: name + status + player count + primary actions -->
|
||||
@@ -255,7 +226,7 @@
|
||||
<Breadcrumbs items={[{ label: 'Fleet', href: '/' }, { label: name }]} />
|
||||
{/snippet}
|
||||
{#snippet actions()}
|
||||
<Button variant="danger" onclick={destroyThisServer} disabled={destroying} loading={destroying}>
|
||||
<Button variant="danger" onclick={() => destroyOpen = true}>
|
||||
Destroy
|
||||
</Button>
|
||||
{/snippet}
|
||||
@@ -307,14 +278,6 @@
|
||||
|
||||
<RoundTelemetry {name} />
|
||||
|
||||
{#if destroyError}
|
||||
<div class="destroy-error" role="alert">{destroyError}</div>
|
||||
{/if}
|
||||
{#if destroyWarnings.length > 0}
|
||||
<ul class="destroy-warn">
|
||||
{#each destroyWarnings as w}<li>{w}</li>{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</Card>
|
||||
|
||||
<div class="tabs-row">
|
||||
@@ -604,27 +567,7 @@
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.destroy-error {
|
||||
margin-top: var(--space-4);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: rgba(255, 86, 112, 0.08);
|
||||
border: 1px solid rgba(255, 86, 112, 0.28);
|
||||
border-radius: var(--radius-md);
|
||||
color: var(--state-danger);
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.destroy-warn {
|
||||
margin: var(--space-3) 0 0;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
background: rgba(255, 176, 32, 0.08);
|
||||
border: 1px solid rgba(255, 176, 32, 0.28);
|
||||
border-radius: var(--radius-md);
|
||||
color: var(--state-warning);
|
||||
font-size: var(--text-sm);
|
||||
list-style: disc inside;
|
||||
}
|
||||
|
||||
/* Tabs row */
|
||||
/* Tabs row */
|
||||
.tabs-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user