Skip to content

Commit

Permalink
fix: #567 use modal to upload files in the knowledge base (#601)
Browse files Browse the repository at this point in the history
### What problem does this PR solve?

fix:  #567 use modal to upload files in the knowledge base

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
  • Loading branch information
cike8899 committed Apr 29, 2024
1 parent 6874c6f commit 38f0cc0
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 20 deletions.
8 changes: 8 additions & 0 deletions web/src/components/file-upload-modal/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.uploader {
:global {
.ant-upload-list {
max-height: 40vh;
overflow-y: auto;
}
}
}
135 changes: 135 additions & 0 deletions web/src/components/file-upload-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useTranslate } from '@/hooks/commonHooks';
import { IModalProps } from '@/interfaces/common';
import { InboxOutlined } from '@ant-design/icons';
import {
Flex,
Modal,
Segmented,
Tabs,
TabsProps,
Upload,
UploadFile,
UploadProps,
} from 'antd';
import { Dispatch, SetStateAction, useState } from 'react';

import styles from './index.less';

const { Dragger } = Upload;

const FileUpload = ({
directory,
fileList,
setFileList,
}: {
directory: boolean;
fileList: UploadFile[];
setFileList: Dispatch<SetStateAction<UploadFile[]>>;
}) => {
const { t } = useTranslate('fileManager');
const props: UploadProps = {
multiple: true,
onRemove: (file) => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
setFileList(newFileList);
},
beforeUpload: (file) => {
setFileList((pre) => {
return [...pre, file];
});

return false;
},
directory,
fileList,
};

return (
<Dragger {...props} className={styles.uploader}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">{t('uploadTitle')}</p>
<p className="ant-upload-hint">{t('uploadDescription')}</p>
</Dragger>
);
};

const FileUploadModal = ({
visible,
hideModal,
loading,
onOk: onFileUploadOk,
}: IModalProps<UploadFile[]>) => {
const { t } = useTranslate('fileManager');
const [value, setValue] = useState<string | number>('local');
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [directoryFileList, setDirectoryFileList] = useState<UploadFile[]>([]);

const onOk = async () => {
const ret = await onFileUploadOk?.([...fileList, ...directoryFileList]);
if (ret !== undefined && ret === 0) {
setFileList([]);
setDirectoryFileList([]);
}
return ret;
};

const items: TabsProps['items'] = [
{
key: '1',
label: t('file'),
children: (
<FileUpload
directory={false}
fileList={fileList}
setFileList={setFileList}
></FileUpload>
),
},
{
key: '2',
label: t('directory'),
children: (
<FileUpload
directory
fileList={directoryFileList}
setFileList={setDirectoryFileList}
></FileUpload>
),
},
];

return (
<>
<Modal
title={t('uploadFile')}
open={visible}
onOk={onOk}
onCancel={hideModal}
confirmLoading={loading}
>
<Flex gap={'large'} vertical>
<Segmented
options={[
{ label: t('local'), value: 'local' },
{ label: t('s3'), value: 's3' },
]}
block
value={value}
onChange={setValue}
/>
{value === 'local' ? (
<Tabs defaultActiveKey="1" items={items} />
) : (
t('comingSoon', { keyPrefix: 'common' })
)}
</Flex>
</Modal>
</>
);
};

