feat: add hooks for document table and refactor document-related modal (#141)

* feat: add hooks for document table

* refactor: refactor document-related modal
This commit is contained in:
balibabu 2024-03-22 11:35:25 +08:00 committed by GitHub
parent 6c6b144de2
commit 73c2f4d418
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 625 additions and 401 deletions

View File

@ -1,8 +1,10 @@
import { IChunk } from '@/interfaces/database/knowledge';
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
import { api_host } from '@/utils/api';
import { buildChunkHighlights } from '@/utils/documentUtils';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { IHighlight } from 'react-pdf-highlighter';
import { useDispatch, useSelector } from 'umi';
import { useGetKnowledgeSearchParams } from './routeHook';
export const useGetDocumentUrl = (documentId: string) => {
const url = useMemo(() => {
@ -19,3 +21,139 @@ export const useGetChunkHighlights = (selectedChunk: IChunk): IHighlight[] => {
return highlights;
};
export const useFetchDocumentList = () => {
const { knowledgeId } = useGetKnowledgeSearchParams();
const dispatch = useDispatch();
const fetchKfList = useCallback(() => {
return dispatch<any>({
type: 'kFModel/getKfList',
payload: {
kb_id: knowledgeId,
},
});
}, [dispatch, knowledgeId]);
return fetchKfList;
};
export const useSetDocumentStatus = () => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const setDocumentStatus = useCallback(
(status: boolean, documentId: string) => {
dispatch({
type: 'kFModel/updateDocumentStatus',
payload: {
doc_id: documentId,
status: Number(status),
kb_id: knowledgeId,
},
});
},
[dispatch, knowledgeId],
);
return setDocumentStatus;
};
export const useSelectDocumentList = () => {
const list: IKnowledgeFile[] = useSelector(
(state: any) => state.kFModel.data,
);
return list;
};
export const useSaveDocumentName = () => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const saveName = useCallback(
(documentId: string, name: string) => {
return dispatch<any>({
type: 'kFModel/document_rename',
payload: {
doc_id: documentId,
name: name,
kb_id: knowledgeId,
},
});
},
[dispatch, knowledgeId],
);
return saveName;
};
export const useCreateDocument = () => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const createDocument = useCallback(
(name: string) => {
try {
return dispatch<any>({
type: 'kFModel/document_create',
payload: {
name,
kb_id: knowledgeId,
},
});
} catch (errorInfo) {
console.log('Failed:', errorInfo);
}
},
[dispatch, knowledgeId],
);
return createDocument;
};
export const useSetDocumentParser = () => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const setDocumentParser = useCallback(
(parserId: string, documentId: string) => {
try {
return dispatch<any>({
type: 'kFModel/document_change_parser',
payload: {
parser_id: parserId,
doc_id: documentId,
kb_id: knowledgeId,
},
});
} catch (errorInfo) {
console.log('Failed:', errorInfo);
}
},
[dispatch, knowledgeId],
);
return setDocumentParser;
};
export const useRemoveDocument = (documentId: string) => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const removeDocument = useCallback(() => {
try {
return dispatch<any>({
type: 'kFModel/document_rm',
payload: {
doc_id: documentId,
kb_id: knowledgeId,
},
});
} catch (errorInfo) {
console.log('Failed:', errorInfo);
}
}, [dispatch, knowledgeId, documentId]);
return removeDocument;
};

View File

