import { useState, useCallback, useEffect } from 'react' import Button from '@/components/ui/Button' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from '@/components/ui/Dialog' import Input from '@/components/ui/Input' import { toast } from 'sonner' import { errorMessage } from '@/lib/utils' import { deleteDocuments } from '@/api/lightrag' import { TrashIcon, AlertTriangleIcon } from 'lucide-react' import { useTranslation } from 'react-i18next' // Simple Label component const Label = ({ htmlFor, className, children, ...props }: React.LabelHTMLAttributes) => ( ) interface DeleteDocumentsDialogProps { selectedDocIds: string[] totalCompletedCount: number onDocumentsDeleted?: () => Promise } export default function DeleteDocumentsDialog({ selectedDocIds, totalCompletedCount, onDocumentsDeleted }: DeleteDocumentsDialogProps) { const { t } = useTranslation() const [open, setOpen] = useState(false) const [confirmText, setConfirmText] = useState('') const [deleteFile, setDeleteFile] = useState(false) const [isDeleting, setIsDeleting] = useState(false) const isConfirmEnabled = confirmText.toLowerCase() === 'yes' && !isDeleting // Reset state when dialog closes useEffect(() => { if (!open) { setConfirmText('') setDeleteFile(false) setIsDeleting(false) } }, [open]) const handleDelete = useCallback(async () => { if (!isConfirmEnabled || selectedDocIds.length === 0) return // Check if user is trying to delete all completed documents if (selectedDocIds.length === totalCompletedCount && totalCompletedCount > 0) { toast.error(t('documentPanel.deleteDocuments.cannotDeleteAll')) return } setIsDeleting(true) try { const result = await deleteDocuments(selectedDocIds, deleteFile) if (result.status === 'deletion_started') { toast.success(t('documentPanel.deleteDocuments.success', { count: selectedDocIds.length })) } else if (result.status === 'busy') { toast.error(t('documentPanel.deleteDocuments.busy')) setConfirmText('') setIsDeleting(false) return } else if (result.status === 'not_allowed') { toast.error(t('documentPanel.deleteDocuments.notAllowed')) setConfirmText('') setIsDeleting(false) return } else { toast.error(t('documentPanel.deleteDocuments.failed', { message: result.message })) setConfirmText('') setIsDeleting(false) return } // Refresh document list if provided if (onDocumentsDeleted) { onDocumentsDeleted().catch(console.error) } // Close dialog after successful operation setOpen(false) } catch (err) { toast.error(t('documentPanel.deleteDocuments.error', { error: errorMessage(err) })) setConfirmText('') } finally { setIsDeleting(false) } }, [isConfirmEnabled, selectedDocIds, totalCompletedCount, deleteFile, setOpen, t, onDocumentsDeleted]) return ( e.preventDefault()}> {t('documentPanel.deleteDocuments.title')} {t('documentPanel.deleteDocuments.description', { count: selectedDocIds.length })}
{t('documentPanel.deleteDocuments.warning')}
{t('documentPanel.deleteDocuments.confirm', { count: selectedDocIds.length })}
) => setConfirmText(e.target.value)} placeholder={t('documentPanel.deleteDocuments.confirmPlaceholder')} className="w-full" disabled={isDeleting} />
setDeleteFile(e.target.checked)} disabled={isDeleting} className="h-4 w-4 text-red-600 focus:ring-red-500 border-gray-300 rounded" />
) }