diff --git a/src/lib/ui/components/DashboardFrame.svelte b/src/lib/ui/components/DashboardFrame.svelte index 6983a78..0a76f67 100644 --- a/src/lib/ui/components/DashboardFrame.svelte +++ b/src/lib/ui/components/DashboardFrame.svelte @@ -5,16 +5,24 @@ import StatusStrip from "./StatusStrip.svelte"; import TelemetryGrid from "./TelemetryGrid.svelte"; - let { dashboard }: { dashboard: UiDashboardPreview } = $props(); + const generatedTitleId = $props.id(); + + let { + dashboard, + titleId = `${generatedTitleId}-title`, + }: { + dashboard: UiDashboardPreview; + titleId?: string; + } = $props(); -
+
{#if dashboard.eyebrow}

{dashboard.eyebrow}

{/if} -

{dashboard.title}

+

{dashboard.title}

{#if dashboard.subtitle} {dashboard.subtitle} {/if} diff --git a/src/lib/ui/components/FooterCell.svelte b/src/lib/ui/components/FooterCell.svelte index f025db4..d4261fe 100644 --- a/src/lib/ui/components/FooterCell.svelte +++ b/src/lib/ui/components/FooterCell.svelte @@ -2,12 +2,32 @@ import type { UiStatusItem } from "../types"; let { item }: { item: UiStatusItem } = $props(); + + let target = $derived(item.link?.external ? "_blank" : undefined); + let rel = $derived(item.link?.external ? "noreferrer" : undefined); - +{/snippet} + +{#if item.link} + + {@render cellContent()} + +{:else} + +{/if} diff --git a/src/lib/ui/components/ModuleCard.svelte b/src/lib/ui/components/ModuleCard.svelte index f2e3991..21a2854 100644 --- a/src/lib/ui/components/ModuleCard.svelte +++ b/src/lib/ui/components/ModuleCard.svelte @@ -64,4 +64,23 @@ background: var(--ui-color-accent); color: #050605; } + + .module-card[data-severity="warning"] { + border-color: color-mix(in srgb, var(--ui-color-warning), transparent 42%); + color: var(--ui-color-warning); + } + + .module-card[data-severity="danger"] { + border-color: color-mix(in srgb, var(--ui-color-danger), transparent 32%); + color: var(--ui-color-danger); + } + + .module-card[data-severity="stale"], + .module-card[data-severity="unavailable"] { + color: var(--ui-color-stale); + } + + .module-card[data-severity="loading"] { + color: var(--ui-color-accent); + } diff --git a/src/lib/ui/components/ServiceRow.svelte b/src/lib/ui/components/ServiceRow.svelte index 22936d3..0021424 100644 --- a/src/lib/ui/components/ServiceRow.svelte +++ b/src/lib/ui/components/ServiceRow.svelte @@ -4,9 +4,12 @@ import StatusBadge from "./StatusBadge.svelte"; let { service }: { service: UiServiceRow } = $props(); + + let target = $derived(service.link?.external ? "_blank" : undefined); + let rel = $derived(service.link?.external ? "noreferrer" : undefined); -
+{#snippet rowContent()}

{service.label}

@@ -15,7 +18,24 @@ {#if service.detail} {/if} -
+{/snippet} + +{#if service.link} + + {@render rowContent()} + +{:else} +
+ {@render rowContent()} +
+{/if} diff --git a/src/routes/page.test.ts b/src/routes/page.test.ts new file mode 100644 index 0000000..5c9d0b7 --- /dev/null +++ b/src/routes/page.test.ts @@ -0,0 +1,28 @@ +import { render } from "svelte/server"; +import { describe, expect, test } from "vitest"; +import Page from "./+page.svelte"; + +describe("home page design-system preview", () => { + test("renders the runtime dashboard data from the server load", () => { + const { body } = render(Page, { + props: { + data: { + dashboard: { + title: "Runtime Surface", + subtitle: "Loaded from persistence", + status: "building", + message: "Runtime model is available.", + schemaVersion: "dashboard.v1", + currentRevisionId: "revision-1234567890", + }, + }, + }, + }); + + expect(body).toContain("Runtime Surface"); + expect(body).toContain("Loaded from persistence"); + expect(body).toContain("revision"); + expect(body).toContain("primary"); + expect(body).toContain("secondary"); + }); +});