import { useMemo } from "react"; import type { DirectiveWithProgress } from "../../lib/api"; import { useDirectiveEventSubscription } from "../../hooks/useDirectives"; export function EventsTab({ directive }: { directive: DirectiveWithProgress }) { // Subscribe to real-time events via SSE const { events: streamEvents, isConnected, error: sseError } = useDirectiveEventSubscription(directive.id); // Combine initial events with streamed events (avoiding duplicates) const allEvents = useMemo(() => { const eventMap = new Map(); // Add initial events first directive.recentEvents.forEach((e) => eventMap.set(e.id, e)); // Add streamed events (will override any duplicates) streamEvents.forEach((e) => eventMap.set(e.id, e)); // Sort by created_at descending (most recent first) return Array.from(eventMap.values()).sort( (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() ); }, [directive.recentEvents, streamEvents]); return (
{/* Connection status */}
{isConnected ? "\u25CF Live" : "\u25CB Connecting..."} {sseError && {sseError}}
{allEvents.length} events
{/* Event list */} {allEvents.length === 0 ? (

No events yet

) : (
{allEvents.map((event) => { const severityColors: Record = { info: "text-[#75aafc]", warning: "text-yellow-400", error: "text-red-400", critical: "text-red-600", }; const severityColor = severityColors[event.severity] || "text-[#556677]"; return (
{event.eventType} {event.actorType}
{new Date(event.createdAt).toLocaleString()}
{event.eventData != null && (
                    {JSON.stringify(event.eventData, null, 2)}
                  
)}
); })}
)}
); }