export default FileUploadModal;
4 changes: 2 additions & 2 deletions web/src/hooks/documentHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ export const useUploadDocument = () => {
const { knowledgeId } = useGetKnowledgeSearchParams();

const uploadDocument = useCallback(
(file: UploadFile) => {
(fileList: UploadFile[]) => {
try {
return dispatch<any>({
type: 'kFModel/upload_document',
payload: {
file,
fileList,
kb_id: knowledgeId,
},
});
Expand Down
14 changes: 7 additions & 7 deletions web/src/hooks/llmHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IThirdOAIModelCollection,
} from '@/interfaces/database/llm';
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { sortLLmFactoryListBySpecifiedOrder } from '@/utils/commonUtil';
import { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'umi';

Expand Down Expand Up @@ -110,13 +111,12 @@ export const useFetchLlmFactoryListOnMount = () => {
const factoryList = useSelectLlmFactoryList();
const myLlmList = useSelectMyLlmList();

const list = useMemo(
() =>
factoryList.filter((x) =>
Object.keys(myLlmList).every((y) => y !== x.name),
),
[factoryList, myLlmList],
);
const list = useMemo(() => {
const currentList = factoryList.filter((x) =>
Object.keys(myLlmList).every((y) => y !== x.name),
);
return sortLLmFactoryListBySpecifiedOrder(currentList);
}, [factoryList, myLlmList]);

const fetchLlmFactoryList = useCallback(() => {
dispatch({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ import styles from './index.less';
interface IProps {
selectedRowKeys: string[];
showCreateModal(): void;
showDocumentUploadModal(): void;
}

const DocumentToolbar = ({ selectedRowKeys, showCreateModal }: IProps) => {
const DocumentToolbar = ({
selectedRowKeys,
showCreateModal,
showDocumentUploadModal,
}: IProps) => {
const { t } = useTranslate('knowledgeDetails');
const { fetchDocumentList } = useFetchDocumentListOnMount();
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
Expand All @@ -48,7 +53,7 @@ const DocumentToolbar = ({ selectedRowKeys, showCreateModal }: IProps) => {
return [
{
key: '1',
onClick: linkToUploadPage,
onClick: showDocumentUploadModal,
label: (
<div>
<Button type="link">
Expand All @@ -75,7 +80,7 @@ const DocumentToolbar = ({ selectedRowKeys, showCreateModal }: IProps) => {
// disabled: true,
},
];
}, [linkToUploadPage, showCreateModal, t]);
}, [showDocumentUploadModal, showCreateModal, t]);

const handleDelete = useCallback(() => {
showDeleteConfirm({
Expand Down
43 changes: 42 additions & 1 deletion web/src/pages/add-knowledge/components/knowledge-file/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {
useFetchDocumentList,
useSaveDocumentName,
useSetDocumentParser,
useUploadDocument,
} from '@/hooks/documentHooks';
import { useGetKnowledgeSearchParams } from '@/hooks/routeHook';
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
import { useFetchTenantInfo } from '@/hooks/userSettingHook';
import { Pagination } from '@/interfaces/common';
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
import { PaginationProps } from 'antd';
import { getUnSupportedFilesCount } from '@/utils/documentUtils';
import { PaginationProps, UploadFile } from 'antd';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useNavigate, useSelector } from 'umi';
import { KnowledgeRouteKey } from './constant';
Expand Down Expand Up @@ -242,3 +244,42 @@ export const useGetRowSelection = () => {

return rowSelection;
};

export const useHandleUploadDocument = () => {
const {
visible: documentUploadVisible,
hideModal: hideDocumentUploadModal,
showModal: showDocumentUploadModal,
} = useSetModalState();
const uploadDocument = useUploadDocument();

const onDocumentUploadOk = useCallback(
async (fileList: UploadFile[]): Promise<number | undefined> => {
if (fileList.length > 0) {
const ret: any = await uploadDocument(fileList);
const count = getUnSupportedFilesCount(ret.retmsg);
/// 500 error code indicates that some file types are not supported
let retcode = ret.retcode;
if (
ret.retcode === 0 ||
(ret.retcode === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
) {
retcode = 0;
hideDocumentUploadModal();
}
return retcode;
}
},
[uploadDocument, hideDocumentUploadModal],
);

const loading = useOneNamespaceEffectsLoading('kFModel', ['upload_document']);

return {
documentUploadLoading: loading,
onDocumentUploadOk,
documentUploadVisible,
hideDocumentUploadModal,
showDocumentUploadModal,
};
};
16 changes: 16 additions & 0 deletions web/src/pages/add-knowledge/components/knowledge-file/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import {
useFetchDocumentListOnMount,
useGetPagination,
useGetRowSelection,
useHandleUploadDocument,
useNavigateToOtherPage,
useRenameDocument,
} from './hooks';
import ParsingActionCell from './parsing-action-cell';
import ParsingStatusCell from './parsing-status-cell';
import RenameModal from './rename-modal';

import FileUploadModal from '@/components/file-upload-modal';
import { formatDate } from '@/utils/date';
import styles from './index.less';

Expand Down Expand Up @@ -58,6 +60,13 @@ const KnowledgeFile = () => {
hideChangeParserModal,
showChangeParserModal,
} = useChangeDocumentParser(currentRecord.id);
const {
documentUploadVisible,
hideDocumentUploadModal,
showDocumentUploadModal,
onDocumentUploadOk,
documentUploadLoading,
} = useHandleUploadDocument();
const { t } = useTranslation('translation', {
keyPrefix: 'knowledgeDetails',
});
Expand Down Expand Up @@ -157,6 +166,7 @@ const KnowledgeFile = () => {
<DocumentToolbar
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
showCreateModal={showCreateModal}
showDocumentUploadModal={showDocumentUploadModal}
></DocumentToolbar>
<Table
rowKey="id"
Expand Down Expand Up @@ -190,6 +200,12 @@ const KnowledgeFile = () => {
hideModal={hideRenameModal}
initialName={currentRecord.name}
></RenameModal>
<FileUploadModal
visible={documentUploadVisible}
hideModal={hideDocumentUploadModal}
loading={documentUploadLoading}
onOk={onDocumentUploadOk}
></FileUploadModal>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,15 @@ const model: DvaModel<KFModelState> = {
}
},
*upload_document({ payload = {} }, { call, put }) {
const fileList = payload.fileList;
const formData = new FormData();
formData.append('file', payload.file);
formData.append('kb_id', payload.kb_id);
fileList.forEach((file: any) => {
formData.append('file', file);
});

const { data } = yield call(kbService.document_upload, formData);
if (data.retcode === 0) {
if (data.retcode === 0 || data.retcode === 500) {
yield put({
type: 'getKfList',
payload: { kb_id: payload.kb_id },
Expand Down
2 changes: 0 additions & 2 deletions web/src/pages/file-manager/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ const model: DvaModel<FileManagerModelState> = {
const pathList = payload.path;
const formData = new FormData();
formData.append('parent_id', payload.parentId);
// formData.append('file', payload.file);
// formData.append('path', payload.path);
fileList.forEach((file: any, index: number) => {
formData.append('file', file);
formData.append('path', pathList[index]);
Expand Down
4 changes: 4 additions & 0 deletions web/src/pages/user-setting/setting-model/index.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.modelWrapper {
width: 100%;
}

.modelContainer {
width: 100%;
.factoryOperationWrapper {
text-align: right;
}
Expand Down
6 changes: 3 additions & 3 deletions web/src/pages/user-setting/setting-model/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ const UserSettingModel = () => {
];

return (
<>
<section id="xx" className={styles.modelWrapper}>
<Spin spinning={loading}>
<section className={styles.modelWrapper}>
<section className={styles.modelContainer}>
<SettingTitle
title={t('model')}
description={t('modelDescription')}
Expand Down Expand Up @@ -257,7 +257,7 @@ const UserSettingModel = () => {
loading={llmAddingLoading}
llmFactory={selectedLlmFactory}
></OllamaModal>
</>
</section>
);
};

Expand Down
Loading

0 comments on commit 38f0cc0

Please sign in to comment.