### What problem does this PR solve? change language Issue link: #245 - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@@ -3,6 +3,7 @@ import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import { Checkbox, Form, Input, Modal, Space } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'umi';
|
||||
import EditTag from '../edit-tag';
|
||||
|
||||
@@ -24,6 +25,7 @@ const ChunkCreatingModal: React.FC<kFProps> = ({ doc_id, chunkId }) => {
|
||||
const [keywords, setKeywords] = useState<string[]>([]);
|
||||
const loading = useOneNamespaceEffectsLoading('chunkModel', ['create_chunk']);
|
||||
const { removeChunk } = useDeleteChunkByIds();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleCancel = () => {
|
||||
dispatch({
|
||||
@@ -87,7 +89,7 @@ const ChunkCreatingModal: React.FC<kFProps> = ({ doc_id, chunkId }) => {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={`${chunkId ? 'Edit' : 'Create'} Chunk`}
|
||||
title={`${chunkId ? t('common.edit') : t('common.create')} ${t('chunk.chunk')}`}
|
||||
open={isShowCreateModal}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
@@ -100,27 +102,27 @@ const ChunkCreatingModal: React.FC<kFProps> = ({ doc_id, chunkId }) => {
|
||||
layout={'vertical'}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="Chunk"
|
||||
label={t('chunk.chunk')}
|
||||
name="content"
|
||||
rules={[{ required: true, message: 'Please input value!' }]}
|
||||
rules={[{ required: true, message: t('chunk.chunkMessage') }]}
|
||||
>
|
||||
<Input.TextArea autoSize={{ minRows: 4, maxRows: 10 }} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<section>
|
||||
<p>Keyword*</p>
|
||||
<p>{t('chunk.keyword')} *</p>
|
||||
<EditTag tags={keywords} setTags={setKeywords} />
|
||||
</section>
|
||||
{chunkId && (
|
||||
<section>
|
||||
<p>Function*</p>
|
||||
<p>{t('chunk.function')} *</p>
|
||||
<Space size={'large'}>
|
||||
<Checkbox onChange={handleCheck} checked={checked}>
|
||||
Enabled
|
||||
{t('chunk.enabled')}
|
||||
</Checkbox>
|
||||
|
||||
<span onClick={handleRemove}>
|
||||
<DeleteOutlined /> Delete
|
||||
<DeleteOutlined /> {t('common.delete')}
|
||||
</span>
|
||||
</Space>
|
||||
</section>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ReactComponent as FilterIcon } from '@/assets/filter.svg';
|
||||
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
@@ -49,6 +50,7 @@ const ChunkToolBar = ({
|
||||
const dispatch = useDispatch();
|
||||
const knowledgeBaseId = useKnowledgeBaseId();
|
||||
const [isShowSearchBox, setIsShowSearchBox] = useState(false);
|
||||
const { t } = useTranslate('chunk');
|
||||
|
||||
const handleSelectAllCheck = useCallback(
|
||||
(e: any) => {
|
||||
@@ -95,7 +97,7 @@ const ChunkToolBar = ({
|
||||
label: (
|
||||
<>
|
||||
<Checkbox onChange={handleSelectAllCheck} checked={checked}>
|
||||
<b>Select All</b>
|
||||
<b>{t('selectAll')}</b>
|
||||
</Checkbox>
|
||||
</>
|
||||
),
|
||||
@@ -106,7 +108,7 @@ const ChunkToolBar = ({
|
||||
label: (
|
||||
<Space onClick={handleEnabledClick}>
|
||||
<CheckCircleOutlined />
|
||||
<b>Enabled Selected</b>
|
||||
<b>{t('enabledSelected')}</b>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
@@ -115,7 +117,7 @@ const ChunkToolBar = ({
|
||||
label: (
|
||||
<Space onClick={handleDisabledClick}>
|
||||
<CloseCircleOutlined />
|
||||
<b>Disabled Selected</b>
|
||||
<b>{t('disabledSelected')}</b>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
@@ -125,7 +127,7 @@ const ChunkToolBar = ({
|
||||
label: (
|
||||
<Space onClick={handleDelete}>
|
||||
<DeleteOutlined />
|
||||
<b>Delete Selected</b>
|
||||
<b>{t('deleteSelected')}</b>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
@@ -136,6 +138,7 @@ const ChunkToolBar = ({
|
||||
handleDelete,
|
||||
handleEnabledClick,
|
||||
handleDisabledClick,
|
||||
t,
|
||||
]);
|
||||
|
||||
const content = (
|
||||
@@ -151,9 +154,9 @@ const ChunkToolBar = ({
|
||||
const filterContent = (
|
||||
<Radio.Group onChange={handleFilterChange} value={available}>
|
||||
<Space direction="vertical">
|
||||
<Radio value={undefined}>All</Radio>
|
||||
<Radio value={1}>Enabled</Radio>
|
||||
<Radio value={0}>Disabled</Radio>
|
||||
<Radio value={undefined}>{t('all')}</Radio>
|
||||
<Radio value={1}>{t('enabled')}</Radio>
|
||||
<Radio value={0}>{t('disabled')}</Radio>
|
||||
</Space>
|
||||
</Radio.Group>
|
||||
);
|
||||
@@ -172,14 +175,14 @@ const ChunkToolBar = ({
|
||||
<Space>
|
||||
<Popover content={content} placement="bottom" arrow={false}>
|
||||
<Button>
|
||||
Bulk
|
||||
{t('bulk')}
|
||||
<DownOutlined />
|
||||
</Button>
|
||||
</Popover>
|
||||
{isShowSearchBox ? (
|
||||
<Input
|
||||
size="middle"
|
||||
placeholder="Search"
|
||||
placeholder={t('search')}
|
||||
prefix={<SearchOutlined />}
|
||||
allowClear
|
||||
onChange={handleSearchChange}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
} from './hooks';
|
||||
import { ChunkModelState } from './model';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styles from './index.less';
|
||||
|
||||
const Chunk = () => {
|
||||
@@ -33,6 +34,7 @@ const Chunk = () => {
|
||||
const documentInfo = useSelectDocumentInfo();
|
||||
const { handleChunkCardClick, selectedChunkId } = useHandleChunkCardClick();
|
||||
const isPdf = documentInfo.type === 'pdf';
|
||||
const { t } = useTranslation();
|
||||
|
||||
const getChunkList = useFetchChunkList();
|
||||
|
||||
@@ -86,7 +88,7 @@ const Chunk = () => {
|
||||
[],
|
||||
);
|
||||
const showSelectedChunkWarning = () => {
|
||||
message.warning('Please select chunk!');
|
||||
message.warning(t('message.pleaseSelectChunk'));
|
||||
};
|
||||
|
||||
const handleRemoveChunk = useCallback(async () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import kbService from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import { pick } from 'lodash';
|
||||
// import { delay } from '@/utils/storeUtil';
|
||||
import i18n from '@/locales/config';
|
||||
import { DvaModel } from 'umi';
|
||||
|
||||
export interface ChunkModelState extends BaseState {
|
||||
@@ -102,7 +103,7 @@ const model: DvaModel<ChunkModelState> = {
|
||||
const { data } = yield call(kbService.switch_chunk, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Modified successfully !');
|
||||
message.success(i18n.t('message.modified'));
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
|
||||
@@ -40,6 +40,7 @@ import classNames from 'classnames';
|
||||
import { ReactElement, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { Link, useNavigate } from 'umi';
|
||||
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Dragger } = Upload;
|
||||
@@ -135,6 +136,7 @@ const KnowledgeUploadFile = () => {
|
||||
const documentList = useSelectDocumentList();
|
||||
const runDocumentByIds = useRunDocument();
|
||||
const uploadDocument = useUploadDocument();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
const enabled = useMemo(() => {
|
||||
if (isUpload) {
|
||||
@@ -257,10 +259,10 @@ const KnowledgeUploadFile = () => {
|
||||
</Flex>
|
||||
<Flex justify="space-around">
|
||||
<p className={styles.selectFilesText}>
|
||||
<b>Select files</b>
|
||||
<b>{t('selectFiles')}</b>
|
||||
</p>
|
||||
<p className={styles.changeSpecificCategoryText}>
|
||||
<b>Change specific category</b>
|
||||
<b>{t('changeSpecificCategory')}</b>
|
||||
</p>
|
||||
</Flex>
|
||||
</div>
|
||||
@@ -275,13 +277,8 @@ const KnowledgeUploadFile = () => {
|
||||
<Button className={styles.uploaderButton}>
|
||||
<CloudUploadOutlined className={styles.uploaderIcon} />
|
||||
</Button>
|
||||
<p className="ant-upload-text">
|
||||
Click or drag file to this area to upload
|
||||
</p>
|
||||
<p className="ant-upload-hint">
|
||||
Support for a single or bulk upload. Strictly prohibited from
|
||||
uploading company data or other banned files.
|
||||
</p>
|
||||
<p className="ant-upload-text">{t('uploadTitle')}</p>
|
||||
<p className="ant-upload-hint">{t('uploadDescription')}</p>
|
||||
</Dragger>
|
||||
</section>
|
||||
<section className={styles.footer}>
|
||||
@@ -292,7 +289,7 @@ const KnowledgeUploadFile = () => {
|
||||
disabled={!enabled}
|
||||
size="large"
|
||||
>
|
||||
Next
|
||||
{t('next', { keyPrefix: 'common' })}
|
||||
</Button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -204,7 +204,9 @@ const KnowledgeFile = () => {
|
||||
<div className={styles.filter}>
|
||||
<Space>
|
||||
<h3>{t('total', { keyPrefix: 'common' })}</h3>
|
||||
<Tag color="purple">{total} files</Tag>
|
||||
<Tag color="purple">
|
||||
{total} {t('files')}
|
||||
</Tag>
|
||||
</Space>
|
||||
<Space>
|
||||
<Input
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BaseState } from '@/interfaces/common';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import i18n from '@/locales/config';
|
||||
import kbService, { getDocumentFile } from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import omit from 'lodash/omit';
|
||||
@@ -54,14 +55,14 @@ const model: DvaModel<KFModelState> = {
|
||||
const { data } = yield call(kbService.createKb, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Created!');
|
||||
message.success(i18n.t('message.created'));
|
||||
}
|
||||
},
|
||||
*updateKf({ payload = {} }, { call }) {
|
||||
const { data } = yield call(kbService.updateKb, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Modified!');
|
||||
message.success(i18n.t('message.modified'));
|
||||
}
|
||||
},
|
||||
*getKfDetail({ payload = {} }, { call }) {
|
||||
@@ -109,7 +110,7 @@ const model: DvaModel<KFModelState> = {
|
||||
);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Modified!');
|
||||
message.success(i18n.t('message.modified'));
|
||||
yield put({
|
||||
type: 'getKfList',
|
||||
payload: { kb_id: payload.kb_id },
|
||||
@@ -122,7 +123,7 @@ const model: DvaModel<KFModelState> = {
|
||||
});
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Deleted!');
|
||||
message.success(i18n.t('message.deleted'));
|
||||
yield put({
|
||||
type: 'getKfList',
|
||||
payload: { kb_id: payload.kb_id },
|
||||
@@ -137,7 +138,7 @@ const model: DvaModel<KFModelState> = {
|
||||
);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('rename success!');
|
||||
message.success(i18n.t('message.renamed'));
|
||||
|
||||
yield put({
|
||||
type: 'getKfList',
|
||||
@@ -156,7 +157,7 @@ const model: DvaModel<KFModelState> = {
|
||||
payload: { kb_id: payload.kb_id },
|
||||
});
|
||||
|
||||
message.success('Created!');
|
||||
message.success(i18n.t('message.created'));
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
@@ -173,7 +174,7 @@ const model: DvaModel<KFModelState> = {
|
||||
payload: { kb_id: payload.knowledgeBaseId },
|
||||
});
|
||||
}
|
||||
message.success('Operation successfully !');
|
||||
message.success(i18n.t('message.operated'));
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
@@ -189,7 +190,7 @@ const model: DvaModel<KFModelState> = {
|
||||
payload: { kb_id: payload.kb_id },
|
||||
});
|
||||
|
||||
message.success('Modified!');
|
||||
message.success(i18n.t('message.modified'));
|
||||
}
|
||||
return retcode;
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ 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';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
import { useDispatch } from 'umi';
|
||||
import { RunningStatus, RunningStatusMap } from '../constant';
|
||||
@@ -80,11 +81,14 @@ export const ParsingStatusCell = ({ record }: IProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const text = record.run;
|
||||
const runningStatus = RunningStatusMap[text];
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isRunning = isParserRunning(text);
|
||||
|
||||
const OperationIcon = iconMap[text];
|
||||
|
||||
const label = t(`knowledgeDetails.runningStatus${text}`);
|
||||
|
||||
const handleOperationIconClick = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/document_run',
|
||||
@@ -103,11 +107,11 @@ export const ParsingStatusCell = ({ record }: IProps) => {
|
||||
{isRunning ? (
|
||||
<Space>
|
||||
<Badge color={runningStatus.color} />
|
||||
{runningStatus.label}
|
||||
{label}
|
||||
<span>{(record.progress * 100).toFixed(2)}%</span>
|
||||
</Space>
|
||||
) : (
|
||||
runningStatus.label
|
||||
label
|
||||
)}
|
||||
</Tag>
|
||||
</Popover>
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
import SvgIcon from '@/components/svg-icon';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useSelectParserList } from '@/hooks/userSettingHook';
|
||||
import { Col, Divider, Empty, Row, Typography } from 'antd';
|
||||
import { useMemo } from 'react';
|
||||
import styles from './index.less';
|
||||
import { ImageMap, TextMap } from './utils';
|
||||
import { ImageMap } from './utils';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
|
||||
const parserList = useSelectParserList();
|
||||
const { t } = useTranslate('knowledgeConfiguration');
|
||||
|
||||
const item = useMemo(() => {
|
||||
const item = parserList.find((x) => x.value === chunkMethod);
|
||||
if (item) {
|
||||
return {
|
||||
title: item.label,
|
||||
description: TextMap[item.value as keyof typeof TextMap]?.description,
|
||||
description: t(item.value),
|
||||
};
|
||||
}
|
||||
return { title: '', description: '' };
|
||||
}, [parserList, chunkMethod]);
|
||||
}, [parserList, chunkMethod, t]);
|
||||
|
||||
const imageList = useMemo(() => {
|
||||
if (chunkMethod in ImageMap) {
|
||||
@@ -33,18 +35,17 @@ const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
|
||||
{imageList.length > 0 ? (
|
||||
<>
|
||||
<Title level={5} className={styles.topTitle}>
|
||||
"{item.title}" Chunking Method Description
|
||||
"{item.title}" {t('methodTitle')}
|
||||
</Title>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.description,
|
||||
}}
|
||||
></p>
|
||||
<Title level={5}>"{item.title}" Examples</Title>
|
||||
<Text>
|
||||
This visual guides is in order to make understanding easier
|
||||
for you.
|
||||
</Text>
|
||||
<Title level={5}>
|
||||
"{item.title}" {t('methodExamples')}
|
||||
</Title>
|
||||
<Text>{t('methodExamplesDescription')}</Text>
|
||||
<Row gutter={[10, 10]} className={styles.imageRow}>
|
||||
{imageList.map((x) => (
|
||||
<Col span={12} key={x}>
|
||||
@@ -56,15 +57,14 @@ const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
<Title level={5}>{item.title} Dialogue Examples</Title>
|
||||
<Title level={5}>
|
||||
{item.title} {t('dialogueExamplesTitle')}
|
||||
</Title>
|
||||
<Divider></Divider>
|
||||
</>
|
||||
) : (
|
||||
<Empty description={''} image={null}>
|
||||
<p>
|
||||
This will display a visual explanation of the knowledge base
|
||||
categories
|
||||
</p>
|
||||
<p>{t('methodEmpty')}</p>
|
||||
<SvgIcon name={'chunk-method/chunk-empty'} width={'100%'}></SvgIcon>
|
||||
</Empty>
|
||||
)}
|
||||
|
||||
@@ -59,7 +59,7 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="permission"
|
||||
label="Permissions"
|
||||
label={t('permissions')}
|
||||
tooltip={t('permissionsTip')}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
@@ -70,7 +70,7 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="embd_id"
|
||||
label="Embedding model"
|
||||
label={t('embeddingModel')}
|
||||
rules={[{ required: true }]}
|
||||
tooltip={t('embeddingModelTip')}
|
||||
>
|
||||
@@ -82,7 +82,7 @@ const ConfigurationForm = ({ form }: { form: FormInstance }) => {
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="parser_id"
|
||||
label="Chunk method"
|
||||
label={t('chunkMethod')}
|
||||
tooltip={t('chunkMethodTip')}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { IKnowledge } from '@/interfaces/database/knowledge';
|
||||
import i18n from '@/locales/config';
|
||||
import kbService from '@/services/kbService';
|
||||
import { message } from 'antd';
|
||||
import { DvaModel } from 'umi';
|
||||
@@ -32,7 +33,7 @@ const model: DvaModel<KSModelState> = {
|
||||
const { data } = yield call(kbService.createKb, payload);
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
message.success('Created!');
|
||||
message.success(i18n.t('message.created'));
|
||||
}
|
||||
return data;
|
||||
},
|
||||
@@ -41,7 +42,7 @@ const model: DvaModel<KSModelState> = {
|
||||
const { retcode } = data;
|
||||
if (retcode === 0) {
|
||||
yield put({ type: 'getKbDetail', payload: { kb_id: payload.kb_id } });
|
||||
message.success('Updated!');
|
||||
message.success(i18n.t('message.updated'));
|
||||
}
|
||||
},
|
||||
*getKbDetail({ payload = {} }, { call, put }) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
KnowledgeDatasetRouteKey,
|
||||
KnowledgeRouteKey,
|
||||
datasetRouteMap,
|
||||
routeMap,
|
||||
} from './constant';
|
||||
import styles from './index.less';
|
||||
|
||||
@@ -49,7 +48,7 @@ const KnowledgeAdding = () => {
|
||||
{t(`knowledgeDetails.${activeKey}`)}
|
||||
</Link>
|
||||
) : (
|
||||
routeMap[activeKey]
|
||||
t(`knowledgeDetails.${activeKey}`)
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user