@ -1,86 +1,69 @@
import {
useFetchTenantInfo,
useSelectParserList,
} from '@/hooks/userSettingHook';
import { Modal, Space, Tag } from 'antd';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'umi';
import styles from './index.less';
const { CheckableTag } = Tag;
interface kFProps {
getKfList: () => void;
parser_id: string;
doc_id: string;
}
const SegmentSetModal: React.FC<kFProps> = ({
getKfList,
parser_id,
doc_id,
}) => {
const dispatch = useDispatch();
const kFModel = useSelector((state: any) => state.kFModel);
const [selectedTag, setSelectedTag] = useState('');
const { isShowSegmentSetModal } = kFModel;
const parserList = useSelectParserList();
useFetchTenantInfo();
useEffect(() => {
setSelectedTag(parser_id);
}, [parser_id]);
const handleCancel = () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowSegmentSetModal: false,
},
});
};
const handleOk = async () => {
const retcode = await dispatch<any>({
type: 'kFModel/document_change_parser',
payload: {
parser_id: selectedTag,
doc_id,
},
});
if (retcode === 0 && getKfList) {
getKfList();
handleCancel();
}
};
const handleChange = (tag: string, checked: boolean) => {
const nextSelectedTag = checked ? tag : selectedTag;
setSelectedTag(nextSelectedTag);
};
return (
<Modal
title="Category"
open={isShowSegmentSetModal}
onOk={handleOk}
onCancel={handleCancel}
>
<Space size={[0, 8]} wrap>
<div className={styles.tags}>
{parserList.map((x) => {
return (
<CheckableTag
key={x.value}
checked={selectedTag === x.value}
onChange={(checked) => handleChange(x.value, checked)}
>
{x.label}
</CheckableTag>
);
})}
</div>
</Space>
</Modal>
);
};
export default SegmentSetModal;
import { IModalManagerChildrenProps } from '@/components/modal-manager';
import {
useFetchTenantInfo,
useSelectParserList,
} from '@/hooks/userSettingHook';
import { Modal, Space, Tag } from 'antd';
import React, { useEffect, useState } from 'react';
import styles from './index.less';
const { CheckableTag } = Tag;
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
loading: boolean;
onOk: (parserId: string) => void;
showModal?(): void;
parser_id: string;
}
const ChunkMethodModal: React.FC<IProps> = ({
parser_id,
onOk,
hideModal,
visible,
}) => {
const [selectedTag, setSelectedTag] = useState('');
const parserList = useSelectParserList();
useFetchTenantInfo();
useEffect(() => {
setSelectedTag(parser_id);
}, [parser_id]);
const handleOk = async () => {
onOk(selectedTag);
};
const handleChange = (tag: string, checked: boolean) => {
const nextSelectedTag = checked ? tag : selectedTag;
setSelectedTag(nextSelectedTag);
};
return (
<Modal
title="Chunk Method"
open={visible}
onOk={handleOk}
onCancel={hideModal}
>
<Space size={[0, 8]} wrap>
<div className={styles.tags}>
{parserList.map((x) => {
return (
<CheckableTag
key={x.value}
checked={selectedTag === x.value}
onChange={(checked) => handleChange(x.value, checked)}
>
{x.label}
</CheckableTag>
);
})}
</div>
</Space>
</Modal>
);
};
export default ChunkMethodModal;

View File

@ -0,0 +1,49 @@
import { IModalManagerChildrenProps } from '@/components/modal-manager';
import { Form, Input, Modal } from 'antd';
import React from 'react';
type FieldType = {
name?: string;
};
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
loading: boolean;
onOk: (name: string) => void;
showModal?(): void;
}
const FileCreatingModal: React.FC<IProps> = ({ visible, hideModal, onOk }) => {
const [form] = Form.useForm();
const handleOk = async () => {
const values = await form.validateFields();
onOk(values.name);
};
return (
<Modal
title="File Name"
open={visible}
onOk={handleOk}
onCancel={hideModal}
>
<Form
form={form}
name="validateOnly"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ maxWidth: 600 }}
autoComplete="off"
>
<Form.Item<FieldType>
label="File Name"
name="name"
rules={[{ required: true, message: 'Please input name!' }]}
>
<Input />
</Form.Item>
</Form>
</Modal>
);
};
export default FileCreatingModal;

View File

