mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-10 16:59:01 +08:00
feat: modify routing to nested mode and rename document (#52)
* feat: modify routing to nested mode * feat: rename document
This commit is contained in:
parent
503735cd1d
commit
7b71fb2db6
0
web/src/components/deleting-confirm/index.less
Normal file
0
web/src/components/deleting-confirm/index.less
Normal file
28
web/src/components/deleting-confirm/index.tsx
Normal file
28
web/src/components/deleting-confirm/index.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
import { Modal } from 'antd';
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
interface IProps {
|
||||
onOk?: (...args: any[]) => any;
|
||||
onCancel?: (...args: any[]) => any;
|
||||
}
|
||||
|
||||
export const showDeleteConfirm = ({ onOk, onCancel }: IProps) => {
|
||||
confirm({
|
||||
title: 'Are you sure delete this item?',
|
||||
icon: <ExclamationCircleFilled />,
|
||||
content: 'Some descriptions',
|
||||
okText: 'Yes',
|
||||
okType: 'danger',
|
||||
cancelText: 'No',
|
||||
onOk() {
|
||||
onOk?.();
|
||||
},
|
||||
onCancel() {
|
||||
onCancel?.();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default showDeleteConfirm;
|
24
web/src/components/modal-manager.tsx
Normal file
24
web/src/components/modal-manager.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
interface IProps {
|
||||
children: (props: {
|
||||
showModal(): void;
|
||||
hideModal(): void;
|
||||
visible: boolean;
|
||||
}) => React.ReactNode;
|
||||
}
|
||||
|
||||
const ModalManager = ({ children }: IProps) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const showModal = () => {
|
||||
setVisible(true);
|
||||
};
|
||||
const hideModal = () => {
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
return children({ visible, showModal, hideModal });
|
||||
};
|
||||
|
||||
export default ModalManager;
|
@ -1,5 +1,13 @@
|
||||
export enum KnowledgeRouteKey {
|
||||
Dataset = 'dataset',
|
||||
Testing = 'testing',
|
||||
Configration = 'configration',
|
||||
Configuration = 'configuration',
|
||||
}
|
||||
|
||||
export enum RunningStatus {
|
||||
UNSTART = '0',
|
||||
RUNNING = '1',
|
||||
CANCEL = '2',
|
||||
DONE = '3',
|
||||
FAIL = '4',
|
||||
}
|
||||
|
8
web/src/hooks/knowledgeHook.ts
Normal file
8
web/src/hooks/knowledgeHook.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { useSearchParams } from 'umi';
|
||||
|
||||
export const useKnowledgeBaseId = (): string => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const knowledgeBaseId = searchParams.get('id');
|
||||
|
||||
return knowledgeBaseId || '';
|
||||
};
|
21
web/src/hooks/routeHook.ts
Normal file
21
web/src/hooks/routeHook.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { useLocation } from 'umi';
|
||||
|
||||
export enum SegmentIndex {
|
||||
Second = '2',
|
||||
Third = '3',
|
||||
}
|
||||
|
||||
export const useSegmentedPathName = (index: SegmentIndex) => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const pathArray = pathname.split('/');
|
||||
return pathArray[index] || '';
|
||||
};
|
||||
|
||||
export const useSecondPathName = () => {
|
||||
return useSegmentedPathName(SegmentIndex.Second);
|
||||
};
|
||||
|
||||
export const useThirdPathName = () => {
|
||||
return useSegmentedPathName(SegmentIndex.Third);
|
||||
};
|
26
web/src/interfaces/database/knowledge.ts
Normal file
26
web/src/interfaces/database/knowledge.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { RunningStatus } from '@/constants/knowledge';
|
||||
|
||||
export interface IKnowledgeFile {
|
||||
chunk_num: number;
|
||||
create_date: string;
|
||||
create_time: number;
|
||||
created_by: string;
|
||||
id: string;
|
||||
kb_id: string;
|
||||
location: string;
|
||||
name: string;
|
||||
parser_id: string;
|
||||
process_begin_at?: any;
|
||||
process_duation: number;
|
||||
progress: number; // parsing process
|
||||
progress_msg: string; // parsing log
|
||||
run: RunningStatus; // parsing status
|
||||
size: number;
|
||||
source_type: string;
|
||||
status: string; // enabled
|
||||
thumbnail?: any; // base64
|
||||
token_num: number;
|
||||
type: string;
|
||||
update_date: string;
|
||||
update_time: number;
|
||||
}
|
@ -14,11 +14,11 @@ import {
|
||||
Spin,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
||||
import CreateModal from './components/createModal';
|
||||
|
||||
import { debounce } from 'lodash';
|
||||
import styles from './index.less';
|
||||
|
||||
interface PayloadType {
|
||||
@ -27,18 +27,13 @@ interface PayloadType {
|
||||
available_int?: number;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
doc_id: string;
|
||||
}
|
||||
|
||||
const Chunk = ({ doc_id }: IProps) => {
|
||||
const Chunk = () => {
|
||||
const dispatch = useDispatch();
|
||||
const chunkModel = useSelector((state: any) => state.chunkModel);
|
||||
const [keywords, SetKeywords] = useState('');
|
||||
const [available_int, setAvailableInt] = useState(-1);
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const [pagination, setPagination] = useState({ page: 1, size: 30 });
|
||||
// const [datas, setDatas] = useState(data)
|
||||
const { data = [], total, chunk_id, isShowCreateModal } = chunkModel;
|
||||
const effects = useSelector((state: any) => state.loading.effects);
|
||||
const loading = getOneNamespaceEffectsLoading('chunkModel', effects, [
|
||||
@ -46,10 +41,11 @@ const Chunk = ({ doc_id }: IProps) => {
|
||||
'chunk_list',
|
||||
'switch_chunk',
|
||||
]);
|
||||
const documentId: string = searchParams.get('doc_id') || '';
|
||||
|
||||
const getChunkList = (value?: string) => {
|
||||
const payload: PayloadType = {
|
||||
doc_id,
|
||||
doc_id: documentId,
|
||||
keywords: value || keywords,
|
||||
available_int,
|
||||
};
|
||||
@ -81,7 +77,7 @@ const Chunk = ({ doc_id }: IProps) => {
|
||||
payload: {
|
||||
isShowCreateModal: true,
|
||||
chunk_id,
|
||||
doc_id,
|
||||
doc_id: documentId,
|
||||
},
|
||||
});
|
||||
getChunkList();
|
||||
@ -100,7 +96,7 @@ const Chunk = ({ doc_id }: IProps) => {
|
||||
payload: {
|
||||
chunk_ids: [id],
|
||||
available_int: Number(available_int),
|
||||
doc_id,
|
||||
doc_id: documentId,
|
||||
},
|
||||
});
|
||||
|
||||
@ -109,7 +105,7 @@ const Chunk = ({ doc_id }: IProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
getChunkList();
|
||||
}, [doc_id, available_int, pagination]);
|
||||
}, [documentId, available_int, pagination]);
|
||||
|
||||
const debounceChange = debounce(getChunkList, 300);
|
||||
const debounceCallback = useCallback(
|
||||
@ -270,7 +266,7 @@ const Chunk = ({ doc_id }: IProps) => {
|
||||
</div>
|
||||
</div>
|
||||
<CreateModal
|
||||
doc_id={doc_id}
|
||||
doc_id={documentId}
|
||||
isShowCreateModal={isShowCreateModal}
|
||||
chunk_id={chunk_id}
|
||||
getChunkList={getChunkList}
|
||||
|
@ -0,0 +1,7 @@
|
||||
import { Outlet } from 'umi';
|
||||
|
||||
export const KnowledgeDataset = () => {
|
||||
return <Outlet></Outlet>;
|
||||
};
|
||||
|
||||
export default KnowledgeDataset;
|
@ -0,0 +1,5 @@
|
||||
const KnowledgeUploadFile = () => {
|
||||
return <div>KnowledgeUploadFile</div>;
|
||||
};
|
||||
|
||||
export default KnowledgeUploadFile;
|
@ -0,0 +1,17 @@
|
||||
import { RunningStatus } from '@/constants/knowledge';
|
||||
|
||||
export const RunningStatusMap = {
|
||||
[RunningStatus.UNSTART]: {
|
||||
label: 'UNSTART',
|
||||
color: 'cyan',
|
||||
},
|
||||
[RunningStatus.RUNNING]: {
|
||||
label: 'Parsing',
|
||||
color: 'blue',
|
||||
},
|
||||
[RunningStatus.CANCEL]: { label: 'CANCEL', color: 'orange' },
|
||||
[RunningStatus.DONE]: { label: 'SUCCESS', color: 'geekblue' },
|
||||
[RunningStatus.FAIL]: { label: 'FAIL', color: 'red' },
|
||||
};
|
||||
|
||||
export * from '@/constants/knowledge';
|
@ -13,9 +13,9 @@ interface kFProps {
|
||||
|
||||
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 [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleCancel = () => {
|
||||
@ -26,7 +26,8 @@ const FileCreatingModal: React.FC<kFProps> = ({ getKfList, kb_id }) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
const handleOk = async () => {
|
||||
|
||||
const createDocument = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
const retcode = await dispatch<any>({
|
||||
@ -44,9 +45,13 @@ const FileCreatingModal: React.FC<kFProps> = ({ getKfList, kb_id }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
createDocument();
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
title="File Name"
|
||||
open={isShowCEFwModal}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
@ -54,15 +59,15 @@ const FileCreatingModal: React.FC<kFProps> = ({ getKfList, kb_id }) => {
|
||||
<Form
|
||||
form={form}
|
||||
name="validateOnly"
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
labelCol={{ span: 4 }}
|
||||
wrapperCol={{ span: 20 }}
|
||||
style={{ maxWidth: 600 }}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="文件名"
|
||||
label="File Name"
|
||||
name="name"
|
||||
rules={[{ required: true, message: 'Please input value!' }]}
|
||||
rules={[{ required: true, message: 'Please input name!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
@ -1,28 +1,34 @@
|
||||
.datasetWrapper {
|
||||
padding: 30px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filter {
|
||||
height: 32px;
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
justify-content: space-between;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
justify-content: space-between;
|
||||
padding: 24px 20px;
|
||||
|
||||
.search {
|
||||
flex: 1;
|
||||
}
|
||||
// .search {
|
||||
// flex: 1;
|
||||
// }
|
||||
|
||||
.operate {
|
||||
width: 200px;
|
||||
}
|
||||
// .operate {
|
||||
// width: 200px;
|
||||
// }
|
||||
}
|
||||
|
||||
.img {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-right: 6px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.column {
|
||||
min-width: 200px
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.tochunks {
|
||||
cursor: pointer;
|
||||
}
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -1,37 +1,38 @@
|
||||
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { getOneNamespaceEffectsLoading } from '@/utils/stroreUtil';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Button, Dropdown, Input, Space, Switch, Table } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Dropdown,
|
||||
Input,
|
||||
Space,
|
||||
Switch,
|
||||
Table,
|
||||
Tag,
|
||||
} from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import CreateEPModal from './createEFileModal';
|
||||
import styles from './index.less';
|
||||
import ParsingActionCell from './parsing-action-cell';
|
||||
import ParsingStatusCell from './parsing-status-cell';
|
||||
import RenameModal from './rename-modal';
|
||||
import SegmentSetModal from './segmentSetModal';
|
||||
import UploadFile from './upload';
|
||||
|
||||
interface DataType {
|
||||
name: string;
|
||||
chunk_num: string;
|
||||
token_num: number;
|
||||
update_date: string;
|
||||
size: string;
|
||||
status: string;
|
||||
id: string;
|
||||
parser_id: string;
|
||||
}
|
||||
|
||||
interface KFProps {
|
||||
kb_id: string;
|
||||
}
|
||||
|
||||
const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
const KnowledgeFile = () => {
|
||||
const dispatch = useDispatch();
|
||||
const kFModel = useSelector((state: any) => state.kFModel);
|
||||
const effects = useSelector((state: any) => state.loading.effects);
|
||||
const { data } = kFModel;
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
|
||||
const loading = getOneNamespaceEffectsLoading('kFModel', effects, [
|
||||
'getKfList',
|
||||
'updateDocumentStatus',
|
||||
@ -43,7 +44,7 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
|
||||
const getKfList = (keywords?: string) => {
|
||||
const payload = {
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
keywords,
|
||||
};
|
||||
if (!keywords) {
|
||||
@ -56,10 +57,10 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (kb_id) {
|
||||
if (knowledgeBaseId) {
|
||||
getKfList();
|
||||
}
|
||||
}, [kb_id]);
|
||||
}, [knowledgeBaseId]);
|
||||
|
||||
const debounceChange = debounce(getKfList, 300);
|
||||
const debounceCallback = useCallback(
|
||||
@ -79,7 +80,7 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
payload: {
|
||||
doc_id,
|
||||
status: Number(e),
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -88,7 +89,7 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
type: 'kFModel/document_rm',
|
||||
payload: {
|
||||
doc_id,
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -109,13 +110,14 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
<div>
|
||||
<UploadFile kb_id={kb_id} getKfList={getKfList} />
|
||||
<UploadFile kb_id={knowledgeBaseId} getKfList={getKfList} />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@ -132,7 +134,7 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
// disabled: true,
|
||||
},
|
||||
];
|
||||
}, [kb_id]);
|
||||
}, [knowledgeBaseId]);
|
||||
const chunkItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
@ -158,14 +160,21 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
// disabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
const toChunk = (id: string) => {
|
||||
navigate(
|
||||
`/knowledge/${KnowledgeRouteKey.Dataset}?id=${kb_id}&doc_id=${id}`,
|
||||
`/knowledge/${KnowledgeRouteKey.Dataset}/chunk?id=${knowledgeBaseId}&doc_id=${id}`,
|
||||
);
|
||||
};
|
||||
const columns: ColumnsType<DataType> = [
|
||||
|
||||
const setDocumentAndParserId = (record: IKnowledgeFile) => () => {
|
||||
setDocId(record.id);
|
||||
setParserId(record.parser_id);
|
||||
};
|
||||
|
||||
const columns: ColumnsType<IKnowledgeFile> = [
|
||||
{
|
||||
title: '名称',
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
render: (text: any, { id }) => (
|
||||
@ -178,32 +187,30 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
{text}
|
||||
</div>
|
||||
),
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: '数据总量',
|
||||
title: 'Chunk Number',
|
||||
dataIndex: 'chunk_num',
|
||||
key: 'chunk_num',
|
||||
className: `${styles.column}`,
|
||||
},
|
||||
{
|
||||
title: 'Tokens',
|
||||
dataIndex: 'token_num',
|
||||
key: 'token_num',
|
||||
className: `${styles.column}`,
|
||||
title: 'Upload Date',
|
||||
dataIndex: 'create_date',
|
||||
key: 'create_date',
|
||||
},
|
||||
{
|
||||
title: '文件大小',
|
||||
dataIndex: 'size',
|
||||
key: 'size',
|
||||
className: `${styles.column}`,
|
||||
title: 'Parsing Status',
|
||||
dataIndex: 'run',
|
||||
key: 'run',
|
||||
render: (text, record) => {
|
||||
return <ParsingStatusCell record={record}></ParsingStatusCell>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
title: 'Enabled',
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
className: `${styles.column}`,
|
||||
render: (_, { status: string, id }) => (
|
||||
render: (_, { status, id }) => (
|
||||
<>
|
||||
<Switch
|
||||
defaultChecked={status === '1'}
|
||||
@ -217,58 +224,65 @@ const KnowledgeFile: React.FC<KFProps> = ({ kb_id }) => {
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'action',
|
||||
className: `${styles.column}`,
|
||||
render: (_, record) => (
|
||||
<Space size="middle">
|
||||
<Dropdown menu={{ items: chunkItems }} trigger={['click']}>
|
||||
<a
|
||||
onClick={() => {
|
||||
setDocId(record.id);
|
||||
setParserId(record.parser_id);
|
||||
}}
|
||||
>
|
||||
分段设置 <DownOutlined />
|
||||
</a>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
<ParsingActionCell
|
||||
documentId={doc_id}
|
||||
knowledgeBaseId={knowledgeBaseId}
|
||||
setDocumentAndParserId={setDocumentAndParserId(record)}
|
||||
record={record}
|
||||
></ParsingActionCell>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const finalColumns = columns.map((x) => ({
|
||||
...x,
|
||||
className: `${styles.column}`,
|
||||
}));
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.datasetWrapper}>
|
||||
<h3>Dataset</h3>
|
||||
<p>Hey, don't forget to adjust the chunk after adding the dataset! 😉</p>
|
||||
<Divider></Divider>
|
||||
<div className={styles.filter}>
|
||||
<div className="search">
|
||||
<Space>
|
||||
<h3>Total</h3>
|
||||
<Tag color="purple">100 files</Tag>
|
||||
</Space>
|
||||
<Space>
|
||||
<Input
|
||||
placeholder="搜索"
|
||||
placeholder="Seach your files"
|
||||
value={inputValue}
|
||||
style={{ width: 220 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
prefix={<SearchOutlined />}
|
||||
/>
|
||||
</div>
|
||||
<div className="operate">
|
||||
|
||||
<Dropdown menu={{ items: actionItems }} trigger={['click']}>
|
||||
<a>
|
||||
导入文件 <DownOutlined />
|
||||
</a>
|
||||
<Button type="primary" icon={<PlusOutlined />}>
|
||||
Add file
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
columns={finalColumns}
|
||||
dataSource={data}
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: true }}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: true, y: 'fill' }}
|
||||
/>
|
||||
<CreateEPModal getKfList={getKfList} kb_id={kb_id} />
|
||||
<CreateEPModal getKfList={getKfList} kb_id={knowledgeBaseId} />
|
||||
<SegmentSetModal
|
||||
getKfList={getKfList}
|
||||
parser_id={parser_id}
|
||||
doc_id={doc_id}
|
||||
/>
|
||||
</>
|
||||
<RenameModal></RenameModal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,14 +1,19 @@
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import kbService from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import omit from 'lodash/omit';
|
||||
import pick from 'lodash/pick';
|
||||
import { Nullable } from 'typings';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface KFModelState {
|
||||
isShowCEFwModal: boolean;
|
||||
isShowTntModal: boolean;
|
||||
isShowSegmentSetModal: boolean;
|
||||
isShowRenameModal: boolean;
|
||||
tenantIfo: any;
|
||||
data: any[];
|
||||
data: IKnowledgeFile[];
|
||||
currentRecord: Nullable<IKnowledgeFile>;
|
||||
}
|
||||
|
||||
const model: DvaModel<KFModelState> = {
|
||||
@ -17,8 +22,10 @@ const model: DvaModel<KFModelState> = {
|
||||
isShowCEFwModal: false,
|
||||
isShowTntModal: false,
|
||||
isShowSegmentSetModal: false,
|
||||
isShowRenameModal: false,
|
||||
tenantIfo: {},
|
||||
data: [],
|
||||
currentRecord: null,
|
||||
},
|
||||
reducers: {
|
||||
updateState(state, { payload }) {
|
||||
@ -27,6 +34,12 @@ const model: DvaModel<KFModelState> = {
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
setIsShowRenameModal(state, { payload }) {
|
||||
return { ...state, isShowRenameModal: payload };
|
||||
},
|
||||
setCurrentRecord(state, { payload }) {
|
||||
return { ...state, currentRecord: payload };
|
||||
},
|
||||
},
|
||||
subscriptions: {
|
||||
setup({ dispatch, history }) {
|
||||
@ -99,6 +112,26 @@ const model: DvaModel<KFModelState> = {
|
||||
});
|
||||
}
|
||||
},
|
||||
*document_rename({ payload = {} }, { call, put }) {
|
||||
const { data } = yield call(
|
||||
kbService.document_rename,
|
||||
omit(payload, ['kb_id']),
|
||||
);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('rename success!');
|
||||
yield put({
|
||||
type: 'setIsShowRenameModal',
|
||||
payload: false,
|
||||
});
|
||||
yield put({
|
||||
type: 'getKfList',
|
||||
payload: { kb_id: payload.kb_id },
|
||||
});
|
||||
}
|
||||
|
||||
return retcode;
|
||||
},
|
||||
*document_create({ payload = {} }, { call, put }) {
|
||||
const { data, response } = yield call(kbService.document_create, payload);
|
||||
const { retcode, data: res, retmsg } = data;
|
||||
|
@ -0,0 +1,88 @@
|
||||
import showDeleteConfirm from '@/components/deleting-confirm';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { DeleteOutlined, EditOutlined, ToolOutlined } from '@ant-design/icons';
|
||||
import { Button, Dropdown, MenuProps, Space, Tooltip } from 'antd';
|
||||
import { useDispatch } from 'umi';
|
||||
|
||||
interface IProps {
|
||||
documentId: string;
|
||||
knowledgeBaseId: string;
|
||||
record: IKnowledgeFile;
|
||||
setDocumentAndParserId: () => void;
|
||||
}
|
||||
|
||||
const ParsingActionCell = ({
|
||||
documentId,
|
||||
knowledgeBaseId,
|
||||
record,
|
||||
setDocumentAndParserId,
|
||||
}: IProps) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const removeDocument = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/document_rm',
|
||||
payload: {
|
||||
doc_id: documentId,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onRmDocument = () => {
|
||||
showDeleteConfirm({ onOk: removeDocument });
|
||||
};
|
||||
|
||||
const setCurrentRecord = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/setCurrentRecord',
|
||||
payload: record,
|
||||
});
|
||||
};
|
||||
|
||||
const showSegmentSetModal = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/updateState',
|
||||
payload: {
|
||||
isShowSegmentSetModal: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const showRenameModal = () => {
|
||||
setCurrentRecord();
|
||||
dispatch({
|
||||
type: 'kFModel/setIsShowRenameModal',
|
||||
payload: true,
|
||||
});
|
||||
};
|
||||
|
||||
const onRename = () => {};
|
||||
|
||||
const chunkItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link" onClick={showSegmentSetModal}>
|
||||
分段设置
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Space size={'middle'}>
|
||||
<Dropdown menu={{ items: chunkItems }} trigger={['click']}>
|
||||
<ToolOutlined size={20} onClick={setDocumentAndParserId} />
|
||||
</Dropdown>
|
||||
<Tooltip title="Rename">
|
||||
<EditOutlined size={20} onClick={showRenameModal} />
|
||||
</Tooltip>
|
||||
<DeleteOutlined size={20} onClick={onRmDocument} />
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
export default ParsingActionCell;
|
@ -0,0 +1,3 @@
|
||||
.popover-content {
|
||||
width: 300px;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
|
||||
import { RunningStatus, RunningStatusMap } from '../constant';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
interface IProps {
|
||||
record: IKnowledgeFile;
|
||||
}
|
||||
|
||||
const PopoverContent = ({ record }: IProps) => {
|
||||
const items: DescriptionsProps['items'] = [
|
||||
{
|
||||
key: 'process_begin_at',
|
||||
label: 'Process Begin At',
|
||||
children: record.process_begin_at,
|
||||
},
|
||||
{
|
||||
key: 'process_duation',
|
||||
label: 'Process Duration',
|
||||
children: record.process_duation,
|
||||
},
|
||||
{
|
||||
key: 'progress_msg',
|
||||
label: 'Progress Msg',
|
||||
children: record.progress_msg,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Flex vertical className={styles['popover-content']}>
|
||||
{items.map((x) => {
|
||||
return (
|
||||
<div>
|
||||
<b>{x.label}:</b>
|
||||
<p>{x.children}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export const ParsingStatusCell = ({ record }: IProps) => {
|
||||
const text = record.run;
|
||||
const runningStatus = RunningStatusMap[text];
|
||||
|
||||
const isRunning = text === RunningStatus.RUNNING;
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={isRunning && <PopoverContent record={record}></PopoverContent>}
|
||||
>
|
||||
<Tag color={runningStatus.color}>
|
||||
{isRunning ? (
|
||||
<Space>
|
||||
<Badge color={runningStatus.color} />
|
||||
`${runningStatus.label}${record.progress * 100}%`
|
||||
</Space>
|
||||
) : (
|
||||
runningStatus.label
|
||||
)}
|
||||
</Tag>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default ParsingStatusCell;
|
@ -0,0 +1,88 @@
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
|
||||
const RenameModal = () => {
|
||||
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();
|
||||
};
|
||||
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldValue('name', initialName);
|
||||
}, [initialName, documentId]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Rename"
|
||||
open={isModalOpen}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
okButtonProps={{ loading }}
|
||||
>
|
||||
<Form
|
||||
name="basic"
|
||||
labelCol={{ span: 4 }}
|
||||
wrapperCol={{ span: 20 }}
|
||||
style={{ maxWidth: 600 }}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="Name"
|
||||
name="name"
|
||||
rules={[{ required: true, message: 'Please input name!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default RenameModal;
|
@ -41,7 +41,6 @@ const SegmentSetModal: React.FC<kFProps> = ({
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
console.log(1111, selectedTag);
|
||||
const retcode = await dispatch<any>({
|
||||
type: 'kFModel/document_change_parser',
|
||||
payload: {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { DeleteOutlined, MinusSquareOutlined } from '@ant-design/icons';
|
||||
import type { PaginationProps } from 'antd';
|
||||
@ -12,18 +14,14 @@ import {
|
||||
Spin,
|
||||
Switch,
|
||||
} from 'antd';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
import CreateModal from '../knowledge-chunk/components/createModal';
|
||||
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { debounce } from 'lodash';
|
||||
import styles from './index.less';
|
||||
interface chunkProps {
|
||||
kb_id: string;
|
||||
}
|
||||
|
||||
const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
const KnowledgeSearching = () => {
|
||||
const dispatch = useDispatch();
|
||||
const kSearchModel = useSelector((state: any) => state.kSearchModel);
|
||||
const chunkModel = useSelector((state: any) => state.chunkModel);
|
||||
@ -31,6 +29,7 @@ const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
'chunk_list',
|
||||
'switch_chunk',
|
||||
]);
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
|
||||
const {
|
||||
data = [],
|
||||
@ -46,7 +45,7 @@ const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/chunk_list',
|
||||
payload: {
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -55,7 +54,7 @@ const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
type: 'kSearchModel/rm_chunk',
|
||||
payload: {
|
||||
chunk_ids: [id],
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -93,7 +92,7 @@ const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
dispatch({
|
||||
type: 'kSearchModel/getKfList',
|
||||
payload: {
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
@ -106,7 +105,7 @@ const KnowledgeSearching: React.FC<chunkProps> = ({ kb_id }) => {
|
||||
chunk_ids: [chunk_id],
|
||||
doc_id,
|
||||
available_int,
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import { Button, Form, Input, Radio, Select, Space, Tag } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
|
||||
@ -13,10 +14,7 @@ const layout = {
|
||||
const { Option } = Select;
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
|
||||
interface kSProps {
|
||||
kb_id: string;
|
||||
}
|
||||
const KnowledgeSetting: React.FC<kSProps> = ({ kb_id }) => {
|
||||
const KnowledgeSetting = () => {
|
||||
const dispatch = useDispatch();
|
||||
const settingModel = useSelector((state: any) => state.settingModel);
|
||||
let navigate = useNavigate();
|
||||
@ -25,17 +23,18 @@ const KnowledgeSetting: React.FC<kSProps> = ({ kb_id }) => {
|
||||
const [form] = Form.useForm();
|
||||
const [selectedTag, setSelectedTag] = useState('');
|
||||
const values = Form.useWatch([], form);
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
|
||||
const getTenantInfo = useCallback(async () => {
|
||||
dispatch({
|
||||
type: 'settingModel/getTenantInfo',
|
||||
payload: {},
|
||||
});
|
||||
if (kb_id) {
|
||||
if (knowledgeBaseId) {
|
||||
const data = await dispatch<any>({
|
||||
type: 'kSModel/getKbDetail',
|
||||
payload: {
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
},
|
||||
});
|
||||
if (data.retcode === 0) {
|
||||
@ -44,19 +43,19 @@ const KnowledgeSetting: React.FC<kSProps> = ({ kb_id }) => {
|
||||
setSelectedTag(data.data.parser_id);
|
||||
}
|
||||
}
|
||||
}, [kb_id]);
|
||||
}, [knowledgeBaseId]);
|
||||
|
||||
const onFinish = async () => {
|
||||
try {
|
||||
await form.validateFields();
|
||||
|
||||
if (kb_id) {
|
||||
if (knowledgeBaseId) {
|
||||
dispatch({
|
||||
type: 'kSModel/updateKb',
|
||||
payload: {
|
||||
...values,
|
||||
parser_id: selectedTag,
|
||||
kb_id,
|
||||
kb_id: knowledgeBaseId,
|
||||
embd_id: undefined,
|
||||
},
|
||||
});
|
||||
@ -69,7 +68,9 @@ const KnowledgeSetting: React.FC<kSProps> = ({ kb_id }) => {
|
||||
},
|
||||
});
|
||||
retcode === 0 &&
|
||||
navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${kb_id}`);
|
||||
navigate(
|
||||
`/knowledge/${KnowledgeRouteKey.Dataset}?id=${knowledgeBaseId}`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { ReactComponent as ConfigrationIcon } from '@/assets/svg/knowledge-configration.svg';
|
||||
import { ReactComponent as DatasetIcon } from '@/assets/svg/knowledge-dataset.svg';
|
||||
import { ReactComponent as TestingIcon } from '@/assets/svg/knowledge-testing.svg';
|
||||
import { useSecondPathName } from '@/hooks/routeHook';
|
||||
import { getWidth } from '@/utils';
|
||||
import { AntDesignOutlined } from '@ant-design/icons';
|
||||
import { Avatar, Menu, MenuProps, Space } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate, useParams, useSelector } from 'umi';
|
||||
import { useNavigate, useSelector } from 'umi';
|
||||
import { KnowledgeRouteKey, routeMap } from '../../constant';
|
||||
import styles from './index.less';
|
||||
|
||||
@ -14,8 +15,7 @@ const KnowledgeSidebar = () => {
|
||||
const kAModel = useSelector((state: any) => state.kAModel);
|
||||
const { id } = kAModel;
|
||||
let navigate = useNavigate();
|
||||
const params = useParams();
|
||||
const activeKey = params.module || KnowledgeRouteKey.Dataset;
|
||||
const activeKey = useSecondPathName();
|
||||
|
||||
const [windowWidth, setWindowWidth] = useState(getWidth());
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
@ -56,8 +56,8 @@ const KnowledgeSidebar = () => {
|
||||
<TestingIcon />,
|
||||
),
|
||||
getItem(
|
||||
routeMap[KnowledgeRouteKey.Configration],
|
||||
KnowledgeRouteKey.Configration,
|
||||
routeMap[KnowledgeRouteKey.Configuration],
|
||||
KnowledgeRouteKey.Configuration,
|
||||
<ConfigrationIcon />,
|
||||
),
|
||||
];
|
||||
|
@ -3,7 +3,17 @@ import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
export const routeMap = {
|
||||
[KnowledgeRouteKey.Dataset]: 'Dataset',
|
||||
[KnowledgeRouteKey.Testing]: 'Retrieval testing',
|
||||
[KnowledgeRouteKey.Configration]: 'Configuration',
|
||||
[KnowledgeRouteKey.Configuration]: 'Configuration',
|
||||
};
|
||||
|
||||
export enum KnowledgeDatasetRouteKey {
|
||||
Chunk = 'chunk',
|
||||
File = 'file',
|
||||
}
|
||||
|
||||
export const datasetRouteMap = {
|
||||
[KnowledgeDatasetRouteKey.Chunk]: 'Chunk',
|
||||
[KnowledgeDatasetRouteKey.File]: 'File Upload',
|
||||
};
|
||||
|
||||
export * from '@/constants/knowledge';
|
||||
|
@ -7,9 +7,12 @@
|
||||
height: 100%;
|
||||
background-color: rgba(247, 248, 250, 1);
|
||||
padding: 16px 20px 28px 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.content {
|
||||
background-color: white;
|
||||
margin-top: 16px;
|
||||
// flex: 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,60 @@
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import { useSecondPathName, useThirdPathName } from '@/hooks/routeHook';
|
||||
import { Breadcrumb } from 'antd';
|
||||
import { ItemType } from 'antd/es/breadcrumb/Breadcrumb';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import {
|
||||
useDispatch,
|
||||
useLocation,
|
||||
useNavigate,
|
||||
useParams,
|
||||
useSelector,
|
||||
} from 'umi';
|
||||
import Chunk from './components/knowledge-chunk';
|
||||
import File from './components/knowledge-file';
|
||||
import Search from './components/knowledge-search';
|
||||
import Setting from './components/knowledge-setting';
|
||||
import { Link, Outlet, useDispatch, useLocation, useNavigate } from 'umi';
|
||||
import Siderbar from './components/knowledge-sidebar';
|
||||
import { KnowledgeRouteKey, routeMap } from './constant';
|
||||
import {
|
||||
KnowledgeDatasetRouteKey,
|
||||
KnowledgeRouteKey,
|
||||
datasetRouteMap,
|
||||
routeMap,
|
||||
} from './constant';
|
||||
import styles from './index.less';
|
||||
|
||||
const KnowledgeAdding = () => {
|
||||
const dispatch = useDispatch();
|
||||
const kAModel = useSelector((state: any) => state.kAModel);
|
||||
const navigate = useNavigate();
|
||||
const { id, doc_id } = kAModel;
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const activeKey: KnowledgeRouteKey =
|
||||
(params.module as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset;
|
||||
(useSecondPathName() as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset;
|
||||
|
||||
const datasetActiveKey: KnowledgeDatasetRouteKey =
|
||||
useThirdPathName() as KnowledgeDatasetRouteKey;
|
||||
|
||||
const gotoList = () => {
|
||||
navigate('/knowledge');
|
||||
};
|
||||
|
||||
const breadcrumbItems = useMemo(() => {
|
||||
return [
|
||||
const breadcrumbItems: ItemType[] = useMemo(() => {
|
||||
const items: ItemType[] = [
|
||||
{
|
||||
title: <a onClick={gotoList}>Knowledge Base</a>,
|
||||
},
|
||||
{
|
||||
title: routeMap[activeKey],
|
||||
title: datasetActiveKey ? (
|
||||
<Link
|
||||
to={`/knowledge/${KnowledgeRouteKey.Dataset}?id=${knowledgeBaseId}`}
|
||||
>
|
||||
{routeMap[activeKey]}
|
||||
</Link>
|
||||
) : (
|
||||
routeMap[activeKey]
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [activeKey]);
|
||||
|
||||
if (datasetActiveKey) {
|
||||
items.push({
|
||||
title: datasetRouteMap[datasetActiveKey],
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}, [activeKey, datasetActiveKey]);
|
||||
|
||||
useEffect(() => {
|
||||
const search: string = location.search.slice(1);
|
||||
@ -65,16 +80,7 @@ const KnowledgeAdding = () => {
|
||||
<div className={styles.contentWrapper}>
|
||||
<Breadcrumb items={breadcrumbItems} />
|
||||
<div className={styles.content}>
|
||||
{activeKey === KnowledgeRouteKey.Dataset && !doc_id && (
|
||||
<File kb_id={id} />
|
||||
)}
|
||||
{activeKey === KnowledgeRouteKey.Configration && (
|
||||
<Setting kb_id={id} />
|
||||
)}
|
||||
{activeKey === KnowledgeRouteKey.Testing && <Search kb_id={id} />}
|
||||
{activeKey === KnowledgeRouteKey.Dataset && !!doc_id && (
|
||||
<Chunk doc_id={doc_id} />
|
||||
)}
|
||||
<Outlet></Outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ReactComponent as FilterIcon } from '@/assets/filter.svg';
|
||||
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Button, Col, Row, Space } from 'antd';
|
||||
import { Button, Flex, Space } from 'antd';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import styles from './index.less';
|
||||
@ -20,7 +21,7 @@ const Knowledge = () => {
|
||||
}, []);
|
||||
|
||||
const handleAddKnowledge = () => {
|
||||
navigate(`add/setting`);
|
||||
navigate(`/knowledge/${KnowledgeRouteKey.Configuration}`);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -50,7 +51,7 @@ const Knowledge = () => {
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
||||
{/* <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
|
||||
{data.map((item: any) => {
|
||||
return (
|
||||
<Col
|
||||
@ -58,14 +59,19 @@ const Knowledge = () => {
|
||||
key={item.name}
|
||||
xs={24}
|
||||
sm={12}
|
||||
md={8}
|
||||
lg={6}
|
||||
md={10}
|
||||
lg={8}
|
||||
>
|
||||
<KnowledgeCard item={item}></KnowledgeCard>
|
||||
</Col>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</Row> */}
|
||||
<Flex gap="large" wrap="wrap">
|
||||
{data.map((item: any) => {
|
||||
return <KnowledgeCard item={item} key={item.name}></KnowledgeCard>;
|
||||
})}
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -26,7 +26,7 @@
|
||||
border: 1px solid rgba(234, 236, 240, 1);
|
||||
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
|
||||
padding: 24px;
|
||||
min-width: 300px;
|
||||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
|
||||
.titleWrapper {
|
||||
|
@ -16,8 +16,37 @@ const routes = [
|
||||
component: '@/pages/knowledge',
|
||||
},
|
||||
{
|
||||
path: '/knowledge/:module',
|
||||
path: '/knowledge',
|
||||
component: '@/pages/add-knowledge',
|
||||
routes: [
|
||||
{
|
||||
path: '/knowledge/dataset',
|
||||
component: '@/pages/add-knowledge/components/knowledge-dataset',
|
||||
routes: [
|
||||
{
|
||||
path: '/knowledge/dataset',
|
||||
component: '@/pages/add-knowledge/components/knowledge-file',
|
||||
},
|
||||
{
|
||||
path: '/knowledge/dataset/upload',
|
||||
component:
|
||||
'@/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file',
|
||||
},
|
||||
{
|
||||
path: '/knowledge/dataset/chunk',
|
||||
component: '@/pages/add-knowledge/components/knowledge-chunk',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/knowledge/configuration',
|
||||
component: '@/pages/add-knowledge/components/knowledge-setting',
|
||||
},
|
||||
{
|
||||
path: '/knowledge/testing',
|
||||
component: '@/pages/add-knowledge/components/knowledge-search',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/chat',
|
||||
|
@ -20,6 +20,7 @@ const {
|
||||
switch_chunk,
|
||||
rm_chunk,
|
||||
retrieval_test,
|
||||
document_rename,
|
||||
} = api;
|
||||
|
||||
const methods = {
|
||||
@ -57,6 +58,10 @@ const methods = {
|
||||
url: document_rm,
|
||||
method: 'post',
|
||||
},
|
||||
document_rename: {
|
||||
url: document_rename,
|
||||
method: 'post',
|
||||
},
|
||||
document_create: {
|
||||
url: document_create,
|
||||
method: 'post',
|
||||
|
@ -33,11 +33,12 @@ export default {
|
||||
rm_chunk: `${api_host}/chunk/rm`,
|
||||
retrieval_test: `${api_host}/chunk/retrieval_test`,
|
||||
|
||||
// 上传
|
||||
// 文件管理
|
||||
upload: `${api_host}/document/upload`,
|
||||
get_document_list: `${api_host}/document/list`,
|
||||
document_change_status: `${api_host}/document/change_status`,
|
||||
document_rm: `${api_host}/document/rm`,
|
||||
document_rename: `${api_host}/document/rename`,
|
||||
document_create: `${api_host}/document/create`,
|
||||
document_change_parser: `${api_host}/document/change_parser`,
|
||||
};
|
||||
|
4
web/typings.d.ts
vendored
4
web/typings.d.ts
vendored
@ -1,2 +1,4 @@
|
||||
import 'umi/typings';
|
||||
declare module 'lodash'
|
||||
declare module 'lodash';
|
||||
|
||||
export type Nullable<T> = T | null;
|
||||
|
Loading…
x
Reference in New Issue
Block a user