Small UI cleanup, auto-refresh, and per-kind artifact routes

- Remove redundant "manage scripts" button and pipeline sidebar from Fleet page
- Bump log tail default 200 -> 1000 lines
- Auto-refresh (5s) on deployments list/detail, betas list, server detail, and artifact detail
- Drift ignores dedicated.cfg (Plutonium MP config; regenerates if deleted)
- Extract ArtifactDetail component; mount under /scripts/[id], /configs/[id], /plugins/[id] so configs and plugins no longer land on /scripts URLs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 23:30:04 -04:00
co-authored by Claude Opus 4.7
parent f10f0cefef
commit f716036d89
15 changed files with 668 additions and 603 deletions
+28 -55
View File
@@ -1,7 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import ServerCard from '$ui/components/ServerCard.svelte';
import PipelineTimeline from '$ui/components/PipelineTimeline.svelte';
import { statusByServer } from '$ui/stores/servers.js';
import type { RosterPlayer, Health } from '$ui/stores/servers.js';
@@ -57,51 +56,36 @@
}
</script>
<div class="grid">
<section class="left">
<header class="hdr">
<div class="title-block">
<h1>Fleet</h1>
<span class="count">{servers.length} server{servers.length === 1 ? '' : 's'}</span>
</div>
<a class="scripts-link" href="/scripts">manage scripts →</a>
</header>
{#if servers.length === 0}
<p class="empty">no servers registered yet — check SERVERS_ROOT</p>
{:else}
<div class="cards">
{#each servers as s (s.name)}
{@const live = liveFor(s.name, s)}
<ServerCard
name={s.name}
players={live.players}
map={live.map}
gametype={live.gametype}
roster={live.roster}
health={live.health}
lastSeenAt={live.lastSeenAt}
lastError={live.lastError}
held={s.held}
/>
{/each}
</div>
{/if}
</section>
<aside class="right">
<PipelineTimeline />
</aside>
</div>
<section class="left">
<header class="hdr">
<div class="title-block">
<h1>Fleet</h1>
<span class="count">{servers.length} server{servers.length === 1 ? '' : 's'}</span>
</div>
</header>
{#if servers.length === 0}
<p class="empty">no servers registered yet — check SERVERS_ROOT</p>
{:else}
<div class="cards">
{#each servers as s (s.name)}
{@const live = liveFor(s.name, s)}
<ServerCard
name={s.name}
players={live.players}
map={live.map}
gametype={live.gametype}
roster={live.roster}
health={live.health}
lastSeenAt={live.lastSeenAt}
lastError={live.lastError}
held={s.held}
/>
{/each}
</div>
{/if}
</section>
<style>
.grid {
display: grid;
grid-template-columns: 1fr 400px;
gap: var(--gap-section);
}
@media (max-width: 900px) {
.grid { grid-template-columns: 1fr; }
}
.hdr {
display: flex;
justify-content: space-between;
@@ -125,17 +109,6 @@
color: var(--ink-500);
letter-spacing: 0.5px;
}
.scripts-link {
color: var(--spark-400);
text-decoration: none;
font-family: var(--font-body);
font-size: var(--text-sm);
padding: 8px 14px;
border: 1px solid var(--border);
border-radius: var(--r-sm);
transition: border-color 0.15s, box-shadow 0.15s;
}
.scripts-link:hover { border-color: var(--accent); box-shadow: var(--accent-glow); }
.cards {
display: grid;
gap: var(--gap-cards);