Refactoring clear document UI

This commit is contained in:
yangdx
2025-04-01 13:31:14 +08:00
parent cd94e84267
commit 4c9c600472
6 changed files with 155 additions and 10 deletions

View File

@@ -382,6 +382,14 @@ export const clearDocuments = async (): Promise<DocActionResponse> => {
return response.data
}
export const clearCache = async (modes?: string[]): Promise<{
status: 'success' | 'fail'
message: string
}> => {
const response = await axiosInstance.post('/documents/clear_cache', { modes })
return response.data
}
export const getAuthStatus = async (): Promise<AuthStatusResponse> => {
try {
// Add a timeout to the request to prevent hanging

View File

@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react'
import { useState, useCallback, useEffect } from 'react'
import Button from '@/components/ui/Button'
import {
Dialog,
@@ -6,24 +6,79 @@ import {
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger
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 } from '@/api/lightrag'
import { clearDocuments, clearCache, getDocuments } from '@/api/lightrag'
import { useBackendState } from '@/stores/state'
import { EraserIcon } from 'lucide-react'
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>
)
export default function ClearDocumentsDialog() {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const [confirmText, setConfirmText] = useState('')
const [clearCacheOption, setClearCacheOption] = useState(false)
const isConfirmEnabled = confirmText.toLowerCase() === 'yes'
const check = useBackendState.use.check()
// 重置状态当对话框关闭时
useEffect(() => {
if (!open) {
setConfirmText('')
setClearCacheOption(false)
}
}, [open])
const handleClear = useCallback(async () => {
if (!isConfirmEnabled) return
try {
// 清空文档
const result = await clearDocuments()
// 如果选择了清空缓存,则清空缓存
if (clearCacheOption) {
try {
await clearCache()
toast.success(t('documentPanel.clearDocuments.cacheCleared'))
} catch (cacheErr) {
toast.error(t('documentPanel.clearDocuments.cacheClearFailed', { error: errorMessage(cacheErr) }))
}
}
if (result.status === 'success') {
toast.success(t('documentPanel.clearDocuments.success'))
// 刷新文档列表和后端状态
try {
await getDocuments()
check()
} catch (refreshErr) {
console.error('Error refreshing documents:', refreshErr)
}
setOpen(false)
} else {
toast.error(t('documentPanel.clearDocuments.failed', { message: result.message }))
@@ -31,7 +86,7 @@ export default function ClearDocumentsDialog() {
} catch (err) {
toast.error(t('documentPanel.clearDocuments.error', { error: errorMessage(err) }))
}
}, [setOpen, t])
}, [isConfirmEnabled, clearCacheOption, setOpen, t, check])
return (
<Dialog open={open} onOpenChange={setOpen}>
@@ -42,12 +97,58 @@ export default function ClearDocumentsDialog() {
</DialogTrigger>
<DialogContent className="sm:max-w-xl" onCloseAutoFocus={(e) => e.preventDefault()}>
<DialogHeader>
<DialogTitle>{t('documentPanel.clearDocuments.title')}</DialogTitle>
<DialogDescription>{t('documentPanel.clearDocuments.confirm')}</DialogDescription>
<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">
<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>
</DialogDescription>
</DialogHeader>
<Button variant="destructive" onClick={handleClear}>
{t('documentPanel.clearDocuments.confirmButton')}
</Button>
<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>
)

View File

@@ -32,14 +32,23 @@
"authDisabled": "تم تعطيل المصادقة. استخدام وضع بدون تسجيل دخول.",
"guestMode": "وضع بدون تسجيل دخول"
},
"common": {
"cancel": "إلغاء"
},
"documentPanel": {
"clearDocuments": {
"button": "مسح",
"tooltip": "مسح المستندات",
"title": "مسح المستندات",
"warning": "تحذير: سيؤدي هذا الإجراء إلى حذف جميع المستندات بشكل دائم ولا يمكن التراجع عنه!",
"confirm": "هل تريد حقًا مسح جميع المستندات؟",
"confirmPrompt": "اكتب 'yes' لتأكيد هذا الإجراء",
"confirmPlaceholder": "اكتب yes للتأكيد",
"clearCache": "مسح ذاكرة التخزين المؤقت أيضًا",
"confirmButton": "نعم",
"success": "تم مسح المستندات بنجاح",
"cacheCleared": "تم مسح ذاكرة التخزين المؤقت بنجاح",
"cacheClearFailed": "فشل مسح ذاكرة التخزين المؤقت:\n{{error}}",
"failed": "فشل مسح المستندات:\n{{message}}",
"error": "فشل مسح المستندات:\n{{error}}"
},

View File

@@ -32,14 +32,23 @@
"authDisabled": "Authentication is disabled. Using login free mode.",
"guestMode": "Login Free"
},
"common": {
"cancel": "Cancel"
},
"documentPanel": {
"clearDocuments": {
"button": "Clear",
"tooltip": "Clear documents",
"title": "Clear Documents",
"warning": "WARNING: This action will permanently delete all documents and cannot be undone!",
"confirm": "Do you really want to clear all documents?",
"confirmPrompt": "Type 'yes' to confirm this action",
"confirmPlaceholder": "Type yes to confirm",
"clearCache": "Also clear cache",
"confirmButton": "YES",
"success": "Documents cleared successfully",
"cacheCleared": "Cache cleared successfully",
"cacheClearFailed": "Failed to clear cache:\n{{error}}",
"failed": "Clear Documents Failed:\n{{message}}",
"error": "Clear Documents Failed:\n{{error}}"
},

View File

@@ -32,14 +32,23 @@
"authDisabled": "L'authentification est désactivée. Utilisation du mode sans connexion.",
"guestMode": "Mode sans connexion"
},
"common": {
"cancel": "Annuler"
},
"documentPanel": {
"clearDocuments": {
"button": "Effacer",
"tooltip": "Effacer les documents",
"title": "Effacer les documents",
"warning": "ATTENTION : Cette action supprimera définitivement tous les documents et ne peut pas être annulée !",
"confirm": "Voulez-vous vraiment effacer tous les documents ?",
"confirmPrompt": "Tapez 'yes' pour confirmer cette action",
"confirmPlaceholder": "Tapez yes pour confirmer",
"clearCache": "Effacer également le cache",
"confirmButton": "OUI",
"success": "Documents effacés avec succès",
"cacheCleared": "Cache effacé avec succès",
"cacheClearFailed": "Échec de l'effacement du cache :\n{{error}}",
"failed": "Échec de l'effacement des documents :\n{{message}}",
"error": "Échec de l'effacement des documents :\n{{error}}"
},

View File

@@ -32,14 +32,23 @@
"authDisabled": "认证已禁用,使用无需登陆模式。",
"guestMode": "无需登陆"
},
"common": {
"cancel": "取消"
},
"documentPanel": {
"clearDocuments": {
"button": "清空",
"tooltip": "清空文档",
"title": "清空文档",
"warning": "警告:此操作将永久删除所有文档,无法恢复!",
"confirm": "确定要清空所有文档吗?",
"confirmPrompt": "请输入 yes 确认操作",
"confirmPlaceholder": "输入 yes 确认",
"clearCache": "同时清空缓存",
"confirmButton": "确定",
"success": "文档清空成功",
"cacheCleared": "缓存清空成功",
"cacheClearFailed": "清空缓存失败:\n{{error}}",
"failed": "清空文档失败:\n{{message}}",
"error": "清空文档失败:\n{{error}}"
},