fix: align notification unread badge with panel visibility rules (#1520)

Stack success events were hidden from the panel but still counted unread on the bell and dashboard.

Share one visibility helper across badge, panel, and Recent Alerts.

Harden mark-all-read against partial API failures.

Fixes #1513
This commit is contained in:
Anso
2026-06-29 18:19:18 -04:00
committed by GitHub
parent 624b586887
commit 1b9a40f874
6 changed files with 136 additions and 22 deletions
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
import { Bell } from 'lucide-react';
import type { Stats, SystemStats, NotificationItem, HealthLevel } from './types';
import { deriveHealth } from './deriveHealth';
import { countVisibleUnread } from '@/lib/notificationVisibility';
interface HealthStatusBarProps {
stats: Stats;
@@ -78,7 +79,7 @@ export function HealthStatusBar({
);
const config = healthConfig[level];
const now = useTicker(SYNC_LABEL_TICK_MS);
const unreadAlerts = notifications.filter(n => !n.is_read).length;
const unreadAlerts = countVisibleUnread(notifications);
const running = `${stats.active}/${stats.total}`;
const cpuLabel = systemStats ? `${parseFloat(systemStats.cpu.usage).toFixed(0)}%` : '--';
const memLabel = systemStats ? formatGib(systemStats.memory.used) : '--';
@@ -5,6 +5,7 @@ import { Badge } from '@/components/ui/badge';
import { Info, AlertTriangle, AlertOctagon, CheckCircle2, Trash2, ChevronLeft, ChevronRight } from 'lucide-react';
import { toast } from '@/components/ui/toast-store';
import { formatRelativeTime } from '@/lib/utils';
import { filterPanelVisible } from '@/lib/notificationVisibility';
import type { NotificationItem } from './types';
import type { Node } from '@/context/NodeContext';
@@ -26,7 +27,7 @@ export function RecentAlerts({ notifications, nodes, onCleared }: RecentAlertsPr
const [clearing, setClearing] = useState(false);
const [page, setPage] = useState(0);
const sorted = notifications
const sorted = filterPanelVisible(notifications)
.slice()
.sort((a, b) => b.timestamp - a.timestamp);
@@ -93,7 +94,7 @@ export function RecentAlerts({ notifications, nodes, onCleared }: RecentAlertsPr
const Icon = config.icon;
return (
<div
key={n.id}
key={`${n.nodeId ?? 'local'}:${n.id}`}
className="flex items-center gap-2.5 py-1.5 px-1 rounded-sm hover:bg-accent/5"
>
<Icon className={`h-3.5 w-3.5 shrink-0 ${config.className}`} strokeWidth={1.5} />