yangdx
commited on
Commit
·
53b0dc2
1
Parent(s):
109988a
Upload file in the order of sorted file name
Browse files
lightrag_webui/src/components/documents/UploadDocumentsDialog.tsx
CHANGED
@@ -77,69 +77,77 @@ export default function UploadDocumentsDialog({ onDocumentsUploaded }: UploadDoc
|
|
77 |
// Track errors locally to ensure we have the final state
|
78 |
const uploadErrors: Record<string, string> = {}
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
setProgresses((pre) => ({
|
85 |
...pre,
|
86 |
-
[file.name]:
|
87 |
}))
|
|
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
setProgresses((pre) => ({
|
92 |
-
...pre,
|
93 |
-
[file.name]: percentCompleted
|
94 |
-
}))
|
95 |
-
})
|
96 |
-
|
97 |
-
if (result.status === 'duplicated') {
|
98 |
-
uploadErrors[file.name] = t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
99 |
-
setFileErrors(prev => ({
|
100 |
-
...prev,
|
101 |
-
[file.name]: t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
102 |
-
}))
|
103 |
-
} else if (result.status !== 'success') {
|
104 |
-
uploadErrors[file.name] = result.message
|
105 |
-
setFileErrors(prev => ({
|
106 |
-
...prev,
|
107 |
-
[file.name]: result.message
|
108 |
-
}))
|
109 |
-
} else {
|
110 |
-
// Mark that we had at least one successful upload
|
111 |
-
hasSuccessfulUpload = true
|
112 |
-
}
|
113 |
-
} catch (err) {
|
114 |
-
console.error(`Upload failed for ${file.name}:`, err)
|
115 |
-
|
116 |
-
// Handle HTTP errors, including 400 errors
|
117 |
-
let errorMsg = errorMessage(err)
|
118 |
-
|
119 |
-
// If it's an axios error with response data, try to extract more detailed error info
|
120 |
-
if (err && typeof err === 'object' && 'response' in err) {
|
121 |
-
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
122 |
-
if (axiosError.response?.status === 400) {
|
123 |
-
// Extract specific error message from backend response
|
124 |
-
errorMsg = axiosError.response.data?.detail || errorMsg
|
125 |
-
}
|
126 |
-
|
127 |
-
// Set progress to 100% to display error message
|
128 |
-
setProgresses((pre) => ({
|
129 |
-
...pre,
|
130 |
-
[file.name]: 100
|
131 |
-
}))
|
132 |
-
}
|
133 |
-
|
134 |
-
// Record error message in both local tracking and state
|
135 |
-
uploadErrors[file.name] = errorMsg
|
136 |
setFileErrors(prev => ({
|
137 |
...prev,
|
138 |
-
[file.name]:
|
139 |
}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
-
})
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
|
144 |
// Check if any files failed to upload using our local tracking
|
145 |
const hasErrors = Object.keys(uploadErrors).length > 0
|
|
|
77 |
// Track errors locally to ensure we have the final state
|
78 |
const uploadErrors: Record<string, string> = {}
|
79 |
|
80 |
+
// Create a collator that supports Chinese sorting
|
81 |
+
const collator = new Intl.Collator(['zh-CN', 'en'], {
|
82 |
+
sensitivity: 'accent', // consider basic characters, accents, and case
|
83 |
+
numeric: true // enable numeric sorting, e.g., "File 10" will be after "File 2"
|
84 |
+
});
|
85 |
+
const sortedFiles = [...filesToUpload].sort((a, b) =>
|
86 |
+
collator.compare(a.name, b.name)
|
87 |
+
);
|
88 |
+
|
89 |
+
// Upload files in sequence, not parallel
|
90 |
+
for (const file of sortedFiles) {
|
91 |
+
try {
|
92 |
+
// Initialize upload progress
|
93 |
+
setProgresses((pre) => ({
|
94 |
+
...pre,
|
95 |
+
[file.name]: 0
|
96 |
+
}))
|
97 |
+
|
98 |
+
const result = await uploadDocument(file, (percentCompleted: number) => {
|
99 |
+
console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
|
100 |
setProgresses((pre) => ({
|
101 |
...pre,
|
102 |
+
[file.name]: percentCompleted
|
103 |
}))
|
104 |
+
})
|
105 |
|
106 |
+
if (result.status === 'duplicated') {
|
107 |
+
uploadErrors[file.name] = t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
setFileErrors(prev => ({
|
109 |
...prev,
|
110 |
+
[file.name]: t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
111 |
}))
|
112 |
+
} else if (result.status !== 'success') {
|
113 |
+
uploadErrors[file.name] = result.message
|
114 |
+
setFileErrors(prev => ({
|
115 |
+
...prev,
|
116 |
+
[file.name]: result.message
|
117 |
+
}))
|
118 |
+
} else {
|
119 |
+
// Mark that we had at least one successful upload
|
120 |
+
hasSuccessfulUpload = true
|
121 |
}
|
122 |
+
} catch (err) {
|
123 |
+
console.error(`Upload failed for ${file.name}:`, err)
|
124 |
+
|
125 |
+
// Handle HTTP errors, including 400 errors
|
126 |
+
let errorMsg = errorMessage(err)
|
127 |
+
|
128 |
+
// If it's an axios error with response data, try to extract more detailed error info
|
129 |
+
if (err && typeof err === 'object' && 'response' in err) {
|
130 |
+
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
131 |
+
if (axiosError.response?.status === 400) {
|
132 |
+
// Extract specific error message from backend response
|
133 |
+
errorMsg = axiosError.response.data?.detail || errorMsg
|
134 |
+
}
|
135 |
+
|
136 |
+
// Set progress to 100% to display error message
|
137 |
+
setProgresses((pre) => ({
|
138 |
+
...pre,
|
139 |
+
[file.name]: 100
|
140 |
+
}))
|
141 |
+
}
|
142 |
+
|
143 |
+
// Record error message in both local tracking and state
|
144 |
+
uploadErrors[file.name] = errorMsg
|
145 |
+
setFileErrors(prev => ({
|
146 |
+
...prev,
|
147 |
+
[file.name]: errorMsg
|
148 |
+
}))
|
149 |
+
}
|
150 |
+
}
|
151 |
|
152 |
// Check if any files failed to upload using our local tracking
|
153 |
const hasErrors = Object.keys(uploadErrors).length > 0
|