fix(web): /machine terminal visible prop, stop/restart confirmation, accurate waiting label

This commit is contained in:
Gabriel Brown
2026-07-11 13:36:54 -04:00
parent a5bc0434f3
commit 696f03e867
3 changed files with 172 additions and 29 deletions
@@ -1,8 +1,18 @@
'use client';
import type { ReactNode } from 'react';
import { Loader2, Play, RotateCw, Server, Square } from 'lucide-react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
Badge,
Button,
Card,
@@ -50,6 +60,48 @@ const Detail = ({ label, value }: { label: string; value: string }) => (
</div>
);
// Stopping or restarting the box tears down the SAME per-user container that a
// running agent thread job executes in, so both actions are destructive and get
// a confirmation step. Start is safe and stays a plain button.
const ConfirmLifecycleButton = ({
icon,
label,
busy,
title,
description,
confirmLabel,
onConfirm,
}: {
icon: ReactNode;
label: string;
busy: boolean;
title: string;
description: string;
confirmLabel: string;
onConfirm: () => void;
}) => (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button type='button' variant='outline' size='sm' disabled={busy}>
{icon}
{label}
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle>
<AlertDialogDescription>{description}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction variant='destructive' onClick={onConfirm}>
{confirmLabel}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
export const BoxStatusCard = ({
status,
pendingAction,
@@ -96,34 +148,36 @@ export const BoxStatusCard = ({
<div className='flex flex-wrap gap-2'>
{running ? (
<>
<Button
type='button'
variant='outline'
size='sm'
disabled={busy}
onClick={() => onAction('stop')}
>
{pendingAction === 'stop' ? (
<Loader2 className='size-4 animate-spin' />
) : (
<Square className='size-4' />
)}
Stop
</Button>
<Button
type='button'
variant='outline'
size='sm'
disabled={busy}
onClick={() => onAction('restart')}
>
{pendingAction === 'restart' ? (
<Loader2 className='size-4 animate-spin' />
) : (
<RotateCw className='size-4' />
)}
Restart
</Button>
<ConfirmLifecycleButton
label='Stop'
busy={busy}
icon={
pendingAction === 'stop' ? (
<Loader2 className='size-4 animate-spin' />
) : (
<Square className='size-4' />
)
}
title='Stop this machine?'
description='Stopping the machine shuts down the container it runs in. Any agent thread job currently running in this machine will be interrupted and lose its in-progress work.'
confirmLabel='Stop machine'
onConfirm={() => onAction('stop')}
/>
<ConfirmLifecycleButton
label='Restart'
busy={busy}
icon={
pendingAction === 'restart' ? (
<Loader2 className='size-4 animate-spin' />
) : (
<RotateCw className='size-4' />
)
}
title='Restart this machine?'
description='Restarting the machine recreates the container it runs in. Any agent thread job currently running in this machine will be interrupted and lose its in-progress work.'
confirmLabel='Restart machine'
onConfirm={() => onAction('restart')}
/>
</>
) : (
<Button