Make UI language, timestamps and live feedback consistent
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import RelativeTime from '$ui/components/RelativeTime.svelte';
|
||||
import { contextHref } from '$lib/navigation-context.js';
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import { page } from '$app/stores';
|
||||
@@ -69,14 +70,6 @@
|
||||
return pollVisible(loadCampaigns, 15000);
|
||||
});
|
||||
|
||||
function ago(iso: string): string {
|
||||
const elapsed = refreshedAt - new Date(iso).getTime();
|
||||
if (elapsed < 60_000) return 'Just now';
|
||||
if (elapsed < 3_600_000) return `${Math.floor(elapsed / 60_000)} min ago`;
|
||||
if (elapsed < 86_400_000) return `${Math.floor(elapsed / 3_600_000)} hr ago`;
|
||||
const days = Math.floor(elapsed / 86_400_000);
|
||||
return `${days} day${days === 1 ? '' : 's'} ago`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head><title>Campaigns | Electric Cherry</title></svelte:head>
|
||||
@@ -138,7 +131,7 @@
|
||||
<td><div class="status"><Badge variant={outcome.tone} size="md">{outcome.label}</Badge>
|
||||
{#if showProgress}<progress max={campaign.servers.length || 1} value={outcome.completed} aria-label={`${outcome.completed} of ${campaign.servers.length} servers complete`}></progress>{/if}
|
||||
</div></td>
|
||||
<td class="started"><button type="button" class="timestamp" aria-label={`Started ${$timeFormat.dateTime(campaign.started_at)}`}><time datetime={campaign.started_at}>{ago(campaign.started_at)}</time><span class="exact-time" aria-hidden="true">{$timeFormat.dateTime(campaign.started_at)}</span></button></td>
|
||||
<td class="started"><button type="button" class="timestamp" aria-label={`Started ${$timeFormat.dateTime(campaign.started_at)}`}><RelativeTime value={campaign.started_at} /><span class="exact-time" aria-hidden="true">{$timeFormat.dateTime(campaign.started_at)}</span></button></td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { plural } from '$ui/plural.js';
|
||||
import RelativeTime from '$ui/components/RelativeTime.svelte';
|
||||
import { contextHref } from '$lib/navigation-context.js';
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import { onMount } from 'svelte';
|
||||
import { pollVisible } from '$ui/poll.js';
|
||||
import Dialog from '$ui/components/primitives/Dialog.svelte';
|
||||
@@ -163,9 +164,6 @@
|
||||
v === 'held' ? 'warning' :
|
||||
'neutral';
|
||||
}
|
||||
function fmt(iso: string | null): string {
|
||||
return $timeFormat.dateTime(iso);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head><title>{detail ? `${detail.deployment.action} campaign · ${detail.deployment.id}` : 'Campaign'} | Electric Cherry</title></svelte:head>
|
||||
@@ -191,14 +189,14 @@
|
||||
</SectionHeader>
|
||||
{#if rollbackError}<p class="err" role="alert">{rollbackError}</p>{/if}
|
||||
<div class="metadata">
|
||||
<span>Started {fmt(detail.deployment.started_at)}</span>
|
||||
<span>Started <RelativeTime value={detail.deployment.started_at} /></span>
|
||||
{#if detail.deployment.beta_id}<span>Source: <a href={contextHref(`/betas/${detail.deployment.beta_id}`, $page.url)}>Beta #{detail.deployment.beta_id}</a></span>{/if}
|
||||
{#if detail.watchdogIncidentId}<span>Source: <a href={contextHref(`/maintenance/${encodeURIComponent(detail.watchdogIncidentId)}`, $page.url)}>Maintenance incident</a></span>{/if}
|
||||
<details class="campaign-details">
|
||||
<summary>Campaign details</summary>
|
||||
<div class="campaign-details-body">
|
||||
<div class="campaign-id"><span class="mono">{detail.deployment.id}</span><Button size="sm" onclick={copyId}>Copy ID</Button><span role="status">{copyStatus}</span></div>
|
||||
{#if detail.deployment.finished_at}<p>Finished {fmt(detail.deployment.finished_at)}</p>{/if}
|
||||
{#if detail.deployment.finished_at}<p>Finished <RelativeTime value={detail.deployment.finished_at} /></p>{/if}
|
||||
{#if detail.deployment.triggered_by && detail.deployment.triggered_by !== 'ui'}<p>Triggered by {detail.deployment.triggered_by}</p>{/if}
|
||||
<p>{detail.watchdogIncidentId ? 'Maintenance rebuilds instance files with the latest promoted setup after checking that the server is safe to update.' : 'Changes wait for an empty server and restart capacity. Rollback snapshots are captured before applying files, then servers restart and verify health. Tested servers retain their pre-beta snapshots.'}</p>
|
||||
</div>
|
||||
@@ -216,7 +214,7 @@
|
||||
<div class="progress-counts">
|
||||
{#if counts.processing}<span>{counts.processing} processing</span>{/if}
|
||||
{#if counts.queued}<span>{counts.queued} queued</span>{/if}
|
||||
{#if counts.attention}<span class="attention">{counts.attention} need attention</span>{/if}
|
||||
{#if counts.attention}<span class="attention">{counts.attention} {plural(counts.attention, 'needs', 'need')} attention</span>{/if}
|
||||
{#if counts.inactive}<span>{counts.inactive} inactive</span>{/if}
|
||||
{#if detail.servers.length === 0}<span>No servers recorded</span>
|
||||
{:else if counts.complete === detail.servers.length}<span>All servers activated</span>{/if}
|
||||
@@ -266,9 +264,9 @@
|
||||
<div><dt>Server ID</dt><dd class="mono">{s.server}</dd></div>
|
||||
{#if s.players !== null}<div><dt>Players at last check</dt><dd>{s.players}</dd></div>{/if}
|
||||
<div><dt>Attempts</dt><dd>{s.attempts}</dd></div>
|
||||
{#if s.checked_at}<div><dt>Last checked</dt><dd>{fmt(s.checked_at)}</dd></div>{/if}
|
||||
{#if s.restarted_at}<div><dt>Restart requested</dt><dd>{fmt(s.restarted_at)}</dd></div>{/if}
|
||||
{#if s.server_deleted_at}<div><dt>Deleted</dt><dd>{fmt(s.server_deleted_at)}</dd></div>{/if}
|
||||
{#if s.checked_at}<div><dt>Last checked</dt><dd><RelativeTime value={s.checked_at} /></dd></div>{/if}
|
||||
{#if s.restarted_at}<div><dt>Restart requested</dt><dd><RelativeTime value={s.restarted_at} /></dd></div>{/if}
|
||||
{#if s.server_deleted_at}<div><dt>Deleted</dt><dd><RelativeTime value={s.server_deleted_at} /></dd></div>{/if}
|
||||
</dl>
|
||||
<div class="detail-actions">
|
||||
{#if !s.server_deleted_at}<a href={contextHref(`/servers/${encodeURIComponent(s.server)}?tab=logs`, $page.url)}>Open logs</a><a href={contextHref(`/servers/${encodeURIComponent(s.server)}?tab=diagnostics`, $page.url)}>Diagnostics</a>{/if}
|
||||
|
||||
Reference in New Issue
Block a user