yangdx
commited on
Commit
·
9426437
1
Parent(s):
ae64c4f
Fix linting
Browse files
lightrag/api/routers/document_routes.py
CHANGED
@@ -559,7 +559,7 @@ def create_document_routes(
|
|
559 |
if file_path.exists():
|
560 |
return InsertResponse(
|
561 |
status="duplicated",
|
562 |
-
message=f"File '{file.filename}' already exists in the input directory."
|
563 |
)
|
564 |
|
565 |
with open(file_path, "wb") as buffer:
|
|
|
559 |
if file_path.exists():
|
560 |
return InsertResponse(
|
561 |
status="duplicated",
|
562 |
+
message=f"File '{file.filename}' already exists in the input directory.",
|
563 |
)
|
564 |
|
565 |
with open(file_path, "wb") as buffer:
|
lightrag_webui/src/components/documents/UploadDocumentsDialog.tsx
CHANGED
@@ -30,18 +30,18 @@ export default function UploadDocumentsDialog() {
|
|
30 |
rejectedFiles.forEach(({ file, errors }) => {
|
31 |
// Get the first error message
|
32 |
let errorMsg = errors[0]?.message || t('documentPanel.uploadDocuments.fileUploader.fileRejected', { name: file.name })
|
33 |
-
|
34 |
// Simplify error message for unsupported file types
|
35 |
if (errorMsg.includes('file-invalid-type')) {
|
36 |
errorMsg = t('documentPanel.uploadDocuments.fileUploader.unsupportedType')
|
37 |
}
|
38 |
-
|
39 |
// Set progress to 100% to display error message
|
40 |
setProgresses((pre) => ({
|
41 |
...pre,
|
42 |
[file.name]: 100
|
43 |
}))
|
44 |
-
|
45 |
// Add error message to fileErrors
|
46 |
setFileErrors(prev => ({
|
47 |
...prev,
|
@@ -55,7 +55,7 @@ export default function UploadDocumentsDialog() {
|
|
55 |
const handleDocumentsUpload = useCallback(
|
56 |
async (filesToUpload: File[]) => {
|
57 |
setIsUploading(true)
|
58 |
-
|
59 |
// Only clear errors for files that are being uploaded, keep errors for rejected files
|
60 |
setFileErrors(prev => {
|
61 |
const newErrors = { ...prev };
|
@@ -64,14 +64,14 @@ export default function UploadDocumentsDialog() {
|
|
64 |
});
|
65 |
return newErrors;
|
66 |
});
|
67 |
-
|
68 |
// Show uploading toast
|
69 |
const toastId = toast.loading(t('documentPanel.uploadDocuments.batch.uploading'))
|
70 |
-
|
71 |
try {
|
72 |
// Track errors locally to ensure we have the final state
|
73 |
const uploadErrors: Record<string, string> = {}
|
74 |
-
|
75 |
await Promise.all(
|
76 |
filesToUpload.map(async (file) => {
|
77 |
try {
|
@@ -80,7 +80,7 @@ export default function UploadDocumentsDialog() {
|
|
80 |
...pre,
|
81 |
[file.name]: 0
|
82 |
}))
|
83 |
-
|
84 |
const result = await uploadDocument(file, (percentCompleted: number) => {
|
85 |
console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
|
86 |
setProgresses((pre) => ({
|
@@ -104,10 +104,10 @@ export default function UploadDocumentsDialog() {
|
|
104 |
}
|
105 |
} catch (err) {
|
106 |
console.error(`Upload failed for ${file.name}:`, err)
|
107 |
-
|
108 |
// Handle HTTP errors, including 400 errors
|
109 |
let errorMsg = errorMessage(err)
|
110 |
-
|
111 |
// If it's an axios error with response data, try to extract more detailed error info
|
112 |
if (err && typeof err === 'object' && 'response' in err) {
|
113 |
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
@@ -115,14 +115,14 @@ export default function UploadDocumentsDialog() {
|
|
115 |
// Extract specific error message from backend response
|
116 |
errorMsg = axiosError.response.data?.detail || errorMsg
|
117 |
}
|
118 |
-
|
119 |
// Set progress to 100% to display error message
|
120 |
setProgresses((pre) => ({
|
121 |
...pre,
|
122 |
[file.name]: 100
|
123 |
}))
|
124 |
}
|
125 |
-
|
126 |
// Record error message in both local tracking and state
|
127 |
uploadErrors[file.name] = errorMsg
|
128 |
setFileErrors(prev => ({
|
@@ -132,10 +132,10 @@ export default function UploadDocumentsDialog() {
|
|
132 |
}
|
133 |
})
|
134 |
)
|
135 |
-
|
136 |
// Check if any files failed to upload using our local tracking
|
137 |
const hasErrors = Object.keys(uploadErrors).length > 0
|
138 |
-
|
139 |
// Update toast status
|
140 |
if (hasErrors) {
|
141 |
toast.error(t('documentPanel.uploadDocuments.batch.error'), { id: toastId })
|
|
|
30 |
rejectedFiles.forEach(({ file, errors }) => {
|
31 |
// Get the first error message
|
32 |
let errorMsg = errors[0]?.message || t('documentPanel.uploadDocuments.fileUploader.fileRejected', { name: file.name })
|
33 |
+
|
34 |
// Simplify error message for unsupported file types
|
35 |
if (errorMsg.includes('file-invalid-type')) {
|
36 |
errorMsg = t('documentPanel.uploadDocuments.fileUploader.unsupportedType')
|
37 |
}
|
38 |
+
|
39 |
// Set progress to 100% to display error message
|
40 |
setProgresses((pre) => ({
|
41 |
...pre,
|
42 |
[file.name]: 100
|
43 |
}))
|
44 |
+
|
45 |
// Add error message to fileErrors
|
46 |
setFileErrors(prev => ({
|
47 |
...prev,
|
|
|
55 |
const handleDocumentsUpload = useCallback(
|
56 |
async (filesToUpload: File[]) => {
|
57 |
setIsUploading(true)
|
58 |
+
|
59 |
// Only clear errors for files that are being uploaded, keep errors for rejected files
|
60 |
setFileErrors(prev => {
|
61 |
const newErrors = { ...prev };
|
|
|
64 |
});
|
65 |
return newErrors;
|
66 |
});
|
67 |
+
|
68 |
// Show uploading toast
|
69 |
const toastId = toast.loading(t('documentPanel.uploadDocuments.batch.uploading'))
|
70 |
+
|
71 |
try {
|
72 |
// Track errors locally to ensure we have the final state
|
73 |
const uploadErrors: Record<string, string> = {}
|
74 |
+
|
75 |
await Promise.all(
|
76 |
filesToUpload.map(async (file) => {
|
77 |
try {
|
|
|
80 |
...pre,
|
81 |
[file.name]: 0
|
82 |
}))
|
83 |
+
|
84 |
const result = await uploadDocument(file, (percentCompleted: number) => {
|
85 |
console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
|
86 |
setProgresses((pre) => ({
|
|
|
104 |
}
|
105 |
} catch (err) {
|
106 |
console.error(`Upload failed for ${file.name}:`, err)
|
107 |
+
|
108 |
// Handle HTTP errors, including 400 errors
|
109 |
let errorMsg = errorMessage(err)
|
110 |
+
|
111 |
// If it's an axios error with response data, try to extract more detailed error info
|
112 |
if (err && typeof err === 'object' && 'response' in err) {
|
113 |
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
|
|
115 |
// Extract specific error message from backend response
|
116 |
errorMsg = axiosError.response.data?.detail || errorMsg
|
117 |
}
|
118 |
+
|
119 |
// Set progress to 100% to display error message
|
120 |
setProgresses((pre) => ({
|
121 |
...pre,
|
122 |
[file.name]: 100
|
123 |
}))
|
124 |
}
|
125 |
+
|
126 |
// Record error message in both local tracking and state
|
127 |
uploadErrors[file.name] = errorMsg
|
128 |
setFileErrors(prev => ({
|
|
|
132 |
}
|
133 |
})
|
134 |
)
|
135 |
+
|
136 |
// Check if any files failed to upload using our local tracking
|
137 |
const hasErrors = Object.keys(uploadErrors).length > 0
|
138 |
+
|
139 |
// Update toast status
|
140 |
if (hasErrors) {
|
141 |
toast.error(t('documentPanel.uploadDocuments.batch.error'), { id: toastId })
|
lightrag_webui/src/components/ui/FileUploader.tsx
CHANGED
@@ -155,7 +155,7 @@ function FileUploader(props: FileUploaderProps) {
|
|
155 |
(acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
|
156 |
// Calculate total file count including both accepted and rejected files
|
157 |
const totalFileCount = (files?.length ?? 0) + acceptedFiles.length + rejectedFiles.length
|
158 |
-
|
159 |
// Check file count limits
|
160 |
if (!multiple && maxFileCount === 1 && (acceptedFiles.length + rejectedFiles.length) > 1) {
|
161 |
toast.error(t('documentPanel.uploadDocuments.fileUploader.singleFileLimit'))
|
@@ -186,19 +186,19 @@ function FileUploader(props: FileUploaderProps) {
|
|
186 |
preview: URL.createObjectURL(file)
|
187 |
})
|
188 |
)
|
189 |
-
|
190 |
// Process rejected files for UI display
|
191 |
-
const newRejectedFiles = rejectedFiles.map(({ file }) =>
|
192 |
Object.assign(file, {
|
193 |
preview: URL.createObjectURL(file),
|
194 |
rejected: true
|
195 |
})
|
196 |
)
|
197 |
-
|
198 |
// Combine all files for display
|
199 |
const allNewFiles = [...newAcceptedFiles, ...newRejectedFiles]
|
200 |
const updatedFiles = files ? [...files, ...allNewFiles] : allNewFiles
|
201 |
-
|
202 |
// Update the files state with all files
|
203 |
setFiles(updatedFiles)
|
204 |
|
@@ -211,13 +211,13 @@ function FileUploader(props: FileUploaderProps) {
|
|
211 |
const isAccepted = Object.entries(accept || {}).some(([mimeType, extensions]) => {
|
212 |
return file.type === mimeType || extensions.includes(fileExt);
|
213 |
});
|
214 |
-
|
215 |
// Check file size
|
216 |
const isSizeValid = file.size <= maxSize;
|
217 |
-
|
218 |
return isAccepted && isSizeValid;
|
219 |
});
|
220 |
-
|
221 |
if (validFiles.length > 0) {
|
222 |
onUpload(validFiles);
|
223 |
}
|
@@ -265,24 +265,24 @@ function FileUploader(props: FileUploaderProps) {
|
|
265 |
const isAccepted = Object.entries(accept || {}).some(([mimeType, extensions]) => {
|
266 |
return file.type === mimeType || extensions.includes(fileExt);
|
267 |
});
|
268 |
-
|
269 |
if (!isAccepted) {
|
270 |
return {
|
271 |
code: 'file-invalid-type',
|
272 |
message: t('documentPanel.uploadDocuments.fileUploader.unsupportedType')
|
273 |
};
|
274 |
}
|
275 |
-
|
276 |
// Check file size
|
277 |
if (file.size > maxSize) {
|
278 |
return {
|
279 |
code: 'file-too-large',
|
280 |
-
message: t('documentPanel.uploadDocuments.fileUploader.fileTooLarge', {
|
281 |
-
maxSize: formatBytes(maxSize)
|
282 |
})
|
283 |
};
|
284 |
}
|
285 |
-
|
286 |
return null;
|
287 |
}}
|
288 |
>
|
|
|
155 |
(acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
|
156 |
// Calculate total file count including both accepted and rejected files
|
157 |
const totalFileCount = (files?.length ?? 0) + acceptedFiles.length + rejectedFiles.length
|
158 |
+
|
159 |
// Check file count limits
|
160 |
if (!multiple && maxFileCount === 1 && (acceptedFiles.length + rejectedFiles.length) > 1) {
|
161 |
toast.error(t('documentPanel.uploadDocuments.fileUploader.singleFileLimit'))
|
|
|
186 |
preview: URL.createObjectURL(file)
|
187 |
})
|
188 |
)
|
189 |
+
|
190 |
// Process rejected files for UI display
|
191 |
+
const newRejectedFiles = rejectedFiles.map(({ file }) =>
|
192 |
Object.assign(file, {
|
193 |
preview: URL.createObjectURL(file),
|
194 |
rejected: true
|
195 |
})
|
196 |
)
|
197 |
+
|
198 |
// Combine all files for display
|
199 |
const allNewFiles = [...newAcceptedFiles, ...newRejectedFiles]
|
200 |
const updatedFiles = files ? [...files, ...allNewFiles] : allNewFiles
|
201 |
+
|
202 |
// Update the files state with all files
|
203 |
setFiles(updatedFiles)
|
204 |
|
|
|
211 |
const isAccepted = Object.entries(accept || {}).some(([mimeType, extensions]) => {
|
212 |
return file.type === mimeType || extensions.includes(fileExt);
|
213 |
});
|
214 |
+
|
215 |
// Check file size
|
216 |
const isSizeValid = file.size <= maxSize;
|
217 |
+
|
218 |
return isAccepted && isSizeValid;
|
219 |
});
|
220 |
+
|
221 |
if (validFiles.length > 0) {
|
222 |
onUpload(validFiles);
|
223 |
}
|
|
|
265 |
const isAccepted = Object.entries(accept || {}).some(([mimeType, extensions]) => {
|
266 |
return file.type === mimeType || extensions.includes(fileExt);
|
267 |
});
|
268 |
+
|
269 |
if (!isAccepted) {
|
270 |
return {
|
271 |
code: 'file-invalid-type',
|
272 |
message: t('documentPanel.uploadDocuments.fileUploader.unsupportedType')
|
273 |
};
|
274 |
}
|
275 |
+
|
276 |
// Check file size
|
277 |
if (file.size > maxSize) {
|
278 |
return {
|
279 |
code: 'file-too-large',
|
280 |
+
message: t('documentPanel.uploadDocuments.fileUploader.fileTooLarge', {
|
281 |
+
maxSize: formatBytes(maxSize)
|
282 |
})
|
283 |
};
|
284 |
}
|
285 |
+
|
286 |
return null;
|
287 |
}}
|
288 |
>
|