"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import type { AgentSession } from "@mosaic/shared"; import { Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { apiPost } from "@/lib/api/client"; const CONFIRM_TEXT = "KILL ALL"; const AUTO_CLOSE_DELAY_MS = 2_000; type KillScope = "internal" | "all"; export interface KillAllDialogProps { sessions: AgentSession[]; onComplete?: () => void; } export function KillAllDialog({ sessions, onComplete }: KillAllDialogProps): React.JSX.Element { const [open, setOpen] = useState(false); const [scope, setScope] = useState("internal"); const [confirmationInput, setConfirmationInput] = useState(""); const [isKilling, setIsKilling] = useState(false); const [completedCount, setCompletedCount] = useState(0); const [targetCount, setTargetCount] = useState(0); const [successCount, setSuccessCount] = useState(null); const closeTimeoutRef = useRef | null>(null); const internalSessions = useMemo( () => sessions.filter((session) => session.providerType.toLowerCase() === "internal"), [sessions] ); const scopedSessions = useMemo( () => (scope === "all" ? sessions : internalSessions), [scope, sessions, internalSessions] ); const hasConfirmation = confirmationInput === CONFIRM_TEXT; const isConfirmDisabled = isKilling || successCount !== null || !hasConfirmation || scopedSessions.length === 0; useEffect((): (() => void) => { return (): void => { if (closeTimeoutRef.current !== null) { clearTimeout(closeTimeoutRef.current); } }; }, []); const resetState = (): void => { setScope("internal"); setConfirmationInput(""); setIsKilling(false); setCompletedCount(0); setTargetCount(0); setSuccessCount(null); }; const handleOpenChange = (nextOpen: boolean): void => { if (!nextOpen && isKilling) { return; } if (!nextOpen) { if (closeTimeoutRef.current !== null) { clearTimeout(closeTimeoutRef.current); } resetState(); } setOpen(nextOpen); }; const handleKillAll = async (): Promise => { if (isConfirmDisabled) { return; } const targetSessions = [...scopedSessions]; setIsKilling(true); setCompletedCount(0); setTargetCount(targetSessions.length); setSuccessCount(null); const killRequests = targetSessions.map(async (session) => { try { await apiPost<{ message: string }>(`/api/mission-control/sessions/${session.id}/kill`, { force: true, }); return true; } catch { return false; } finally { setCompletedCount((currentCount) => currentCount + 1); } }); const results = await Promise.all(killRequests); const successfulKills = results.filter(Boolean).length; setIsKilling(false); setSuccessCount(successfulKills); onComplete?.(); closeTimeoutRef.current = setTimeout(() => { setOpen(false); resetState(); }, AUTO_CLOSE_DELAY_MS); }; return ( Kill All Agents This force-kills every selected agent session. This action cannot be undone.
Scope
) => { setConfirmationInput(event.target.value); }} placeholder={CONFIRM_TEXT} autoComplete="off" disabled={isKilling} />
{scopedSessions.length === 0 ? (

No sessions in the selected scope.

) : null} {isKilling ? (
) : successCount !== null ? (

Killed {successCount} of {targetCount} agents. Closing...

) : null}
); }