Feat: Upload file UI/UX enhancements (#5359)

### What problem does this PR solve?

Modifies the UX for uploading process on the website.

- Adds option to parse on creation the files
- Adds progress bar to display progress of chunk
- Adds per file feedback on uploading operation

#### Screenshots:

- Show files uploading:

![image](https://github.com/user-attachments/assets/a5693f42-8232-4d5c-a240-20ed343634a5)

- Errors on specific files

![image](https://github.com/user-attachments/assets/986a7f54-ab32-4634-89ab-a098fe1954aa)


### Type of change

- [X] New Feature (non-breaking change which adds functionality)
This commit is contained in:
Omar Leonardo Sanchez Granados
2025-03-05 02:20:32 -05:00
committed by GitHub
parent f65c3ae62b
commit 11e3f5e8b2
13 changed files with 189 additions and 92 deletions

View File

@ -10,7 +10,6 @@ import {
} from '@/hooks/document-hooks';
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
import { getUnSupportedFilesCount } from '@/utils/document-util';
import { UploadFile } from 'antd';
import { useCallback, useState } from 'react';
import { useNavigate } from 'umi';
@ -143,29 +142,103 @@ export const useHandleUploadDocument = () => {
hideModal: hideDocumentUploadModal,
showModal: showDocumentUploadModal,
} = useSetModalState();
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [uploadProgress, setUploadProgress] = useState<number>(0);
const { uploadDocument, loading } = useUploadNextDocument();
const { runDocumentByIds, loading: _ } = useRunNextDocument();
const onDocumentUploadOk = useCallback(
async (fileList: UploadFile[]): Promise<number | undefined> => {
if (fileList.length > 0) {
const ret: any = await uploadDocument(fileList);
if (typeof ret?.message !== 'string') {
return;
}
const count = getUnSupportedFilesCount(ret?.message);
/// 500 error code indicates that some file types are not supported
let code = ret?.code;
if (
ret?.code === 0 ||
(ret?.code === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
) {
code = 0;
hideDocumentUploadModal();
}
return code;
async (parseOnCreation: boolean): Promise<number | undefined> => {
const processFileGroup = async (filesPart: UploadFile[]) => {
// set status to uploading on files
setFileList(
fileList.map((file) => {
if (!filesPart.includes(file)) {
return file;
}
let newFile = file;
newFile.status = 'uploading';
newFile.percent = 1;
return newFile;
}),
);
const ret = await uploadDocument(filesPart);
const files = ret?.data || [];
const succesfulFilenames = files.map((file: any) => file.name);
// set status to done or error on files (based on response)
setFileList(
fileList.map((file) => {
if (!filesPart.includes(file)) {
return file;
}
let newFile = file;
newFile.status = succesfulFilenames.includes(file.name)
? 'done'
: 'error';
newFile.percent = 100;
newFile.response = ret.message;
return newFile;
}),
);
return {
code: ret?.code,
fileIds: files.map((file: any) => file.id),
totalSuccess: succesfulFilenames.length,
};
};
const totalFiles = fileList.length;
if (totalFiles === 0) {
console.log('No files to upload');
hideDocumentUploadModal();
return 0;
}
let totalSuccess = 0;
let codes = [];
let toRunFileIds: any[] = [];
for (let i = 0; i < totalFiles; i += 10) {
setUploadProgress(Math.floor((i / totalFiles) * 100));
const files = fileList.slice(i, i + 10);
const {
code,
totalSuccess: count,
fileIds,
} = await processFileGroup(files);
codes.push(code);
totalSuccess += count;
toRunFileIds = toRunFileIds.concat(fileIds);
}
const allSuccess = codes.every((code) => code === 0);
const any500 = codes.some((code) => code === 500);
let code = 500;
if (allSuccess || (any500 && totalSuccess === totalFiles)) {
code = 0;
hideDocumentUploadModal();
}
if (parseOnCreation) {
await runDocumentByIds({
documentIds: toRunFileIds,
run: 1,
shouldDelete: false,
});
}
setUploadProgress(100);
return code;
},
[uploadDocument, hideDocumentUploadModal],
[uploadDocument, hideDocumentUploadModal, fileList],
);
return {
@ -174,6 +247,10 @@ export const useHandleUploadDocument = () => {
documentUploadVisible,
hideDocumentUploadModal,
showDocumentUploadModal,
uploadFileList: fileList,
setUploadFileList: setFileList,
uploadProgress,
setUploadProgress,
};
};

View File

@ -69,6 +69,10 @@ const KnowledgeFile = () => {
showDocumentUploadModal,
onDocumentUploadOk,
documentUploadLoading,
uploadFileList,
setUploadFileList,
uploadProgress,
setUploadProgress,
} = useHandleUploadDocument();
const {
webCrawlUploadVisible,
@ -229,6 +233,10 @@ const KnowledgeFile = () => {
hideModal={hideDocumentUploadModal}
loading={documentUploadLoading}
onOk={onDocumentUploadOk}
uploadFileList={uploadFileList}
setUploadFileList={setUploadFileList}
uploadProgress={uploadProgress}
setUploadProgress={setUploadProgress}
></FileUploadModal>
<WebCrawlModal
visible={webCrawlUploadVisible}