diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index c124aa2..4f4f8fa 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -2,6 +2,7 @@ import { theme } from "$lib/stores/theme"; import { allAlerts, refreshData, refreshing } from "$lib/stores/sites"; import { page } from "$app/stores"; + import { goto } from "$app/navigation"; import { slide } from "svelte/transition"; import { Satellite, Globe, BookOpen, Bell, Moon, Sun, Monitor, RefreshCw } from "@lucide/svelte"; import Logo from "$lib/components/ui/logo.svelte"; @@ -13,7 +14,27 @@ { href: "/methodology", label: "Methodology", icon: BookOpen }, ]; let alertCount = $derived($allAlerts.length); - + let latestAlert = $derived.by(() => { + if ($allAlerts.length === 0) return null; + const a = $allAlerts.reduce((a, b) => new Date(a.triggeredAt) > new Date(b.triggeredAt) ? a : b); + const siteName = a.message.match(/for (.+?)(?:\.|:|\s|$)/)?.[1] ?? ""; + const severityColor = a.severity === "critical" ? "var(--critical)" : a.severity === "warning" ? "var(--watch)" : "var(--accent)"; + const shortMsg = a.message.replace(/ for .+/, "").replace(/\.$/, ""); + return { siteName, severityColor, shortMsg, message: a.message, triggeredAt: a.triggeredAt }; + }); + + function openLatestAlert() { + if (!latestAlert) return; + const allSites = document.querySelectorAll('[role="option"]'); + for (const el of allSites) { + if (el.textContent?.includes(latestAlert.siteName)) { + (el as HTMLElement).click(); + return; + } + } + goto("/dashboard"); + } + // Store reference to the hamburger button to restore focus when menu closes let hamburgerBtn: HTMLButtonElement | undefined = $state(); @@ -72,6 +93,18 @@ {alertCount} {/if} + {#if latestAlert} + + {/if}