All files / web/src/components/ai-providers delete-model-dialog.tsx

0% Statements 0/80
100% Branches 1/1
100% Functions 1/1
0% Lines 0/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114                                                                                                                                                                                                                                   
'use client';
 
import type { Model } from '@shared/types/data/model';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@web/components/ui/alert-dialog';
import { Input } from '@web/components/ui/input';
import { Label } from '@web/components/ui/label';
import { AlertTriangle } from 'lucide-react';
import type { ReactElement } from 'react';
import { useId, useState } from 'react';
 
interface DeleteModelDialogProps {
  model: Model | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onConfirm: () => Promise<void>;
}
 
export function DeleteModelDialog({
  model,
  open,
  onOpenChange,
  onConfirm,
}: DeleteModelDialogProps): ReactElement {
  const [confirmName, setConfirmName] = useState('');
  const [isDeleting, setIsDeleting] = useState(false);
  const inputId = useId();
 
  const handleConfirm = async () => {
    if (!model || confirmName !== model.model_name) return;
 
    setIsDeleting(true);
    try {
      await onConfirm();
      onOpenChange(false);
      setConfirmName('');
    } catch (error) {
      console.error('Error deleting model:', error);
    } finally {
      setIsDeleting(false);
    }
  };
 
  const handleCancel = () => {
    setConfirmName('');
    onOpenChange(false);
  };
 
  const isConfirmDisabled =
    !model || confirmName !== model.model_name || isDeleting;
 
  return (
    <AlertDialog open={open} onOpenChange={onOpenChange}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle className="flex items-center gap-2">
            <AlertTriangle className="h-5 w-5 text-destructive" />
            Delete Model
          </AlertDialogTitle>
          <AlertDialogDescription className="space-y-4 pt-4">
            <p>
              This action cannot be undone. This will permanently delete the
              model <span className="font-semibold">{model?.model_name}</span>{' '}
              and remove it from all skills that use it.
            </p>
            <div className="space-y-2">
              <Label htmlFor={inputId}>
                Type{' '}
                <span className="font-mono font-semibold">
                  {model?.model_name}
                </span>{' '}
                to confirm:
              </Label>
              <Input
                id={inputId}
                value={confirmName}
                onChange={(e) => setConfirmName(e.target.value)}
                placeholder="Enter model name"
                className="font-mono"
                disabled={isDeleting}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && !isConfirmDisabled) {
                    handleConfirm();
                  }
                }}
              />
            </div>
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel onClick={handleCancel} disabled={isDeleting}>
            Cancel
          </AlertDialogCancel>
          <AlertDialogAction
            onClick={handleConfirm}
            disabled={isConfirmDisabled}
            variant={'destructive'}
          >
            {isDeleting ? 'Deleting...' : 'Delete Model'}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}