Преглед на файлове

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

* feat: add hooks for document table

* refactor: refactor document-related modal
tags/v0.1.0
balibabu преди 1 година
родител
ревизия
73c2f4d418
No account linked to committer's email address

+ 140
- 2
web/src/hooks/documentHooks.ts Целия файл

@@ -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;
};

web/src/pages/add-knowledge/components/knowledge-file/segmentSetModal.tsx → web/src/pages/add-knowledge/components/knowledge-file/chunk-method-modal.tsx Целия файл

@@ -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;

+ 49
- 0
web/src/pages/add-knowledge/components/knowledge-file/create-file-modal.tsx Целия файл

@@ -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;

+ 0
- 78
web/src/pages/add-knowledge/components/knowledge-file/createEFileModal.tsx Целия файл

@@ -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;

+ 241
- 0
web/src/pages/add-knowledge/components/knowledge-file/hooks.ts Целия файл

@@ -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,
};
};

+ 77
- 152
web/src/pages/add-knowledge/components/knowledge-file/index.tsx Целия файл

@@ -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';
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();
import styles from './index.less';
const loading = getOneNamespaceEffectsLoading('kFModel', effects, [
'getKfList',
'updateDocumentStatus',
]);
const [doc_id, setDocId] = useState('0');
const [parser_id, setParserId] = useState('0');
let navigate = useNavigate();
const KnowledgeFile = () => {
const data = useSelectDocumentList();
const { fetchDocumentList } = useFetchDocumentListOnMount();
const parserList = useSelectParserList();
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 { pagination, setPagination, total, searchString } =
useGetPagination(fetchDocumentList);
const onChangeStatus = useSetDocumentStatus();
const { linkToUploadPage, toChunk } = useNavigateToOtherPage();
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}
/>
<ChunkMethodModal
parser_id={currentRecord.parser_id}
onOk={onChangeParserOk}
visible={changeParserVisible}
hideModal={hideChangeParserModal}
loading={changeParserLoading}
/>
<RenameModal></RenameModal>
<RenameModal
visible={renameVisible}
onOk={onRenameOk}
loading={renameLoading}
hideModal={hideRenameModal}
initialName={currentRecord.name}
></RenameModal>
</div>
);
};

+ 12
- 1
web/src/pages/add-knowledge/components/knowledge-file/model.ts Целия файл

@@ -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: {

+ 10
- 43
web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx Целия файл

@@ -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>
),

+ 20
- 36
web/src/pages/add-knowledge/components/knowledge-file/rename-modal/index.tsx Целия файл

@@ -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

+ 5
- 1
web/src/pages/add-knowledge/components/knowledge-setting/category-panel.tsx Целия файл

@@ -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

+ 2
- 2
web/src/pages/add-knowledge/components/knowledge-setting/index.tsx Целия файл

@@ -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>

+ 1
- 1
web/src/pages/chat/index.tsx Целия файл

@@ -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 = () => {

Loading…
Отказ
Запис