feat: daemon health panel, brand-rail status chips, user timezone selector
Build / build (push) Successful in 10m35s

- Health API now surfaces Docker /info + /version (version, platform,
  kernel, container/image counts, storage driver, memory, latency) and
  NPM aggregates (proxy host total, managed-by-Tinyforge count, access
  lists, certificates, endpoint URL).
- Docker/NPM indicators moved out of the sidebar footer and into a
  compact mono-styled rail directly under the Tinyforge brand title,
  with pulse/fault animations and click-to-expand error hints.
- New SystemDaemonsCard on the dashboard: two terminal-styled panels
  (Docker Engine + Proxy) with a running/paused/stopped stacked bar,
  key-value diagnostics, and a total-vs-managed proportion meter on
  the proxy-hosts tile.
- Shared health store so the sidebar and dashboard share a single
  30 s poll instead of duplicating traffic.
- User-facing timezone preference with auto-detect fallback; all
  dates across projects, sites, stacks, settings, backup, event log
  and stale containers now render through \$fmt.date / \$fmt.datetime.
- en/ru translations for both features.
This commit is contained in:
2026-04-23 14:32:30 +03:00
parent a182a93950
commit 90e6e59d9e
24 changed files with 2267 additions and 177 deletions
+6 -1
View File
@@ -5,9 +5,11 @@
import SkeletonCard from '$lib/components/SkeletonCard.svelte';
import EmptyState from '$lib/components/EmptyState.svelte';
import SystemHealthCard from '$lib/components/SystemHealthCard.svelte';
import SystemDaemonsCard from '$lib/components/SystemDaemonsCard.svelte';
import ForgeHero from '$lib/components/ForgeHero.svelte';
import { IconDeploy, IconAlert } from '$lib/components/icons';
import { t } from '$lib/i18n';
import { fmt } from '$lib/format/datetime';
let projects = $state<Project[]>([]);
let instancesByProject = $state<Record<string, Instance[]>>({});
@@ -181,6 +183,9 @@
<!-- System health summary -->
<SystemHealthCard />
<!-- Detailed daemon panel: Docker engine + NPM/Traefik proxy -->
<SystemDaemonsCard />
<!-- Static sites summary -->
{#if !loading}
<section class="section">
@@ -219,7 +224,7 @@
{/if}
</div>
{#if site.last_sync_at}
<p class="text-xs text-[var(--text-tertiary)]">{$t('sites.lastSync')}: {new Date(site.last_sync_at).toLocaleString()}</p>
<p class="text-xs text-[var(--text-tertiary)]">{$t('sites.lastSync')}: {$fmt.dateTime(site.last_sync_at)}</p>
{/if}
</a>
{/each}