import { Trans, useLingui } from "@lingui/react/macro"; import type { ComputerStatus } from "@rakazo/contracts"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@rakazo/ui-web"; import { MoreHorizontal } from "lucide-react"; import { useState } from "react"; import { computerUpdates } from "../lib/computer-updates"; import { rpc } from "../lib/rpc"; type Action = "recover" | "reset" | "update"; export function ComputerMaintenanceActions({ botId, computer, onChanged, }: { botId: string; computer: ComputerStatus | null; onChanged: () => Promise; }) { const { t } = useLingui(); const [menuOpen, setMenuOpen] = useState(false); const [pending, setPending] = useState(null); const [confirmReset, setConfirmReset] = useState(false); const [error, setError] = useState(null); if (!computer) return null; const busy = Boolean(computer.busyBotName) || computer.state === "booting"; const showRecover = computer.state === "error" || computer.state === "running" || computer.state === "suspended" || computer.state === "stopped"; const showReset = showRecover; const showUpdate = computer.canUpdate; const hasActions = showRecover || showReset || showUpdate; if (!hasActions) return null; async function run(action: Action) { setPending(action); setError(null); try { if (action === "recover") await computerUpdates.start(botId, "recover"); else if (action === "reset") await rpc.computer.reset({ botId }); else await computerUpdates.start(botId); setConfirmReset(false); setMenuOpen(false); await onChanged(); } catch (err) { setError(err instanceof Error ? err.message : t`Could not update computer`); } finally { setPending(null); } } function openResetConfirm() { setError(null); setMenuOpen(false); setConfirmReset(true); } // Escape closes the dialog inside the popup, so Shell's Escape handler does not also // close the computer overlay. const resetDialog = ( { if (!open) setConfirmReset(false); }} > Reset computer? Restore the last saved workspace. Unsaved work on the computer is lost. {error ?

{error}

: null} Cancel void run("reset")}> {pending === "reset" ? Resetting… : Reset}
); return ( <> { if (open) setError(null); setMenuOpen(open); }} > } > {showRecover ? ( void run("recover")} > {pending === "recover" ? Recovering… : Recover computer} ) : null} {showReset ? ( {pending === "reset" ? Resetting… : Reset computer} ) : null} {showUpdate ? ( void run("update")} > {pending === "update" ? Updating… : Update computer} ) : null} {error ?

{error}

: null}
{resetDialog} ); }