File size: 5,073 Bytes
eef0ccc 0e5f52f eef0ccc 0e5f52f eef0ccc 0e5f52f d760937 0e5f52f eef0ccc 77ca676 0e5f52f eef0ccc 6221908 eef0ccc 6221908 eef0ccc d760937 77ca676 29ee1c2 eef0ccc 0e5f52f eef0ccc 0e5f52f 6221908 1933c59 eef0ccc 1933c59 2e931df d760937 1933c59 d760937 1933c59 0e5f52f 2e931df 0e5f52f 77ca676 0e5f52f eef0ccc f8915e6 eef0ccc 0e5f52f 6221908 f8915e6 eef0ccc 6221908 eef0ccc 6221908 eef0ccc 6221908 eef0ccc 0e5f52f |
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
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 Checkbox from '@/components/ui/Checkbox'
import { toast } from 'sonner'
import { errorMessage } from '@/lib/utils'
import { clearDocuments, clearCache } from '@/api/lightrag'
import { EraserIcon, AlertTriangleIcon } from 'lucide-react'
import { useTranslation } from 'react-i18next'
// 简单的Label组件
const Label = ({
htmlFor,
className,
children,
...props
}: React.LabelHTMLAttributes<HTMLLabelElement>) => (
<label
htmlFor={htmlFor}
className={className}
{...props}
>
{children}
</label>
)
interface ClearDocumentsDialogProps {
onDocumentsCleared?: () => Promise<void>
}
export default function ClearDocumentsDialog({ onDocumentsCleared }: ClearDocumentsDialogProps) {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const [confirmText, setConfirmText] = useState('')
const [clearCacheOption, setClearCacheOption] = useState(false)
const isConfirmEnabled = confirmText.toLowerCase() === 'yes'
// 重置状态当对话框关闭时
useEffect(() => {
if (!open) {
setConfirmText('')
setClearCacheOption(false)
}
}, [open])
const handleClear = useCallback(async () => {
if (!isConfirmEnabled) return
try {
const result = await clearDocuments()
if (result.status !== 'success') {
toast.error(t('documentPanel.clearDocuments.failed', { message: result.message }))
setConfirmText('')
return
}
toast.success(t('documentPanel.clearDocuments.success'))
if (clearCacheOption) {
try {
await clearCache()
toast.success(t('documentPanel.clearDocuments.cacheCleared'))
} catch (cacheErr) {
toast.error(t('documentPanel.clearDocuments.cacheClearFailed', { error: errorMessage(cacheErr) }))
}
}
// Refresh document list if provided
if (onDocumentsCleared) {
onDocumentsCleared().catch(console.error)
}
// 所有操作成功后关闭对话框
setOpen(false)
} catch (err) {
toast.error(t('documentPanel.clearDocuments.error', { error: errorMessage(err) }))
setConfirmText('')
}
}, [isConfirmEnabled, clearCacheOption, setOpen, t, onDocumentsCleared])
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="outline" side="bottom" tooltip={t('documentPanel.clearDocuments.tooltip')} size="sm">
<EraserIcon/> {t('documentPanel.clearDocuments.button')}
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-xl" onCloseAutoFocus={(e) => e.preventDefault()}>
<DialogHeader>
<DialogTitle className="flex items-center gap-2 text-red-500 dark:text-red-400 font-bold">
<AlertTriangleIcon className="h-5 w-5" />
{t('documentPanel.clearDocuments.title')}
</DialogTitle>
<DialogDescription className="pt-2">
{t('documentPanel.clearDocuments.description')}
</DialogDescription>
</DialogHeader>
<div className="text-red-500 dark:text-red-400 font-semibold mb-4">
{t('documentPanel.clearDocuments.warning')}
</div>
<div className="mb-4">
{t('documentPanel.clearDocuments.confirm')}
</div>
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="confirm-text" className="text-sm font-medium">
{t('documentPanel.clearDocuments.confirmPrompt')}
</Label>
<Input
id="confirm-text"
value={confirmText}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setConfirmText(e.target.value)}
placeholder={t('documentPanel.clearDocuments.confirmPlaceholder')}
className="w-full"
/>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="clear-cache"
checked={clearCacheOption}
onCheckedChange={(checked: boolean | 'indeterminate') => setClearCacheOption(checked === true)}
/>
<Label htmlFor="clear-cache" className="text-sm font-medium cursor-pointer">
{t('documentPanel.clearDocuments.clearCache')}
</Label>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
{t('common.cancel')}
</Button>
<Button
variant="destructive"
onClick={handleClear}
disabled={!isConfirmEnabled}
>
{t('documentPanel.clearDocuments.confirmButton')}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
|