Unify UI workflows and streamline fleet management

This commit is contained in:
2026-09-18 14:00:28 -04:00
parent 9cf0bd87f4
commit f54cac8c50
63 changed files with 1706 additions and 1286 deletions
+9 -16
View File
@@ -1,10 +1,11 @@
<script lang="ts">
import RoundTelemetry from './RoundTelemetry.svelte';
import ServerIdentity from './ServerIdentity.svelte';
import type { RosterPlayer, Health } from '$ui/stores/servers.js';
import { uiNow } from '$ui/stores/servers.js';
import { gametypeLabel } from '$ui/gametype.js';
import { elapsedSince } from '$ui/duration.js';
import { mapTitle, serverTitle } from '$ui/server-labels.js';
import { mapTitle, serverTitle, serverIdentity } from '$ui/server-labels.js';
import Card from './primitives/Card.svelte';
import Badge from './primitives/Badge.svelte';
import Stat from './primitives/Stat.svelte';
@@ -71,6 +72,7 @@
let showRoster = $derived(health === 'online' || health === 'stale');
let title = $derived(serverTitle(name));
let mapLabel = $derived(mapLabelOverride ?? mapTitle(map));
const showMap = $derived(mapLabel !== '—' && mapLabel !== serverIdentity(name).map);
let gtLabel = $derived(gametypeLabel(gametype));
let activeElapsed = $derived(activeSince ? elapsedSince(activeSince, $uiNow) : null);
@@ -101,7 +103,7 @@
<div class="head">
<div class="name-row">
<StatusPip {health} />
<strong class="name" title={name}>{title}</strong>
<strong class="name"><ServerIdentity {name} mapLabel={mapLabelOverride} /></strong>
</div>
{#if health === 'starting'}
<Badge variant="info" uppercase>Starting</Badge>
@@ -119,13 +121,7 @@
{/if}
</div>
<div class="meta">
<span class="map">{mapLabel}</span>
{#if gtLabel}
<span class="dot" aria-hidden="true">·</span>
<span class="gt">{gtLabel}</span>
{/if}
</div>
{#if gtLabel || showMap}<div class="meta">{#if showMap}<span>{health === 'online' ? 'Current map' : 'Last map'}: {mapLabel}</span>{/if}{#if gtLabel}<span class="gt">{gtLabel}</span>{/if}</div>{/if}
{#if health === 'online' && players !== null && players > 0 && gameInProgress}<RoundTelemetry {name} since={gameStartedAt} />{/if}
@@ -194,7 +190,7 @@
outline: 1px solid rgba(255, 176, 32, 0.28);
}
:global(.card.offline) {
opacity: 0.62;
border-color: color-mix(in srgb, var(--state-danger) 25%, var(--border-subtle));
}
.restart-bar {
@@ -232,9 +228,7 @@
font-weight: var(--weight-semibold);
color: var(--text-primary);
letter-spacing: var(--tracking-tight);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.players { flex-shrink: 0; }
@@ -249,9 +243,8 @@
overflow: hidden;
text-overflow: ellipsis;
}
.map { color: var(--text-secondary); font-weight: var(--weight-medium); }
.gt { color: var(--text-tertiary); }
.dot { color: var(--text-quaternary); }
.timing {
display: flex;
@@ -265,7 +258,7 @@
gap: 2px;
}
.metric-label {
font-size: 10px;
font-size: var(--text-xs);
font-weight: var(--weight-semibold);
text-transform: uppercase;
letter-spacing: var(--tracking-label);