@ -1,78 +0,0 @@
import { Form, Input, Modal } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'umi';
type FieldType = {
name?: string;
};
interface kFProps {
getKfList: () => void;
kb_id: string;
}
const FileCreatingModal: React.FC<kFProps> = ({ getKfList, kb_id }) => {
const dispatch = useDispatch();
const [form] = Form.useForm();
const kFModel = useSelector((state: any) => state.kFModel);
const { isShowCEFwModal } = kFModel;
const { t } = useTranslation();
const handleCancel = () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowCEFwModal: false,
},
});
};
const createDocument = async () => {
try {
const values = await form.validateFields();
const retcode = await dispatch<any>({
type: 'kFModel/document_create',
payload: {
name: values.name,
kb_id,
},
});
if (retcode === 0) {
getKfList && getKfList();
}
} catch (errorInfo) {
console.log('Failed:', errorInfo);
}
};
const handleOk = async () => {
createDocument();
};
return (
<Modal
title="File Name"
open={isShowCEFwModal}
onOk={handleOk}
onCancel={handleCancel}
>
<Form
form={form}
name="validateOnly"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ maxWidth: 600 }}
autoComplete="off"
>
<Form.Item<FieldType>
label="File Name"
name="name"
rules={[{ required: true, message: 'Please input name!' }]}
>
<Input />
</Form.Item>
</Form>
</Modal>
);
};
export default FileCreatingModal;

View File

@ -0,0 +1,241 @@
import { useSetModalState } from '@/hooks/commonHooks';
import {
useCreateDocument,
useFetchDocumentList,
useSaveDocumentName,
useSetDocumentParser,
} from '@/hooks/documentHooks';
import { useGetKnowledgeSearchParams } from '@/hooks/routeHook';
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
import { useFetchTenantInfo } from '@/hooks/userSettingHook';
import { Pagination } from '@/interfaces/common';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { PaginationProps } from 'antd';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useNavigate, useSelector } from 'umi';
import { KnowledgeRouteKey } from './constant';
export const useFetchDocumentListOnMount = () => {
const { knowledgeId } = useGetKnowledgeSearchParams();
const fetchDocumentList = useFetchDocumentList();
const dispatch = useDispatch();
useFetchTenantInfo();
useEffect(() => {
if (knowledgeId) {
fetchDocumentList();
dispatch({
type: 'kFModel/pollGetDocumentList-start',
payload: knowledgeId,
});
}
return () => {
dispatch({
type: 'kFModel/pollGetDocumentList-stop',
});
};
}, [knowledgeId, dispatch, fetchDocumentList]);
return { fetchDocumentList };
};
export const useGetPagination = (fetchDocumentList: () => void) => {
const dispatch = useDispatch();
const kFModel = useSelector((state: any) => state.kFModel);
const setPagination = useCallback(
(pageNumber = 1, pageSize?: number) => {
const pagination: Pagination = {
current: pageNumber,
} as Pagination;
if (pageSize) {
pagination.pageSize = pageSize;
}
dispatch({
type: 'kFModel/setPagination',
payload: pagination,
});
},
[dispatch],
);
const onPageChange: PaginationProps['onChange'] = useCallback(
(pageNumber: number, pageSize: number) => {
setPagination(pageNumber, pageSize);
fetchDocumentList();
},
[fetchDocumentList, setPagination],
);
const pagination: PaginationProps = useMemo(() => {
return {
showQuickJumper: true,
total: kFModel.total,
showSizeChanger: true,
current: kFModel.pagination.currentPage,
pageSize: kFModel.pagination.pageSize,
pageSizeOptions: [1, 2, 10, 20, 50, 100],
onChange: onPageChange,
};
}, [kFModel, onPageChange]);
return {
pagination,
setPagination,
total: kFModel.total,
searchString: kFModel.searchString,
};
};
export const useSelectDocumentListLoading = () => {
return useOneNamespaceEffectsLoading('kFModel', [
'getKfList',
'updateDocumentStatus',
]);
};
export const useNavigateToOtherPage = () => {
const navigate = useNavigate();
const { knowledgeId } = useGetKnowledgeSearchParams();
const linkToUploadPage = useCallback(() => {
navigate(`/knowledge/dataset/upload?id=${knowledgeId}`);
}, [navigate, knowledgeId]);
const toChunk = useCallback(
(id: string) => {
navigate(
`/knowledge/${KnowledgeRouteKey.Dataset}/chunk?id=${knowledgeId}&doc_id=${id}`,
);
},
[navigate, knowledgeId],
);
return { linkToUploadPage, toChunk };
};
export const useHandleSearchChange = (setPagination: () => void) => {
const dispatch = useDispatch();
const { knowledgeId } = useGetKnowledgeSearchParams();
const throttledGetDocumentList = useCallback(() => {
dispatch({
type: 'kFModel/throttledGetDocumentList',
payload: knowledgeId,
});
}, [dispatch, knowledgeId]);
const handleInputChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const value = e.target.value;
dispatch({ type: 'kFModel/setSearchString', payload: value });
setPagination();
throttledGetDocumentList();
},
[setPagination, throttledGetDocumentList, dispatch],
);
return { handleInputChange };
};
export const useSetSelectedRecord = () => {
const [currentRecord, setCurrentRecord] = useState<IKnowledgeFile>(
{} as IKnowledgeFile,
);
const setRecord = (record: IKnowledgeFile) => () => {
setCurrentRecord(record);
};
return { currentRecord, setRecord };
};
export const useRenameDocument = (documentId: string) => {
const saveName = useSaveDocumentName();
const {
visible: renameVisible,
hideModal: hideRenameModal,
showModal: showRenameModal,
} = useSetModalState();
const loading = useOneNamespaceEffectsLoading('kFModel', ['document_rename']);
const onRenameOk = useCallback(
async (name: string) => {
const ret = await saveName(documentId, name);
if (ret === 0) {
hideRenameModal();
}
},
[hideRenameModal, saveName, documentId],
);
return {
renameLoading: loading,
onRenameOk,
renameVisible,
hideRenameModal,
showRenameModal,
};
};
export const useCreateEmptyDocument = () => {
const createDocument = useCreateDocument();
const {
visible: createVisible,
hideModal: hideCreateModal,
showModal: showCreateModal,
} = useSetModalState();
const loading = useOneNamespaceEffectsLoading('kFModel', ['document_create']);
const onCreateOk = useCallback(
async (name: string) => {
const ret = await createDocument(name);
if (ret === 0) {
hideCreateModal();
}
},
[hideCreateModal, createDocument],
);
return {
createLoading: loading,
onCreateOk,
createVisible,
hideCreateModal,
showCreateModal,
};
};
export const useChangeDocumentParser = (documentId: string) => {
const setDocumentParser = useSetDocumentParser();
const {
visible: changeParserVisible,
hideModal: hideChangeParserModal,
showModal: showChangeParserModal,
} = useSetModalState();
const loading = useOneNamespaceEffectsLoading('kFModel', [
'document_change_parser',
]);
const onChangeParserOk = useCallback(
async (parserId: string) => {
const ret = await setDocumentParser(parserId, documentId);
if (ret === 0) {
hideChangeParserModal();
}
},
[hideChangeParserModal, setDocumentParser, documentId],
);
return {
changeParserLoading: loading,
onChangeParserOk,
changeParserVisible,
hideChangeParserModal,
showChangeParserModal,
};
};

