mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-21 13:32:49 +08:00
### What problem does this PR solve? fix: #209 after saving the knowledge base configuration, jump to the dataset page feat: translate ConfigurationForm feat: translate KnowledgeTesting feat: translate document list page feat: translate knowledge list page Issue link: #209 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -42,6 +42,7 @@ import ParsingStatusCell from './parsing-status-cell';
|
||||
import RenameModal from './rename-modal';
|
||||
|
||||
import { useSetSelectedRecord } from '@/hooks/logicHooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styles from './index.less';
|
||||
|
||||
const KnowledgeFile = () => {
|
||||
@ -76,6 +77,9 @@ const KnowledgeFile = () => {
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal,
|
||||
} = useChangeDocumentParser(currentRecord.id);
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'knowledgeDetails',
|
||||
});
|
||||
|
||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||
return [
|
||||
@ -87,7 +91,7 @@ const KnowledgeFile = () => {
|
||||
<Button type="link">
|
||||
<Space>
|
||||
<FileTextOutlined />
|
||||
Local files
|
||||
{t('localFiles')}
|
||||
</Space>
|
||||
</Button>
|
||||
</div>
|
||||
@ -101,18 +105,18 @@ const KnowledgeFile = () => {
|
||||
<div>
|
||||
<Button type="link">
|
||||
<FileOutlined />
|
||||
Create empty file
|
||||
{t('emptyFiles')}
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
// disabled: true,
|
||||
},
|
||||
];
|
||||
}, [linkToUploadPage, showCreateModal]);
|
||||
}, [linkToUploadPage, showCreateModal, t]);
|
||||
|
||||
const columns: ColumnsType<IKnowledgeFile> = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: t('name'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
fixed: 'left',
|
||||
@ -133,17 +137,17 @@ const KnowledgeFile = () => {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Chunk Number',
|
||||
title: t('chunkNumber'),
|
||||
dataIndex: 'chunk_num',
|
||||
key: 'chunk_num',
|
||||
},
|
||||
{
|
||||
title: 'Upload Date',
|
||||
title: t('uploadDate'),
|
||||
dataIndex: 'create_date',
|
||||
key: 'create_date',
|
||||
},
|
||||
{
|
||||
title: 'Chunk Method',
|
||||
title: t('chunkMethod'),
|
||||
dataIndex: 'parser_id',
|
||||
key: 'parser_id',
|
||||
render: (text) => {
|
||||
@ -151,7 +155,7 @@ const KnowledgeFile = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Enabled',
|
||||
title: t('enabled'),
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
render: (_, { status, id }) => (
|
||||
@ -166,7 +170,7 @@ const KnowledgeFile = () => {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Parsing Status',
|
||||
title: t('parsingStatus'),
|
||||
dataIndex: 'run',
|
||||
key: 'run',
|
||||
render: (text, record) => {
|
||||
@ -174,7 +178,7 @@ const KnowledgeFile = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
title: t('action'),
|
||||
key: 'action',
|
||||
render: (_, record) => (
|
||||
<ParsingActionCell
|
||||
@ -194,17 +198,17 @@ const KnowledgeFile = () => {
|
||||
|
||||
return (
|
||||
<div className={styles.datasetWrapper}>
|
||||
<h3>Dataset</h3>
|
||||
<p>Hey, don't forget to adjust the chunk after adding the dataset! 😉</p>
|
||||
<h3>{t('dataset')}</h3>
|
||||
<p>{t('datasetDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<div className={styles.filter}>
|
||||
<Space>
|
||||
<h3>Total</h3>
|
||||
<h3>{t('total', { keyPrefix: 'common' })}</h3>
|
||||
<Tag color="purple">{total} files</Tag>
|
||||
</Space>
|
||||
<Space>
|
||||
<Input
|
||||
placeholder="Seach your files"
|
||||
placeholder={t('searchFiles')}
|
||||
value={searchString}
|
||||
style={{ width: 220 }}
|
||||
allowClear
|
||||
@ -214,7 +218,7 @@ const KnowledgeFile = () => {
|
||||
|
||||
<Dropdown menu={{ items: actionItems }} trigger={['click']}>
|
||||
<Button type="primary" icon={<PlusOutlined />}>
|
||||
Add file
|
||||
{t('addFile')}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useShowDeleteConfirm } from '@/hooks/commonHooks';
|
||||
import { useShowDeleteConfirm, useTranslate } from '@/hooks/commonHooks';
|
||||
import { useRemoveDocument } from '@/hooks/documentHooks';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { api_host } from '@/utils/api';
|
||||
@ -29,7 +29,7 @@ const ParsingActionCell = ({
|
||||
}: IProps) => {
|
||||
const documentId = record.id;
|
||||
const isRunning = isParserRunning(record.run);
|
||||
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const removeDocument = useRemoveDocument(documentId);
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
|
||||
@ -65,7 +65,7 @@ const ParsingActionCell = ({
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link" onClick={onShowChangeParserModal}>
|
||||
Chunk Method
|
||||
{t('chunkMethod')}
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
@ -83,7 +83,7 @@ const ParsingActionCell = ({
|
||||
<ToolOutlined size={20} />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Tooltip title="Rename">
|
||||
<Tooltip title={t('rename', { keyPrefix: 'common' })}>
|
||||
<Button
|
||||
type="text"
|
||||
disabled={isRunning}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ReactComponent as RefreshIcon } from '@/assets/svg/refresh.svg';
|
||||
import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
|
||||
@ -22,6 +23,8 @@ interface IProps {
|
||||
}
|
||||
|
||||
const PopoverContent = ({ record }: IProps) => {
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
const replaceText = (text: string) => {
|
||||
// Remove duplicate \n
|
||||
const nextText = text.replace(/(\n)\1+/g, '$1');
|
||||
@ -44,17 +47,17 @@ const PopoverContent = ({ record }: IProps) => {
|
||||
const items: DescriptionsProps['items'] = [
|
||||
{
|
||||
key: 'process_begin_at',
|
||||
label: 'Process Begin At',
|
||||
label: t('processBeginAt'),
|
||||
children: record.process_begin_at,
|
||||
},
|
||||
{
|
||||
key: 'process_duation',
|
||||
label: 'Process Duration',
|
||||
label: t('processDuration'),
|
||||
children: record.process_duation,
|
||||
},
|
||||
{
|
||||
key: 'progress_msg',
|
||||
label: 'Progress Msg',
|
||||
label: t('progressMsg'),
|
||||
children: replaceText(record.progress_msg.trim()),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -17,7 +18,7 @@ const RenameModal = ({
|
||||
hideModal,
|
||||
}: IProps) => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { t } = useTranslate('common');
|
||||
type FieldType = {
|
||||
name?: string;
|
||||
};
|
||||
@ -43,7 +44,7 @@ const RenameModal = ({
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Rename"
|
||||
title={t('rename')}
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={hideModal}
|
||||
@ -60,9 +61,9 @@ const RenameModal = ({
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="Name"
|
||||
label={t('name')}
|
||||
name="name"
|
||||
rules={[{ required: true, message: 'Please input name!' }]}
|
||||
rules={[{ required: true, message: t('namePlaceholder') }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
@ -7,40 +7,27 @@ import {
|
||||
} from './hooks';
|
||||
|
||||
import MaxTokenNumber from '@/components/max-token-number';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { FormInstance } from 'antd/lib';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
const { submitKnowledgeConfiguration, submitLoading } =
|
||||
useSubmitKnowledgeConfiguration();
|
||||
const { submitKnowledgeConfiguration, submitLoading, navigateToDataset } =
|
||||
useSubmitKnowledgeConfiguration(form);
|
||||
const { parserList, embeddingModelOptions, disabled } =
|
||||
useFetchKnowledgeConfigurationOnMount(form);
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
return (
|
||||
<Form
|
||||
form={form}
|
||||
name="validateOnly"
|
||||
layout="vertical"
|
||||
autoComplete="off"
|
||||
onFinish={submitKnowledgeConfiguration}
|
||||
onFinishFailed={onFinishFailed}
|
||||
>
|
||||
<Form.Item
|
||||
name="name"
|
||||
label="Knowledge base name"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Form form={form} name="validateOnly" layout="vertical" autoComplete="off">
|
||||
<Form.Item name="name" label={t('name')} rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="avatar"
|
||||
label="Knowledge base photo"
|
||||
label={t('photo')}
|
||||
valuePropName="fileList"
|
||||
getValueFromEvent={normFile}
|
||||
>
|
||||
@ -52,43 +39,43 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
>
|
||||
<button style={{ border: 0, background: 'none' }} type="button">
|
||||
<PlusOutlined />
|
||||
<div style={{ marginTop: 8 }}>Upload</div>
|
||||
<div style={{ marginTop: 8 }}>{t('upload')}</div>
|
||||
</button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
<Form.Item name="description" label="Description">
|
||||
<Form.Item name="description" label={t('description')}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Language"
|
||||
label={t('language')}
|
||||
name="language"
|
||||
initialValue={'English'}
|
||||
rules={[{ required: true, message: 'Please input your language!' }]}
|
||||
rules={[{ required: true, message: t('languageMessage') }]}
|
||||
>
|
||||
<Select placeholder="select your language">
|
||||
<Option value="English">English</Option>
|
||||
<Option value="Chinese">Chinese</Option>
|
||||
<Select placeholder={t('languagePlaceholder')}>
|
||||
<Option value="English">{t('english')}</Option>
|
||||
<Option value="Chinese">{t('chinese')}</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="permission"
|
||||
label="Permissions"
|
||||
tooltip="If the permission is 'Team', all the team member can manipulate the knowledgebase."
|
||||
tooltip={t('permissionsTip')}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio value="me">Only me</Radio>
|
||||
<Radio value="team">Team</Radio>
|
||||
<Radio value="me">{t('me')}</Radio>
|
||||
<Radio value="team">{t('team')}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="embd_id"
|
||||
label="Embedding model"
|
||||
rules={[{ required: true }]}
|
||||
tooltip="The embedding model used to embedding chunks. It's unchangable once the knowledgebase has chunks. You need to delete all the chunks if you want to change it."
|
||||
tooltip={t('embeddingModelTip')}
|
||||
>
|
||||
<Select
|
||||
placeholder="Please select a embedding model"
|
||||
placeholder={t('embeddingModelPlaceholder')}
|
||||
options={embeddingModelOptions}
|
||||
disabled={disabled}
|
||||
></Select>
|
||||
@ -96,10 +83,10 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
<Form.Item
|
||||
name="parser_id"
|
||||
label="Chunk method"
|
||||
tooltip="The instruction is at right."
|
||||
tooltip={t('chunkMethodTip')}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Select placeholder="Please select a chunk method" disabled={disabled}>
|
||||
<Select placeholder={t('chunkMethodPlaceholder')} disabled={disabled}>
|
||||
{parserList.map((x) => (
|
||||
<Option value={x.value} key={x.value}>
|
||||
{x.label}
|
||||
@ -120,16 +107,16 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
<Form.Item>
|
||||
<div className={styles.buttonWrapper}>
|
||||
<Space>
|
||||
<Button htmlType="reset" size={'middle'}>
|
||||
Cancel
|
||||
<Button size={'middle'} onClick={navigateToDataset}>
|
||||
{t('cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
size={'middle'}
|
||||
loading={submitLoading}
|
||||
onClick={submitKnowledgeConfiguration}
|
||||
>
|
||||
Save
|
||||
{t('save')}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
useUpdateKnowledge,
|
||||
} from '@/hooks/knowledgeHook';
|
||||
import { useFetchLlmList, useSelectLlmOptions } from '@/hooks/llmHooks';
|
||||
import { useNavigateToDataset } from '@/hooks/routeHook';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import {
|
||||
useFetchTenantInfo,
|
||||
@ -20,24 +21,24 @@ import pick from 'lodash/pick';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { LlmModelType } from '../../constant';
|
||||
|
||||
export const useSubmitKnowledgeConfiguration = () => {
|
||||
export const useSubmitKnowledgeConfiguration = (form: FormInstance) => {
|
||||
const save = useUpdateKnowledge();
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
const submitLoading = useOneNamespaceEffectsLoading('kSModel', ['updateKb']);
|
||||
const navigateToDataset = useNavigateToDataset();
|
||||
|
||||
const submitKnowledgeConfiguration = useCallback(
|
||||
async (values: any) => {
|
||||
const avatar = await getBase64FromUploadFileList(values.avatar);
|
||||
save({
|
||||
...values,
|
||||
avatar,
|
||||
kb_id: knowledgeBaseId,
|
||||
});
|
||||
},
|
||||
[save, knowledgeBaseId],
|
||||
);
|
||||
const submitKnowledgeConfiguration = useCallback(async () => {
|
||||
const values = await form.validateFields();
|
||||
const avatar = await getBase64FromUploadFileList(values.avatar);
|
||||
save({
|
||||
...values,
|
||||
avatar,
|
||||
kb_id: knowledgeBaseId,
|
||||
});
|
||||
navigateToDataset();
|
||||
}, [save, knowledgeBaseId, form, navigateToDataset]);
|
||||
|
||||
return { submitKnowledgeConfiguration, submitLoading };
|
||||
return { submitKnowledgeConfiguration, submitLoading, navigateToDataset };
|
||||
};
|
||||
|
||||
export const useFetchKnowledgeConfigurationOnMount = (form: FormInstance) => {
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
useSelectKnowledgeDetailsLoading,
|
||||
} from './hooks';
|
||||
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Title } = Typography;
|
||||
@ -13,11 +14,14 @@ const { Title } = Typography;
|
||||
const Configuration = () => {
|
||||
const loading = useSelectKnowledgeDetailsLoading();
|
||||
const { form, chunkMethod } = useHandleChunkMethodChange();
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
return (
|
||||
<div className={styles.configurationWrapper}>
|
||||
<Title level={5}>Configuration</Title>
|
||||
<p>Update your knowledge base details especially parsing method here.</p>
|
||||
<Title level={5}>
|
||||
{t('configuration', { keyPrefix: 'knowledgeDetails' })}
|
||||
</Title>
|
||||
<p>{t('titleDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<Spin spinning={loading}>
|
||||
<Row gutter={32}>
|
||||
|
||||
@ -8,8 +8,9 @@ import { getWidth } from '@/utils';
|
||||
import { Avatar, Menu, MenuProps, Space } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate, useSelector } from 'umi';
|
||||
import { KnowledgeRouteKey, routeMap } from '../../constant';
|
||||
import { KnowledgeRouteKey } from '../../constant';
|
||||
import styles from './index.less';
|
||||
|
||||
const KnowledgeSidebar = () => {
|
||||
@ -23,6 +24,7 @@ const KnowledgeSidebar = () => {
|
||||
|
||||
const [windowWidth, setWindowWidth] = useState(getWidth());
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleSelect: MenuProps['onSelect'] = (e) => {
|
||||
navigate(`/knowledge/${e.key}?id=${id}`);
|
||||
@ -32,7 +34,7 @@ const KnowledgeSidebar = () => {
|
||||
|
||||
const getItem = useCallback(
|
||||
(
|
||||
label: React.ReactNode,
|
||||
label: string,
|
||||
key: React.Key,
|
||||
icon?: React.ReactNode,
|
||||
disabled?: boolean,
|
||||
@ -43,28 +45,28 @@ const KnowledgeSidebar = () => {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label,
|
||||
label: t(`knowledgeDetails.${label}`),
|
||||
type,
|
||||
disabled,
|
||||
} as MenuItem;
|
||||
},
|
||||
[],
|
||||
[t],
|
||||
);
|
||||
|
||||
const items: MenuItem[] = useMemo(() => {
|
||||
return [
|
||||
getItem(
|
||||
routeMap[KnowledgeRouteKey.Dataset], // TODO: Change icon color when selected
|
||||
KnowledgeRouteKey.Dataset, // TODO: Change icon color when selected
|
||||
KnowledgeRouteKey.Dataset,
|
||||
<DatasetIcon />,
|
||||
),
|
||||
getItem(
|
||||
routeMap[KnowledgeRouteKey.Testing],
|
||||
KnowledgeRouteKey.Testing,
|
||||
KnowledgeRouteKey.Testing,
|
||||
<TestingIcon />,
|
||||
),
|
||||
getItem(
|
||||
routeMap[KnowledgeRouteKey.Configuration],
|
||||
KnowledgeRouteKey.Configuration,
|
||||
KnowledgeRouteKey.Configuration,
|
||||
<ConfigurationIcon />,
|
||||
),
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import SimilaritySlider from '@/components/similarity-slider';
|
||||
import { Button, Card, Divider, Flex, Form, Input, Slider, Tag } from 'antd';
|
||||
import { Button, Card, Divider, Flex, Form, Input, Slider } from 'antd';
|
||||
import { FormInstance } from 'antd/lib';
|
||||
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import styles from './index.less';
|
||||
|
||||
@ -22,6 +23,7 @@ const TestingControl = ({ form, handleTesting }: IProps) => {
|
||||
const loading = useOneNamespaceEffectsLoading('testingModel', [
|
||||
'testDocumentChunk',
|
||||
]);
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
const buttonDisabled =
|
||||
!question || (typeof question === 'string' && question.trim() === '');
|
||||
@ -29,9 +31,9 @@ const TestingControl = ({ form, handleTesting }: IProps) => {
|
||||
return (
|
||||
<section className={styles.testingControlWrapper}>
|
||||
<div>
|
||||
<b>Retrieval testing</b>
|
||||
<b>{t('testing')}</b>
|
||||
</div>
|
||||
<p>Final step! After success, leave the rest to Infiniflow AI.</p>
|
||||
<p>{t('testingDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<section>
|
||||
<Form
|
||||
@ -46,22 +48,18 @@ const TestingControl = ({ form, handleTesting }: IProps) => {
|
||||
<Form.Item<FieldType>
|
||||
label="Top K"
|
||||
name={'top_k'}
|
||||
tooltip="For the computaion cost, not all the retrieved chunk will be computed vector cosine similarity with query.
|
||||
The bigger the 'Top K' is, the higher the recall rate is, the slower the retrieval speed is."
|
||||
tooltip={t('topKTip')}
|
||||
>
|
||||
<Slider marks={{ 0: 0, 2048: 2048 }} max={2048} />
|
||||
</Form.Item>
|
||||
<Card size="small" title="Test text">
|
||||
<Card size="small" title={t('testText')}>
|
||||
<Form.Item<FieldType>
|
||||
name={'question'}
|
||||
rules={[
|
||||
{ required: true, message: 'Please input your question!' },
|
||||
]}
|
||||
rules={[{ required: true, message: t('testTextPlaceholder') }]}
|
||||
>
|
||||
<Input.TextArea autoSize={{ minRows: 8 }}></Input.TextArea>
|
||||
</Form.Item>
|
||||
<Flex justify={'space-between'}>
|
||||
<Tag>10/200</Tag>
|
||||
<Flex justify={'end'}>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
@ -69,7 +67,7 @@ const TestingControl = ({ form, handleTesting }: IProps) => {
|
||||
disabled={buttonDisabled}
|
||||
loading={loading}
|
||||
>
|
||||
Testing
|
||||
{t('testingLabel')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ReactComponent as SelectedFilesCollapseIcon } from '@/assets/svg/selected-files-collapse.svg';
|
||||
import Image from '@/components/image';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { ITestingChunk } from '@/interfaces/database/knowledge';
|
||||
import {
|
||||
Card,
|
||||
@ -10,11 +11,13 @@ import {
|
||||
Popover,
|
||||
Space,
|
||||
} from 'antd';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
import { TestingModelState } from '../model';
|
||||
import styles from './index.less';
|
||||
import SelectFiles from './select-files';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
const similarityList: Array<{ field: keyof ITestingChunk; label: string }> = [
|
||||
{ field: 'similarity', label: 'Hybrid Similarity' },
|
||||
{ field: 'term_similarity', label: 'Term Similarity' },
|
||||
@ -22,6 +25,7 @@ const similarityList: Array<{ field: keyof ITestingChunk; label: string }> = [
|
||||
];
|
||||
|
||||
const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
return (
|
||||
<Flex gap={10}>
|
||||
{similarityList.map((x) => (
|
||||
@ -29,7 +33,7 @@ const ChunkTitle = ({ item }: { item: ITestingChunk }) => {
|
||||
<span className={styles.similarityCircle}>
|
||||
{((item[x.field] as number) * 100).toFixed(2)}
|
||||
</span>
|
||||
<span className={styles.similarityText}>{x.label}</span>
|
||||
<span className={styles.similarityText}>{t(camelCase(x.field))}</span>
|
||||
</Space>
|
||||
))}
|
||||
</Flex>
|
||||
@ -49,6 +53,7 @@ const TestingResult = ({ handleTesting }: IProps) => {
|
||||
selectedDocumentIds,
|
||||
}: TestingModelState = useSelector((state: any) => state.testingModel);
|
||||
const dispatch = useDispatch();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
const onChange: PaginationProps['onChange'] = (pageNumber, pageSize) => {
|
||||
console.log('Page: ', pageNumber, pageSize);
|
||||
@ -75,13 +80,15 @@ const TestingResult = ({ handleTesting }: IProps) => {
|
||||
align="center"
|
||||
className={styles.selectFilesTitle}
|
||||
>
|
||||
<span>
|
||||
{selectedDocumentIds?.length ?? 0}/{documents.length} Files
|
||||
Selected
|
||||
</span>
|
||||
<Space>
|
||||
<span>
|
||||
{selectedDocumentIds?.length ?? 0}/{documents.length}
|
||||
</span>
|
||||
{t('filesSelected')}
|
||||
</Space>
|
||||
<Space size={52}>
|
||||
<b>Hits</b>
|
||||
<b>View</b>
|
||||
<b>{t('hits')}</b>
|
||||
<b>{t('view')}</b>
|
||||
</Space>
|
||||
</Flex>
|
||||
),
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
import { Breadcrumb } from 'antd';
|
||||
import { ItemType } from 'antd/es/breadcrumb/Breadcrumb';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link, Outlet, useDispatch, useLocation } from 'umi';
|
||||
import Siderbar from './components/knowledge-sidebar';
|
||||
import {
|
||||
@ -21,6 +22,7 @@ const KnowledgeAdding = () => {
|
||||
const dispatch = useDispatch();
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const activeKey: KnowledgeRouteKey =
|
||||
(useSecondPathName() as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset;
|
||||
@ -33,14 +35,18 @@ const KnowledgeAdding = () => {
|
||||
const breadcrumbItems: ItemType[] = useMemo(() => {
|
||||
const items: ItemType[] = [
|
||||
{
|
||||
title: <a onClick={() => gotoList('/knowledge')}>Knowledge Base</a>,
|
||||
title: (
|
||||
<a onClick={() => gotoList('/knowledge')}>
|
||||
{t('header.knowledgeBase')}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: datasetActiveKey ? (
|
||||
<Link
|
||||
to={`/knowledge/${KnowledgeRouteKey.Dataset}?id=${knowledgeBaseId}`}
|
||||
>
|
||||
{routeMap[activeKey]}
|
||||
{t(`knowledgeDetails.${activeKey}`)}
|
||||
</Link>
|
||||
) : (
|
||||
routeMap[activeKey]
|
||||
@ -55,7 +61,7 @@ const KnowledgeAdding = () => {
|
||||
}
|
||||
|
||||
return items;
|
||||
}, [activeKey, datasetActiveKey, gotoList, knowledgeBaseId]);
|
||||
}, [activeKey, datasetActiveKey, gotoList, knowledgeBaseId, t]);
|
||||
|
||||
useEffect(() => {
|
||||
const search: string = location.search.slice(1);
|
||||
|
||||
Reference in New Issue
Block a user