yangdx commited on
Commit
ab73985
·
1 Parent(s): 70a9b1c

Add i18n translation for upload module

Browse files
lightrag_webui/src/components/documents/UploadDocumentsDialog.tsx CHANGED
@@ -21,18 +21,14 @@ export default function UploadDocumentsDialog() {
21
  const [open, setOpen] = useState(false)
22
  const [isUploading, setIsUploading] = useState(false)
23
  const [progresses, setProgresses] = useState<Record<string, number>>({})
24
- // Track upload errors for each file
25
  const [fileErrors, setFileErrors] = useState<Record<string, string>>({})
26
 
27
  const handleDocumentsUpload = useCallback(
28
  async (filesToUpload: File[]) => {
29
  setIsUploading(true)
30
-
31
- // Reset error states before new upload
32
  setFileErrors({})
33
 
34
  try {
35
- // Use a single toast for the entire batch upload process
36
  toast.promise(
37
  (async () => {
38
  try {
@@ -40,14 +36,13 @@ export default function UploadDocumentsDialog() {
40
  filesToUpload.map(async (file) => {
41
  try {
42
  const result = await uploadDocument(file, (percentCompleted: number) => {
43
- console.debug(t('documentPanel.uploadDocuments.uploading', { name: file.name, percent: percentCompleted }))
44
  setProgresses((pre) => ({
45
  ...pre,
46
  [file.name]: percentCompleted
47
  }))
48
  })
49
 
50
- // Store error message if upload failed
51
  if (result.status !== 'success') {
52
  setFileErrors(prev => ({
53
  ...prev,
@@ -55,7 +50,6 @@ export default function UploadDocumentsDialog() {
55
  }))
56
  }
57
  } catch (err) {
58
- // Store error message from exception
59
  setFileErrors(prev => ({
60
  ...prev,
61
  [file.name]: errorMessage(err)
@@ -63,21 +57,18 @@ export default function UploadDocumentsDialog() {
63
  }
64
  })
65
  )
66
- // Keep dialog open to show final status
67
- // User needs to close dialog manually
68
  } catch (error) {
69
  console.error('Upload failed:', error)
70
  }
71
  })(),
72
  {
73
- loading: t('documentPanel.uploadDocuments.uploading.batch'),
74
- success: t('documentPanel.uploadDocuments.success.batch'),
75
- error: t('documentPanel.uploadDocuments.error.batch')
76
  }
77
  )
78
  } catch (err) {
79
- // Handle general upload errors
80
- toast.error(`Upload error: ${errorMessage(err)}`)
81
  } finally {
82
  setIsUploading(false)
83
  }
@@ -89,12 +80,10 @@ export default function UploadDocumentsDialog() {
89
  <Dialog
90
  open={open}
91
  onOpenChange={(open) => {
92
- // Prevent closing dialog during upload
93
  if (isUploading) {
94
  return
95
  }
96
  if (!open) {
97
- // Reset states when dialog is closed
98
  setProgresses({})
99
  setFileErrors({})
100
  }
 
21
  const [open, setOpen] = useState(false)
22
  const [isUploading, setIsUploading] = useState(false)
23
  const [progresses, setProgresses] = useState<Record<string, number>>({})
 
24
  const [fileErrors, setFileErrors] = useState<Record<string, string>>({})
25
 
26
  const handleDocumentsUpload = useCallback(
27
  async (filesToUpload: File[]) => {
28
  setIsUploading(true)
 
 
29
  setFileErrors({})
30
 
31
  try {
 
32
  toast.promise(
33
  (async () => {
34
  try {
 
36
  filesToUpload.map(async (file) => {
37
  try {
38
  const result = await uploadDocument(file, (percentCompleted: number) => {
39
+ console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
40
  setProgresses((pre) => ({
41
  ...pre,
42
  [file.name]: percentCompleted
43
  }))
44
  })
45
 
 
46
  if (result.status !== 'success') {
47
  setFileErrors(prev => ({
48
  ...prev,
 
50
  }))
51
  }
52
  } catch (err) {
 
53
  setFileErrors(prev => ({
54
  ...prev,
55
  [file.name]: errorMessage(err)
 
57
  }
58
  })
59
  )
 
 
60
  } catch (error) {
61
  console.error('Upload failed:', error)
62
  }
63
  })(),
64
  {
65
+ loading: t('documentPanel.uploadDocuments.batch.uploading'),
66
+ success: t('documentPanel.uploadDocuments.batch.success'),
67
+ error: t('documentPanel.uploadDocuments.batch.error')
68
  }
69
  )
70
  } catch (err) {
71
+ toast.error(t('documentPanel.uploadDocuments.generalError', { error: errorMessage(err) }))
 
72
  } finally {
73
  setIsUploading(false)
74
  }
 
80
  <Dialog
81
  open={open}
82
  onOpenChange={(open) => {
 
83
  if (isUploading) {
84
  return
85
  }
86
  if (!open) {
 
87
  setProgresses({})
88
  setFileErrors({})
89
  }
lightrag_webui/src/components/ui/FileUploader.tsx CHANGED
@@ -6,6 +6,7 @@ import * as React from 'react'
6
  import { FileText, Upload, X } from 'lucide-react'
7
  import Dropzone, { type DropzoneProps, type FileRejection } from 'react-dropzone'
8
  import { toast } from 'sonner'
 
9
 
10
  import { cn } from '@/lib/utils'
11
  import { useControllableState } from '@radix-ui/react-use-controllable-state'
@@ -119,6 +120,7 @@ function formatBytes(
119
  }
120
 
121
  function FileUploader(props: FileUploaderProps) {
 
122
  const {
123
  value: valueProp,
124
  onValueChange,
@@ -143,12 +145,12 @@ function FileUploader(props: FileUploaderProps) {
143
  const onDrop = React.useCallback(
144
  (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
145
  if (!multiple && maxFileCount === 1 && acceptedFiles.length > 1) {
146
- toast.error('Cannot upload more than 1 file at a time')
147
  return
148
  }
149
 
150
  if ((files?.length ?? 0) + acceptedFiles.length > maxFileCount) {
151
- toast.error(`Cannot upload more than ${maxFileCount} files`)
152
  return
153
  }
154
 
@@ -164,7 +166,7 @@ function FileUploader(props: FileUploaderProps) {
164
 
165
  if (rejectedFiles.length > 0) {
166
  rejectedFiles.forEach(({ file }) => {
167
- toast.error(`File ${file.name} was rejected`)
168
  })
169
  }
170
 
@@ -173,7 +175,7 @@ function FileUploader(props: FileUploaderProps) {
173
  }
174
  },
175
 
176
- [files, maxFileCount, multiple, onUpload, setFiles]
177
  )
178
 
179
  function onRemove(index: number) {
@@ -226,7 +228,7 @@ function FileUploader(props: FileUploaderProps) {
226
  <div className="rounded-full border border-dashed p-3">
227
  <Upload className="text-muted-foreground size-7" aria-hidden="true" />
228
  </div>
229
- <p className="text-muted-foreground font-medium">Drop the files here</p>
230
  </div>
231
  ) : (
232
  <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
@@ -235,18 +237,18 @@ function FileUploader(props: FileUploaderProps) {
235
  </div>
236
  <div className="flex flex-col gap-px">
237
  <p className="text-muted-foreground font-medium">
238
- Drag and drop files here, or click to select files
239
  </p>
240
  {description ? (
241
  <p className="text-muted-foreground/70 text-sm">{description}</p>
242
  ) : (
243
  <p className="text-muted-foreground/70 text-sm">
244
- You can upload
245
- {maxFileCount > 1
246
- ? ` ${maxFileCount === Infinity ? 'multiple' : maxFileCount}
247
- files (up to ${formatBytes(maxSize)} each)`
248
- : ` a file with ${formatBytes(maxSize)}`}
249
- Supported formats: TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS
250
  </p>
251
  )}
252
  </div>
@@ -301,6 +303,7 @@ interface FileCardProps {
301
  }
302
 
303
  function FileCard({ file, progress, error, onRemove }: FileCardProps) {
 
304
  return (
305
  <div className="relative flex items-center gap-2.5">
306
  <div className="flex flex-1 gap-2.5">
@@ -323,7 +326,7 @@ function FileCard({ file, progress, error, onRemove }: FileCardProps) {
323
  <div className="flex items-center gap-2">
324
  <Button type="button" variant="outline" size="icon" className="size-7" onClick={onRemove}>
325
  <X className="size-4" aria-hidden="true" />
326
- <span className="sr-only">Remove file</span>
327
  </Button>
328
  </div>
329
  </div>
 
6
  import { FileText, Upload, X } from 'lucide-react'
7
  import Dropzone, { type DropzoneProps, type FileRejection } from 'react-dropzone'
8
  import { toast } from 'sonner'
9
+ import { useTranslation } from 'react-i18next'
10
 
11
  import { cn } from '@/lib/utils'
12
  import { useControllableState } from '@radix-ui/react-use-controllable-state'
 
120
  }
121
 
122
  function FileUploader(props: FileUploaderProps) {
123
+ const { t } = useTranslation()
124
  const {
125
  value: valueProp,
126
  onValueChange,
 
145
  const onDrop = React.useCallback(
146
  (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
147
  if (!multiple && maxFileCount === 1 && acceptedFiles.length > 1) {
148
+ toast.error(t('documentPanel.uploadDocuments.fileUploader.singleFileLimit'))
149
  return
150
  }
151
 
152
  if ((files?.length ?? 0) + acceptedFiles.length > maxFileCount) {
153
+ toast.error(t('documentPanel.uploadDocuments.fileUploader.maxFilesLimit', { count: maxFileCount }))
154
  return
155
  }
156
 
 
166
 
167
  if (rejectedFiles.length > 0) {
168
  rejectedFiles.forEach(({ file }) => {
169
+ toast.error(t('documentPanel.uploadDocuments.fileUploader.fileRejected', { name: file.name }))
170
  })
171
  }
172
 
 
175
  }
176
  },
177
 
178
+ [files, maxFileCount, multiple, onUpload, setFiles, t]
179
  )
180
 
181
  function onRemove(index: number) {
 
228
  <div className="rounded-full border border-dashed p-3">
229
  <Upload className="text-muted-foreground size-7" aria-hidden="true" />
230
  </div>
231
+ <p className="text-muted-foreground font-medium">{t('documentPanel.uploadDocuments.fileUploader.dropHere')}</p>
232
  </div>
233
  ) : (
234
  <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
 
237
  </div>
238
  <div className="flex flex-col gap-px">
239
  <p className="text-muted-foreground font-medium">
240
+ {t('documentPanel.uploadDocuments.fileUploader.dragAndDrop')}
241
  </p>
242
  {description ? (
243
  <p className="text-muted-foreground/70 text-sm">{description}</p>
244
  ) : (
245
  <p className="text-muted-foreground/70 text-sm">
246
+ {t('documentPanel.uploadDocuments.fileUploader.uploadDescription', {
247
+ count: maxFileCount,
248
+ isMultiple: maxFileCount === Infinity,
249
+ maxSize: formatBytes(maxSize)
250
+ })}
251
+ {t('documentPanel.uploadDocuments.fileTypes')}
252
  </p>
253
  )}
254
  </div>
 
303
  }
304
 
305
  function FileCard({ file, progress, error, onRemove }: FileCardProps) {
306
+ const { t } = useTranslation()
307
  return (
308
  <div className="relative flex items-center gap-2.5">
309
  <div className="flex flex-1 gap-2.5">
 
326
  <div className="flex items-center gap-2">
327
  <Button type="button" variant="outline" size="icon" className="size-7" onClick={onRemove}>
328
  <X className="size-4" aria-hidden="true" />
329
+ <span className="sr-only">{t('documentPanel.uploadDocuments.fileUploader.removeFile')}</span>
330
  </Button>
331
  </div>
332
  </div>
lightrag_webui/src/locales/ar.json CHANGED
@@ -48,12 +48,28 @@
48
  "tooltip": "رفع المستندات",
49
  "title": "رفع المستندات",
50
  "description": "اسحب وأفلت مستنداتك هنا أو انقر للتصفح.",
51
- "uploading": "جارٍ الرفع {{name}}: {{percent}}%",
52
- "success": "نجاح الرفع:\nتم رفع {{name}} بنجاح",
53
- "failed": "فشل الرفع:\n{{name}}\n{{message}}",
54
- "error": "فشل الرفع:\n{{name}}\n{{error}}",
 
 
 
 
 
 
 
55
  "generalError": "فشل الرفع\n{{error}}",
56
- "fileTypes": "الأنواع المدعومة: TXT، MD، DOCX، PDF، PPTX، RTF، ODT، EPUB، HTML، HTM، TEX، JSON، XML، YAML، YML، CSV، LOG، CONF، INI، PROPERTIES، SQL، BAT، SH، C، CPP، PY، JAVA، JS، TS، SWIFT، GO، RB، PHP، CSS، SCSS، LESS"
 
 
 
 
 
 
 
 
 
57
  },
58
  "documentManager": {
59
  "title": "إدارة المستندات",
 
48
  "tooltip": "رفع المستندات",
49
  "title": "رفع المستندات",
50
  "description": "اسحب وأفلت مستنداتك هنا أو انقر للتصفح.",
51
+ "single": {
52
+ "uploading": "جارٍ الرفع {{name}}: {{percent}}%",
53
+ "success": "نجاح الرفع:\nتم رفع {{name}} بنجاح",
54
+ "failed": "فشل الرفع:\n{{name}}\n{{message}}",
55
+ "error": "فشل الرفع:\n{{name}}\n{{error}}"
56
+ },
57
+ "batch": {
58
+ "uploading": "جارٍ رفع الملفات...",
59
+ "success": "تم رفع الملفات بنجاح",
60
+ "error": "فشل رفع بعض الملفات"
61
+ },
62
  "generalError": "فشل الرفع\n{{error}}",
63
+ "fileTypes": "الأنواع المدعومة: TXT، MD، DOCX، PDF، PPTX، RTF، ODT، EPUB، HTML، HTM، TEX، JSON، XML، YAML، YML، CSV، LOG، CONF، INI، PROPERTIES، SQL، BAT، SH، C، CPP، PY، JAVA، JS، TS، SWIFT، GO، RB، PHP، CSS، SCSS، LESS",
64
+ "fileUploader": {
65
+ "singleFileLimit": "لا يمكن رفع أكثر من ملف واحد في المرة الواحدة",
66
+ "maxFilesLimit": "لا يمكن رفع أكثر من {{count}} ملفات",
67
+ "fileRejected": "تم رفض الملف {{name}}",
68
+ "dropHere": "أفلت الملفات هنا",
69
+ "dragAndDrop": "اسحب وأفلت الملفات هنا، أو انقر للاختيار",
70
+ "removeFile": "إزالة الملف",
71
+ "uploadDescription": "يمكنك رفع {{isMultiple ? 'عدة' : count}} ملفات (حتى {{maxSize}} لكل منها)"
72
+ }
73
  },
74
  "documentManager": {
75
  "title": "إدارة المستندات",
lightrag_webui/src/locales/en.json CHANGED
@@ -48,12 +48,28 @@
48
  "tooltip": "Upload documents",
49
  "title": "Upload Documents",
50
  "description": "Drag and drop your documents here or click to browse.",
51
- "uploading": "Uploading {{name}}: {{percent}}%",
52
- "success": "Upload Success:\n{{name}} uploaded successfully",
53
- "failed": "Upload Failed:\n{{name}}\n{{message}}",
54
- "error": "Upload Failed:\n{{name}}\n{{error}}",
 
 
 
 
 
 
 
55
  "generalError": "Upload Failed\n{{error}}",
56
- "fileTypes": "Supported types: TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS"
 
 
 
 
 
 
 
 
 
57
  },
58
  "documentManager": {
59
  "title": "Document Management",
@@ -95,15 +111,15 @@
95
  "pipelineStatus": {
96
  "title": "Pipeline Status",
97
  "busy": "Pipeline Busy",
98
- "requestPending": "Reques Pending",
99
  "jobName": "Job Name",
100
  "startTime": "Start Time",
101
  "progress": "Progress",
102
  "unit": "batch",
103
  "latestMessage": "Latest Message",
104
- "historyMessages": "History Message",
105
  "errors": {
106
- "fetchFailed": "Fail to get pipeline status\n{{error}}"
107
  }
108
  }
109
  },
 
48
  "tooltip": "Upload documents",
49
  "title": "Upload Documents",
50
  "description": "Drag and drop your documents here or click to browse.",
51
+ "single": {
52
+ "uploading": "Uploading {{name}}: {{percent}}%",
53
+ "success": "Upload Success:\n{{name}} uploaded successfully",
54
+ "failed": "Upload Failed:\n{{name}}\n{{message}}",
55
+ "error": "Upload Failed:\n{{name}}\n{{error}}"
56
+ },
57
+ "batch": {
58
+ "uploading": "Uploading files...",
59
+ "success": "Files uploaded successfully",
60
+ "error": "Some files failed to upload"
61
+ },
62
  "generalError": "Upload Failed\n{{error}}",
63
+ "fileTypes": "Supported types: TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS",
64
+ "fileUploader": {
65
+ "singleFileLimit": "Cannot upload more than 1 file at a time",
66
+ "maxFilesLimit": "Cannot upload more than {{count}} files",
67
+ "fileRejected": "File {{name}} was rejected",
68
+ "dropHere": "Drop the files here",
69
+ "dragAndDrop": "Drag and drop files here, or click to select files",
70
+ "removeFile": "Remove file",
71
+ "uploadDescription": "You can upload {{isMultiple ? 'multiple' : count}} files (up to {{maxSize}} each)"
72
+ }
73
  },
74
  "documentManager": {
75
  "title": "Document Management",
 
111
  "pipelineStatus": {
112
  "title": "Pipeline Status",
113
  "busy": "Pipeline Busy",
114
+ "requestPending": "Request Pending",
115
  "jobName": "Job Name",
116
  "startTime": "Start Time",
117
  "progress": "Progress",
118
  "unit": "batch",
119
  "latestMessage": "Latest Message",
120
+ "historyMessages": "History Messages",
121
  "errors": {
122
+ "fetchFailed": "Failed to get pipeline status\n{{error}}"
123
  }
124
  }
125
  },
lightrag_webui/src/locales/fr.json CHANGED
@@ -48,12 +48,28 @@
48
  "tooltip": "Télécharger des documents",
49
  "title": "Télécharger des documents",
50
  "description": "Glissez-déposez vos documents ici ou cliquez pour parcourir.",
51
- "uploading": "Téléchargement de {{name}} : {{percent}}%",
52
- "success": "Succès du téléchargement :\n{{name}} téléchargé avec succès",
53
- "failed": "Échec du téléchargement :\n{{name}}\n{{message}}",
54
- "error": "Échec du téléchargement :\n{{name}}\n{{error}}",
 
 
 
 
 
 
 
55
  "generalError": "Échec du téléchargement\n{{error}}",
56
- "fileTypes": "Types pris en charge : TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS"
 
 
 
 
 
 
 
 
 
57
  },
58
  "documentManager": {
59
  "title": "Gestion des documents",
 
48
  "tooltip": "Télécharger des documents",
49
  "title": "Télécharger des documents",
50
  "description": "Glissez-déposez vos documents ici ou cliquez pour parcourir.",
51
+ "single": {
52
+ "uploading": "Téléchargement de {{name}} : {{percent}}%",
53
+ "success": "Succès du téléchargement :\n{{name}} téléchargé avec succès",
54
+ "failed": "Échec du téléchargement :\n{{name}}\n{{message}}",
55
+ "error": "Échec du téléchargement :\n{{name}}\n{{error}}"
56
+ },
57
+ "batch": {
58
+ "uploading": "Téléchargement des fichiers...",
59
+ "success": "Fichiers téléchargés avec succès",
60
+ "error": "Certains fichiers n'ont pas pu être téléchargés"
61
+ },
62
  "generalError": "Échec du téléchargement\n{{error}}",
63
+ "fileTypes": "Types pris en charge : TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS",
64
+ "fileUploader": {
65
+ "singleFileLimit": "Impossible de télécharger plus d'un fichier à la fois",
66
+ "maxFilesLimit": "Impossible de télécharger plus de {{count}} fichiers",
67
+ "fileRejected": "Le fichier {{name}} a été rejeté",
68
+ "dropHere": "Déposez les fichiers ici",
69
+ "dragAndDrop": "Glissez et déposez les fichiers ici, ou cliquez pour sélectionner",
70
+ "removeFile": "Supprimer le fichier",
71
+ "uploadDescription": "Vous pouvez télécharger {{isMultiple ? 'plusieurs' : count}} fichiers (jusqu'à {{maxSize}} chacun)"
72
+ }
73
  },
74
  "documentManager": {
75
  "title": "Gestion des documents",
lightrag_webui/src/locales/zh.json CHANGED
@@ -48,12 +48,28 @@
48
  "tooltip": "上传文档",
49
  "title": "上传文档",
50
  "description": "拖拽文件到此处或点击浏览",
51
- "uploading": "正在上传 {{name}}:{{percent}}%",
52
- "success": "上传成功:\n{{name}} 上传完成",
53
- "failed": "上传失败:\n{{name}}\n{{message}}",
54
- "error": "上传失败:\n{{name}}\n{{error}}",
 
 
 
 
 
 
 
55
  "generalError": "上传失败\n{{error}}",
56
- "fileTypes": "支持的文件类型:TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS"
 
 
 
 
 
 
 
 
 
57
  },
58
  "documentManager": {
59
  "title": "文档管理",
 
48
  "tooltip": "上传文档",
49
  "title": "上传文档",
50
  "description": "拖拽文件到此处或点击浏览",
51
+ "single": {
52
+ "uploading": "正在上传 {{name}}:{{percent}}%",
53
+ "success": "上传成功:\n{{name}} 上传完成",
54
+ "failed": "上传失败:\n{{name}}\n{{message}}",
55
+ "error": "上传失败:\n{{name}}\n{{error}}"
56
+ },
57
+ "batch": {
58
+ "uploading": "正在上传文件...",
59
+ "success": "文件上传完成",
60
+ "error": "部分文件上传失败"
61
+ },
62
  "generalError": "上传失败\n{{error}}",
63
+ "fileTypes": "支持的文件类型:TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS",
64
+ "fileUploader": {
65
+ "singleFileLimit": "一次只能上传一个文件",
66
+ "maxFilesLimit": "最多只能上传 {{count}} 个文件",
67
+ "fileRejected": "文件 {{name}} 被拒绝",
68
+ "dropHere": "将文件拖放到此处",
69
+ "dragAndDrop": "拖放文件到此处,或点击选择文件",
70
+ "removeFile": "移除文件",
71
+ "uploadDescription": "您可以上传{{isMultiple ? '多个' : count}}个文件(每个文件最大{{maxSize}})"
72
+ }
73
  },
74
  "documentManager": {
75
  "title": "文档管理",