Upload file in the order of sorted file name
This commit is contained in:
@@ -77,69 +77,77 @@ export default function UploadDocumentsDialog({ onDocumentsUploaded }: UploadDoc
|
|||||||
// Track errors locally to ensure we have the final state
|
// Track errors locally to ensure we have the final state
|
||||||
const uploadErrors: Record<string, string> = {}
|
const uploadErrors: Record<string, string> = {}
|
||||||
|
|
||||||
await Promise.all(
|
// Create a collator that supports Chinese sorting
|
||||||
filesToUpload.map(async (file) => {
|
const collator = new Intl.Collator(['zh-CN', 'en'], {
|
||||||
try {
|
sensitivity: 'accent', // consider basic characters, accents, and case
|
||||||
// Initialize upload progress
|
numeric: true // enable numeric sorting, e.g., "File 10" will be after "File 2"
|
||||||
|
});
|
||||||
|
const sortedFiles = [...filesToUpload].sort((a, b) =>
|
||||||
|
collator.compare(a.name, b.name)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Upload files in sequence, not parallel
|
||||||
|
for (const file of sortedFiles) {
|
||||||
|
try {
|
||||||
|
// Initialize upload progress
|
||||||
|
setProgresses((pre) => ({
|
||||||
|
...pre,
|
||||||
|
[file.name]: 0
|
||||||
|
}))
|
||||||
|
|
||||||
|
const result = await uploadDocument(file, (percentCompleted: number) => {
|
||||||
|
console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
|
||||||
setProgresses((pre) => ({
|
setProgresses((pre) => ({
|
||||||
...pre,
|
...pre,
|
||||||
[file.name]: 0
|
[file.name]: percentCompleted
|
||||||
}))
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
const result = await uploadDocument(file, (percentCompleted: number) => {
|
if (result.status === 'duplicated') {
|
||||||
console.debug(t('documentPanel.uploadDocuments.single.uploading', { name: file.name, percent: percentCompleted }))
|
uploadErrors[file.name] = t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
||||||
setProgresses((pre) => ({
|
|
||||||
...pre,
|
|
||||||
[file.name]: percentCompleted
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result.status === 'duplicated') {
|
|
||||||
uploadErrors[file.name] = t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
|
||||||
setFileErrors(prev => ({
|
|
||||||
...prev,
|
|
||||||
[file.name]: t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
|
||||||
}))
|
|
||||||
} else if (result.status !== 'success') {
|
|
||||||
uploadErrors[file.name] = result.message
|
|
||||||
setFileErrors(prev => ({
|
|
||||||
...prev,
|
|
||||||
[file.name]: result.message
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
// Mark that we had at least one successful upload
|
|
||||||
hasSuccessfulUpload = true
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Upload failed for ${file.name}:`, err)
|
|
||||||
|
|
||||||
// Handle HTTP errors, including 400 errors
|
|
||||||
let errorMsg = errorMessage(err)
|
|
||||||
|
|
||||||
// If it's an axios error with response data, try to extract more detailed error info
|
|
||||||
if (err && typeof err === 'object' && 'response' in err) {
|
|
||||||
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
|
||||||
if (axiosError.response?.status === 400) {
|
|
||||||
// Extract specific error message from backend response
|
|
||||||
errorMsg = axiosError.response.data?.detail || errorMsg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set progress to 100% to display error message
|
|
||||||
setProgresses((pre) => ({
|
|
||||||
...pre,
|
|
||||||
[file.name]: 100
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record error message in both local tracking and state
|
|
||||||
uploadErrors[file.name] = errorMsg
|
|
||||||
setFileErrors(prev => ({
|
setFileErrors(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
[file.name]: errorMsg
|
[file.name]: t('documentPanel.uploadDocuments.fileUploader.duplicateFile')
|
||||||
|
}))
|
||||||
|
} else if (result.status !== 'success') {
|
||||||
|
uploadErrors[file.name] = result.message
|
||||||
|
setFileErrors(prev => ({
|
||||||
|
...prev,
|
||||||
|
[file.name]: result.message
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
// Mark that we had at least one successful upload
|
||||||
|
hasSuccessfulUpload = true
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Upload failed for ${file.name}:`, err)
|
||||||
|
|
||||||
|
// Handle HTTP errors, including 400 errors
|
||||||
|
let errorMsg = errorMessage(err)
|
||||||
|
|
||||||
|
// If it's an axios error with response data, try to extract more detailed error info
|
||||||
|
if (err && typeof err === 'object' && 'response' in err) {
|
||||||
|
const axiosError = err as { response?: { status: number, data?: { detail?: string } } }
|
||||||
|
if (axiosError.response?.status === 400) {
|
||||||
|
// Extract specific error message from backend response
|
||||||
|
errorMsg = axiosError.response.data?.detail || errorMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set progress to 100% to display error message
|
||||||
|
setProgresses((pre) => ({
|
||||||
|
...pre,
|
||||||
|
[file.name]: 100
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
})
|
|
||||||
)
|
// Record error message in both local tracking and state
|
||||||
|
uploadErrors[file.name] = errorMsg
|
||||||
|
setFileErrors(prev => ({
|
||||||
|
...prev,
|
||||||
|
[file.name]: errorMsg
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if any files failed to upload using our local tracking
|
// Check if any files failed to upload using our local tracking
|
||||||
const hasErrors = Object.keys(uploadErrors).length > 0
|
const hasErrors = Object.keys(uploadErrors).length > 0
|
||||||
|
Reference in New Issue
Block a user