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>
  )
}