fix
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { prefersReducedMotion } from "svelte/motion";
|
||||
import Icon from "./Icon.svelte";
|
||||
import { launcher } from "../lib/launcher.svelte";
|
||||
import { formatBytes } from "../lib/format";
|
||||
|
||||
// Its own panel rather than a block inside the action card: the card is anchored to the
|
||||
// bottom of the window and cannot grow, so three rows plus a password field pushed the
|
||||
@@ -24,6 +25,24 @@
|
||||
/** The short version of a row's state, for the column that has room for three words.
|
||||
NOT called `state`: that shadows the `$state` rune in this file, and everything
|
||||
declared with it silently stops being reactive. */
|
||||
/** `20260921T125618Z` -> `21 Sep 2026`; anything else is shown as it came. */
|
||||
function stamped(snapshot: string | null): string {
|
||||
if (!snapshot || snapshot.length < 8) return snapshot ?? "unknown";
|
||||
const y = Number(snapshot.slice(0, 4));
|
||||
const m = Number(snapshot.slice(4, 6));
|
||||
const d = Number(snapshot.slice(6, 8));
|
||||
if (!y || !m || !d) return snapshot;
|
||||
const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
||||
return `${d} ${MONTHS[m - 1] ?? "?"} ${y}`;
|
||||
}
|
||||
|
||||
function aged(days: number | null): string {
|
||||
if (days === null) return "";
|
||||
if (days <= 0) return "today";
|
||||
if (days === 1) return "1 day old";
|
||||
return `${days} days old`;
|
||||
}
|
||||
|
||||
function rowState(row: { behind: boolean | null; dirty: boolean }): { text: string; tone: string } {
|
||||
if (row.dirty) return { text: "uncommitted", tone: "warn" };
|
||||
if (row.behind === true) return { text: "behind", tone: "go" };
|
||||
@@ -62,6 +81,32 @@
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<!-- The payload a release does NOT rebuild. It is copied forward from the previous
|
||||
version every time, so it ages quietly: this is the only place that says by how
|
||||
much, which is what turns "the tiles are old" into a decision. -->
|
||||
{#if plan.data}
|
||||
{@const d = plan.data}
|
||||
<div class="payload">
|
||||
<span class="payload-head">Carried forward — a release does not rebuild these</span>
|
||||
<div class="payload-row">
|
||||
<span class="payload-name">Database seed</span>
|
||||
<span class="payload-val mono">{stamped(d.db_snapshot)}</span>
|
||||
<span class="payload-age" class:stale={(d.db_age_days ?? 0) > 30}>{aged(d.db_age_days)}</span>
|
||||
<span class="payload-size mono">{formatBytes(d.db_bytes)}</span>
|
||||
</div>
|
||||
<div class="payload-row">
|
||||
<span class="payload-name">Map tiles</span>
|
||||
<span class="payload-val mono">{d.tile_sets} sets</span>
|
||||
<span class="payload-age" class:stale={(d.tiles_age_days ?? 0) > 90}>{aged(d.tiles_age_days)}</span>
|
||||
<span class="payload-size mono">{formatBytes(d.tile_bytes)}</span>
|
||||
</div>
|
||||
<span class="payload-foot mono">{d.tile_datasets.join(" · ")}</span>
|
||||
{#if !d.is_live}
|
||||
<span class="payload-foot">Read from this PC's {d.version}, which is not what the DHP serves.</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="checks mono">
|
||||
<span class:ok={plan.online}>DHP {plan.online ? "✓" : "✗"}</span>
|
||||
<span class:ok={plan.docker}>Docker {plan.docker ? "✓" : "✗"}</span>
|
||||
@@ -108,6 +153,48 @@
|
||||
</section>
|
||||
|
||||
<style>
|
||||
/* The data payload. Quiet by default - it is context, not a control - but the age goes
|
||||
amber once it is old enough to matter, which is the whole point of showing it. */
|
||||
.payload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
margin: 10px 0 2px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.payload-head {
|
||||
color: var(--muted);
|
||||
font-size: var(--text-xs);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.payload-row {
|
||||
display: grid;
|
||||
grid-template-columns: 7.5rem 7rem minmax(0, 1fr) auto;
|
||||
gap: 8px;
|
||||
align-items: baseline;
|
||||
font-size: var(--text-xs);
|
||||
}
|
||||
.payload-name {
|
||||
color: var(--ink-2);
|
||||
}
|
||||
.payload-val,
|
||||
.payload-size {
|
||||
color: var(--muted);
|
||||
}
|
||||
.payload-age {
|
||||
color: var(--muted);
|
||||
}
|
||||
.payload-age.stale {
|
||||
color: var(--warn);
|
||||
}
|
||||
.payload-foot {
|
||||
margin-top: 4px;
|
||||
color: var(--muted);
|
||||
font-size: var(--text-xs);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.release {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user