View File

@ -1,12 +1,9 @@
import { KnowledgeRouteKey } from '@/constants/knowledge';
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
import {
useFetchTenantInfo,
useSelectParserList,
} from '@/hooks/userSettingHook';
import { Pagination } from '@/interfaces/common';
useSelectDocumentList,
useSetDocumentStatus,
} from '@/hooks/documentHooks';
import { useSelectParserList } from '@/hooks/userSettingHook';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { getOneNamespaceEffectsLoading } from '@/utils/storeUtil';
import {
FileOutlined,
FileTextOutlined,
@ -25,133 +22,57 @@ import {
Tag,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { PaginationProps } from 'antd/lib';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useNavigate, useSelector } from 'umi';
import CreateEPModal from './createEFileModal';
import styles from './index.less';
import { useMemo } from 'react';
import ChunkMethodModal from './chunk-method-modal';
import CreateFileModal from './create-file-modal';
import {
useChangeDocumentParser,
useCreateEmptyDocument,
useFetchDocumentListOnMount,
useGetPagination,
useHandleSearchChange,
useNavigateToOtherPage,
useRenameDocument,
useSetSelectedRecord,
} from './hooks';
import ParsingActionCell from './parsing-action-cell';
import ParsingStatusCell from './parsing-status-cell';
import RenameModal from './rename-modal';
import SegmentSetModal from './segmentSetModal';
import styles from './index.less';
const KnowledgeFile = () => {
const dispatch = useDispatch();
const kFModel = useSelector((state: any) => state.kFModel);
const effects = useSelector((state: any) => state.loading.effects);
const { data, total } = kFModel;
const knowledgeBaseId = useKnowledgeBaseId();
const loading = getOneNamespaceEffectsLoading('kFModel', effects, [
'getKfList',
'updateDocumentStatus',
]);
const [doc_id, setDocId] = useState('0');
const [parser_id, setParserId] = useState('0');
let navigate = useNavigate();
const data = useSelectDocumentList();
const { fetchDocumentList } = useFetchDocumentListOnMount();
const parserList = useSelectParserList();
const { pagination, setPagination, total, searchString } =
useGetPagination(fetchDocumentList);
const onChangeStatus = useSetDocumentStatus();
const { linkToUploadPage, toChunk } = useNavigateToOtherPage();
const getKfList = useCallback(() => {
const payload = {
kb_id: knowledgeBaseId,
};
dispatch({
type: 'kFModel/getKfList',
payload,
});
}, [dispatch, knowledgeBaseId]);
const throttledGetDocumentList = () => {
dispatch({
type: 'kFModel/throttledGetDocumentList',
payload: knowledgeBaseId,
});
};
const setPagination = useCallback(
(pageNumber = 1, pageSize?: number) => {
const pagination: Pagination = {
current: pageNumber,
} as Pagination;
if (pageSize) {
pagination.pageSize = pageSize;
}
dispatch({
type: 'kFModel/setPagination',
payload: pagination,
});
},
[dispatch],
);
const onPageChange: PaginationProps['onChange'] = useCallback(
(pageNumber: number, pageSize: number) => {
setPagination(pageNumber, pageSize);
getKfList();
},
[getKfList, setPagination],
);
const pagination: PaginationProps = useMemo(() => {
return {
showQuickJumper: true,
total,
showSizeChanger: true,
current: kFModel.pagination.currentPage,
pageSize: kFModel.pagination.pageSize,
pageSizeOptions: [1, 2, 10, 20, 50, 100],
onChange: onPageChange,
};
}, [total, kFModel.pagination, onPageChange]);
useEffect(() => {
if (knowledgeBaseId) {
getKfList();
dispatch({
type: 'kFModel/pollGetDocumentList-start',
payload: knowledgeBaseId,
});
}
return () => {
dispatch({
type: 'kFModel/pollGetDocumentList-stop',
});
};
}, [knowledgeBaseId, dispatch, getKfList]);
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const value = e.target.value;
dispatch({ type: 'kFModel/setSearchString', payload: value });
setPagination();
throttledGetDocumentList();
};
const onChangeStatus = (e: boolean, doc_id: string) => {
dispatch({
type: 'kFModel/updateDocumentStatus',
payload: {
doc_id,
status: Number(e),
kb_id: knowledgeBaseId,
},
});
};
const showCEFModal = useCallback(() => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowCEFwModal: true,
},
});
}, [dispatch]);
const linkToUploadPage = useCallback(() => {
navigate(`/knowledge/dataset/upload?id=${knowledgeBaseId}`);
}, [navigate, knowledgeBaseId]);
const { handleInputChange } = useHandleSearchChange(setPagination);
const { currentRecord, setRecord } = useSetSelectedRecord();
const {
renameLoading,
onRenameOk,
renameVisible,
hideRenameModal,
showRenameModal,
} = useRenameDocument(currentRecord.id);
const {
createLoading,
onCreateOk,
createVisible,
hideCreateModal,
showCreateModal,
} = useCreateEmptyDocument();
const {
changeParserLoading,
onChangeParserOk,
changeParserVisible,
hideChangeParserModal,
showChangeParserModal,
} = useChangeDocumentParser(currentRecord.id);
const actionItems: MenuProps['items'] = useMemo(() => {
return [
@ -172,7 +93,7 @@ const KnowledgeFile = () => {
{ type: 'divider' },
{
key: '2',
onClick: showCEFModal,
onClick: showCreateModal,
label: (
<div>
<Button type="link">
@ -184,18 +105,7 @@ const KnowledgeFile = () => {
// disabled: true,
},
];
}, [linkToUploadPage, showCEFModal]);
const toChunk = (id: string) => {
navigate(
`/knowledge/${KnowledgeRouteKey.Dataset}/chunk?id=${knowledgeBaseId}&doc_id=${id}`,
);
};
const setDocumentAndParserId = (record: IKnowledgeFile) => () => {
setDocId(record.id);
setParserId(record.parser_id);
};
}, [linkToUploadPage, showCreateModal]);
const columns: ColumnsType<IKnowledgeFile> = [
{
@ -255,8 +165,12 @@ const KnowledgeFile = () => {
key: 'action',
render: (_, record) => (
<ParsingActionCell
knowledgeBaseId={knowledgeBaseId}
setDocumentAndParserId={setDocumentAndParserId(record)}
setDocumentAndParserId={setRecord(record)}
showRenameModal={() => {
setRecord(record)();
showRenameModal();
}}
showChangeParserModal={showChangeParserModal}
record={record}
></ParsingActionCell>
),
@ -268,8 +182,6 @@ const KnowledgeFile = () => {
className: `${styles.column}`,
}));
useFetchTenantInfo();
return (
<div className={styles.datasetWrapper}>
<h3>Dataset</h3>
@ -283,7 +195,7 @@ const KnowledgeFile = () => {
<Space>
<Input
placeholder="Seach your files"
value={kFModel.searchString}
value={searchString}
style={{ width: 220 }}
allowClear
onChange={handleInputChange}
@ -305,13 +217,26 @@ const KnowledgeFile = () => {
pagination={pagination}
scroll={{ scrollToFirstRowOnChange: true, x: 1300, y: 'fill' }}
/>
<CreateEPModal getKfList={getKfList} kb_id={knowledgeBaseId} />
<SegmentSetModal
getKfList={getKfList}
parser_id={parser_id}
doc_id={doc_id}
<CreateFileModal
visible={createVisible}
hideModal={hideCreateModal}
loading={createLoading}
onOk={onCreateOk}
/>
<RenameModal></RenameModal>
<ChunkMethodModal
parser_id={currentRecord.parser_id}
onOk={onChangeParserOk}
visible={changeParserVisible}
hideModal={hideChangeParserModal}
loading={changeParserLoading}
/>
<RenameModal
visible={renameVisible}
onOk={onRenameOk}
loading={renameLoading}
hideModal={hideRenameModal}
initialName={currentRecord.name}
></RenameModal>
</div>
);
};

View File

@ -164,6 +164,10 @@ const model: DvaModel<KFModelState> = {
const { data } = yield call(kbService.document_create, payload);
const { retcode } = data;
if (retcode === 0) {
put({
type: 'getKfList',
payload: { kb_id: payload.kb_id },
});
put({
type: 'kFModel/updateState',
payload: {
@ -192,9 +196,16 @@ const model: DvaModel<KFModelState> = {
return retcode;
},
*document_change_parser({ payload = {} }, { call, put }) {
const { data } = yield call(kbService.document_change_parser, payload);
const { data } = yield call(
kbService.document_change_parser,
omit(payload, ['kb_id']),
);
const { retcode } = data;
if (retcode === 0) {
put({
type: 'getKfList',
payload: { kb_id: payload.kb_id },
});
put({
type: 'updateState',
payload: {

View File

@ -1,5 +1,8 @@
import showDeleteConfirm from '@/components/deleting-confirm';
import { useRemoveDocument } from '@/hooks/documentHooks';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { api_host } from '@/utils/api';
import { downloadFile } from '@/utils/fileUtil';
import {
DeleteOutlined,
DownloadOutlined,
@ -7,37 +10,27 @@ import {
ToolOutlined,
} from '@ant-design/icons';
import { Button, Dropdown, MenuProps, Space, Tooltip } from 'antd';
import { useDispatch } from 'umi';
import { isParserRunning } from '../utils';
import { api_host } from '@/utils/api';
import { downloadFile } from '@/utils/fileUtil';
import styles from './index.less';
interface IProps {
knowledgeBaseId: string;
record: IKnowledgeFile;
setDocumentAndParserId: () => void;
showRenameModal: () => void;
showChangeParserModal: () => void;
}
const ParsingActionCell = ({
knowledgeBaseId,
record,
setDocumentAndParserId,
showRenameModal,
showChangeParserModal,
}: IProps) => {
const dispatch = useDispatch();
const documentId = record.id;
const isRunning = isParserRunning(record.run);
const removeDocument = () => {
dispatch({
type: 'kFModel/document_rm',
payload: {
doc_id: documentId,
kb_id: knowledgeBaseId,
},
});
};
const removeDocument = useRemoveDocument(documentId);
const onRmDocument = () => {
if (!isRunning) {
@ -52,39 +45,13 @@ const ParsingActionCell = ({
});
};
const setCurrentRecord = () => {
dispatch({
type: 'kFModel/setCurrentRecord',
payload: record,
});
};
const showSegmentSetModal = () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowSegmentSetModal: true,
},
});
};
const showRenameModal = () => {
if (!isRunning) {
setCurrentRecord();
dispatch({
type: 'kFModel/setIsShowRenameModal',
payload: true,
});
}
};
const chunkItems: MenuProps['items'] = [
{
key: '1',
label: (
<div>
<Button type="link" onClick={showSegmentSetModal}>
Category
<Button type="link" onClick={showChangeParserModal}>
Chunk Method
</Button>
</div>
),

View File

@ -1,46 +1,30 @@
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
import { IModalManagerChildrenProps } from '@/components/modal-manager';
import { Form, Input, Modal } from 'antd';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'umi';
const RenameModal = () => {
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
loading: boolean;
initialName: string;
onOk: (name: string) => void;
showModal?(): void;
}
const RenameModal = ({
visible,
onOk,
loading,
initialName,
hideModal,
}: IProps) => {
const [form] = Form.useForm();
const dispatch = useDispatch();
const kFModel = useSelector((state: any) => state.kFModel);
const loading = useSelector(
(state: any) => state.loading.effects['kFModel/document_rename'],
);
const knowledgeBaseId = useKnowledgeBaseId();
const isModalOpen = kFModel.isShowRenameModal;
const initialName = kFModel.currentRecord?.name;
const documentId = kFModel.currentRecord?.id;
type FieldType = {
name?: string;
};
const closeModal = () => {
dispatch({
type: 'kFModel/setIsShowRenameModal',
payload: false,
});
};
const handleOk = async () => {
const ret = await form.validateFields();
dispatch({
type: 'kFModel/document_rename',
payload: {
doc_id: documentId,
name: ret.name,
kb_id: knowledgeBaseId,
},
});
};
const handleCancel = () => {
closeModal();
onOk(ret.name);
};
const onFinish = (values: any) => {
@ -52,17 +36,17 @@ const RenameModal = () => {
};
useEffect(() => {
if (isModalOpen) {
if (visible) {
form.setFieldValue('name', initialName);
}
}, [initialName, documentId, form, isModalOpen]);
}, [initialName, form, visible]);
return (
<Modal
title="Rename"
open={isModalOpen}
open={visible}
onOk={handleOk}
onCancel={handleCancel}
onCancel={hideModal}
okButtonProps={{ loading }}
>
<Form

View File

@ -35,7 +35,11 @@ const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
<Title level={5} className={styles.topTitle}>
{item.title} Category
</Title>
<Text>{item.description}</Text>
<p
dangerouslySetInnerHTML={{
__html: item.description,
}}
></p>
<Title level={5}>{item.title} Image Examples</Title>
<Text>
We've prepared detailed visual guides to make understanding easier

View File

@ -21,10 +21,10 @@ const Configuration = () => {
<Divider></Divider>
<Spin spinning={loading}>
<Row gutter={32}>
<Col span={12}>
<Col span={8}>
<ConfigurationForm form={form}></ConfigurationForm>
</Col>
<Col span={12}>
<Col span={16}>
<CategoryPanel chunkMethod={chunkMethod}></CategoryPanel>
</Col>
</Row>

View File

@ -1,4 +1,5 @@
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
import RenameModal from '@/components/rename-modal';
import { DeleteOutlined, EditOutlined, FormOutlined } from '@ant-design/icons';
import {
Avatar,
@ -34,7 +35,6 @@ import {
useSelectFirstDialogOnMount,
} from './hooks';
import RenameModal from '@/components/rename-modal';
import styles from './index.less';
const Chat = () => {