import { useState, useRef, useEffect } from "react"; import { Lightbulb, Layers, Target, Loader2, HelpCircle, X } from "lucide-react"; import type { AiSessionSummary } from "../api"; interface BackgroundTasksIndicatorProps { sessions: AiSessionSummary[]; generating: number; needsInput: number; onOpenSession: (session: AiSessionSummary) => void; onDismissSession: (id: string) => void; } const TYPE_ICONS = { planning: Lightbulb, subtask: Layers, mission_interview: Target, } as const; const TYPE_LABELS = { planning: "Planning", subtask: "Subtask Breakdown", mission_interview: "Mission Interview", } as const; export function BackgroundTasksIndicator({ sessions, generating, needsInput, onOpenSession, onDismissSession, }: BackgroundTasksIndicatorProps) { const [popoverOpen, setPopoverOpen] = useState(false); const containerRef = useRef(null); // Close popover on outside click useEffect(() => { if (!popoverOpen) return; const handler = (e: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(e.target as Node)) { setPopoverOpen(false); } }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [popoverOpen]); if (sessions.length === 0) return null; const total = sessions.length; const hasAttention = needsInput > 0; return (
{popoverOpen && (
Background Tasks
{sessions.map((session) => { const Icon = TYPE_ICONS[session.type]; const isGenerating = session.status === "generating"; const isAwaiting = session.status === "awaiting_input"; return (
{ onOpenSession(session); setPopoverOpen(false); }} >
{session.title}
{TYPE_LABELS[session.type]} {isGenerating && " — generating..."} {isAwaiting && " — needs input"}
{isGenerating && ( )} {isAwaiting && ( )}
); })}
)}
); }