feat:knowledge ui upgrade
This commit is contained in:
26
web/src/assets/images/CloudUploadOutlined.svg
Normal file
26
web/src/assets/images/CloudUploadOutlined.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>编组 12</title>
|
||||||
|
<g id="空间里层页面优化" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="工作台-知识库-创建数据集-本地文件" transform="translate(-816, -184)">
|
||||||
|
<g id="上传" transform="translate(252, 148)">
|
||||||
|
<g id="编组-13" transform="translate(16, 16)">
|
||||||
|
<g id="编组-12" transform="translate(548, 20)">
|
||||||
|
<g id="编组-55" transform="translate(5, 2)">
|
||||||
|
<path d="M4,0 L18.9462071,0 L18.9462071,0 L29,10 L29,34 C29,36.209139 27.209139,38 25,38 L4,38 C1.790861,38 0,36.209139 0,34 L0,4 C0,1.790861 1.790861,4.4408921e-16 4,0 Z" id="矩形" fill="#EBEBEB"></path>
|
||||||
|
<path d="M19,0 L29,10 L21,10 C19.8954305,10 19,9.1045695 19,8 L19,0 L19,0 Z" id="矩形" fill="#A8A9AA"></path>
|
||||||
|
<g id="编组-56" transform="translate(18, 23)">
|
||||||
|
<circle id="椭圆形" fill="#171719" cx="11" cy="11" r="11"></circle>
|
||||||
|
<g id="编组-54" transform="translate(6, 6)" stroke="#FFFFFF" stroke-linecap="round">
|
||||||
|
<path d="M10,6 L10,7.5 C10,8.88071187 8.88071187,10 7.5,10 L2.5,10 C1.11928813,10 0,8.88071187 0,7.5 L0,6 L0,6" id="路径"></path>
|
||||||
|
<line x1="5" y1="0.08499952" x2="5" y2="6.99635859" id="路径-24"></line>
|
||||||
|
<polyline id="路径-25" stroke-linejoin="round" points="2 3 4.98005548 6.08298138e-18 8 3"></polyline>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -240,10 +240,10 @@ const UploadFiles = forwardRef<UploadFilesRef, UploadFilesProps>(({
|
|||||||
|
|
||||||
if (isCanDrag) {
|
if (isCanDrag) {
|
||||||
return (
|
return (
|
||||||
<div className="rb:mb-6 rb:w-full">
|
<div className="rb:mb-6 rb:w-full rb:border rb:border-dashed rb:border-gray-900 rb:rounded-xl">
|
||||||
<Dragger {...uploadProps} style={{ height: '270px' }}>
|
<Dragger {...uploadProps} style={{ height: '270px' }}>
|
||||||
<div className="rb:flex rb:justify-center rb:flex-col rb:items-center">
|
<div className="rb:flex rb:justify-center rb:flex-col rb:items-center">
|
||||||
<div className="rb:size-12 rb:bg-cover rb:bg-[url('@/assets/images/CloudUploadOutlined.png')]"></div>
|
<div className="rb:size-12 rb:bg-cover rb:bg-[url('@/assets/images/CloudUploadOutlined.svg')]"></div>
|
||||||
{(!isAutoUpload || !hasProgress && (!fileList || !fileList.length)) &&
|
{(!isAutoUpload || !hasProgress && (!fileList || !fileList.length)) &&
|
||||||
<>
|
<>
|
||||||
<div className="rb:text-base rb:text-[14px] rb:font-medium rb:flex rb:items-center rb:mt-2 rb:leading-5">
|
<div className="rb:text-base rb:text-[14px] rb:font-medium rb:flex rb:items-center rb:mt-2 rb:leading-5">
|
||||||
|
|||||||
@@ -630,6 +630,7 @@ export const en = {
|
|||||||
documentInfo: 'Document Information',
|
documentInfo: 'Document Information',
|
||||||
documentPreview:'Document Preview',
|
documentPreview:'Document Preview',
|
||||||
type: 'Type',
|
type: 'Type',
|
||||||
|
viewBasicInfo: 'View Basic Information',
|
||||||
permission_id: 'Permission',
|
permission_id: 'Permission',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
created_at: 'Created At',
|
created_at: 'Created At',
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ export const zh = {
|
|||||||
documentInfo: '文档信息',
|
documentInfo: '文档信息',
|
||||||
documentPreview: '文档预览',
|
documentPreview: '文档预览',
|
||||||
type: '类型',
|
type: '类型',
|
||||||
|
viewBasicInfo:'查看基本信息',
|
||||||
permission_id: '权限',
|
permission_id: '权限',
|
||||||
status: '状态',
|
status: '状态',
|
||||||
created_at: '创建时间',
|
created_at: '创建时间',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useMemo,useRef, useState, useEffect } from 'react';
|
|||||||
import { Button, Flex, Radio, Steps, Modal, Input, Spin, message, Checkbox, Select, Form, Progress} from 'antd';
|
import { Button, Flex, Radio, Steps, Modal, Input, Spin, message, Checkbox, Select, Form, Progress} from 'antd';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import './Private.css';
|
||||||
import Table, { type TableRef } from '@/components/Table'
|
import Table, { type TableRef } from '@/components/Table'
|
||||||
import type { AnyObject } from 'antd/es/_util/type';
|
import type { AnyObject } from 'antd/es/_util/type';
|
||||||
import type { UploadFileResponse,KnowledgeBaseDocumentData } from '@/views/KnowledgeBase/types';
|
import type { UploadFileResponse,KnowledgeBaseDocumentData } from '@/views/KnowledgeBase/types';
|
||||||
@@ -32,7 +33,7 @@ const { TextArea } = Input;
|
|||||||
};
|
};
|
||||||
const getActiveRadioStyle = (active: boolean): React.CSSProperties => ({
|
const getActiveRadioStyle = (active: boolean): React.CSSProperties => ({
|
||||||
...radioWrapperBaseStyle,
|
...radioWrapperBaseStyle,
|
||||||
border: active ? '1px solid #1677ff' : radioWrapperBaseStyle.border,
|
border: active ? '1px solid #171719' : radioWrapperBaseStyle.border,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -549,7 +550,7 @@ const CreateDataset = () => {
|
|||||||
<>
|
<>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
|
|
||||||
<div className='rb:p-6 rb:pt-2 rb:h-full'>
|
<div className='rb:p-3 rb:pt-2 rb:h-full rb:flex rb:flex-col'>
|
||||||
{/* <Typography.Title level={4} className='rb:!m-0 rb:!mb-4'>
|
{/* <Typography.Title level={4} className='rb:!m-0 rb:!mb-4'>
|
||||||
{t('knowledgeBase.createA') + ' ' + t('knowledgeBase.dataset')}
|
{t('knowledgeBase.createA') + ' ' + t('knowledgeBase.dataset')}
|
||||||
</Typography.Title> */}
|
</Typography.Title> */}
|
||||||
@@ -557,298 +558,299 @@ const CreateDataset = () => {
|
|||||||
<img src={exitIcon} alt='exit' className='rb:w-4 rb:h-4' />
|
<img src={exitIcon} alt='exit' className='rb:w-4 rb:h-4' />
|
||||||
<span className='rb:text-gray-500 rb:text-sm'>{t('common.exit')}</span>
|
<span className='rb:text-gray-500 rb:text-sm'>{t('common.exit')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='rb:px-24 rb:py-5 rb:bg-[#FBFDFF] rb:rounded-lg rb:border rb:border-[#DFE4ED]'>
|
<div className='rb:px-24 rb:py-5 rb:bg-white rb:rounded-lg'>
|
||||||
<Steps current={current} items={steps} />
|
<Steps current={current} items={steps} className="custom-steps" />
|
||||||
</div>
|
</div>
|
||||||
|
<div className='rb:bg-white rb:rounded-lg rb:flex-1 rb:mt-3'>
|
||||||
|
|
||||||
{current === 0 && (
|
{current === 0 && (
|
||||||
<div className='rb:flex rb:w-full rb:mt-10'>
|
<div className='rb:flex rb:w-full rb:p-6'>
|
||||||
{source && source === 'local' && (
|
{source && source === 'local' && (
|
||||||
<UploadFiles
|
<UploadFiles
|
||||||
ref={uploadRef}
|
ref={uploadRef}
|
||||||
isCanDrag={true}
|
isCanDrag={true}
|
||||||
fileSize={100}
|
fileSize={100}
|
||||||
multiple={true}
|
multiple={true}
|
||||||
maxCount={99}
|
maxCount={99}
|
||||||
fileType={fileType}
|
fileType={fileType}
|
||||||
customRequest={handleUpload}
|
customRequest={handleUpload}
|
||||||
onChange={(fileList) => {
|
onChange={(fileList) => {
|
||||||
console.log('File list changed:', fileList);
|
console.log('File list changed:', fileList);
|
||||||
}}
|
}}
|
||||||
onRemove={async (file) => {
|
onRemove={async (file) => {
|
||||||
// 如果文件正在上传,取消上传
|
// 如果文件正在上传,取消上传
|
||||||
const fileUid = file.uid;
|
const fileUid = file.uid;
|
||||||
const abortController = abortControllersRef.current.get(fileUid);
|
const abortController = abortControllersRef.current.get(fileUid);
|
||||||
if (abortController) {
|
if (abortController) {
|
||||||
abortController.abort();
|
abortController.abort();
|
||||||
abortControllersRef.current.delete(fileUid);
|
abortControllersRef.current.delete(fileUid);
|
||||||
console.log('Upload cancelled:', (file as any).name);
|
console.log('Upload cancelled:', (file as any).name);
|
||||||
// 取消上传后直接返回 true,允许移除文件
|
// 取消上传后直接返回 true,允许移除文件
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only delete server file when file upload was successful (has response.id)
|
|
||||||
if (file.response?.id) {
|
|
||||||
try {
|
|
||||||
await deleteDocument(file.response.id);
|
|
||||||
setRechunkFileIds(prev => prev.filter(id => id !== file.response.id));
|
|
||||||
console.log('Server file deleted:', file.response.id);
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to delete file:', error);
|
|
||||||
messageApi.error(t('common.deleteFailed') || 'Failed to delete file');
|
|
||||||
return false; // Don't remove file when deletion fails
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Only delete server file when file upload was successful (has response.id)
|
||||||
// Also allow removal in other cases (such as failed uploads)
|
if (file.response?.id) {
|
||||||
return true;
|
try {
|
||||||
}} />
|
await deleteDocument(file.response.id);
|
||||||
)}
|
setRechunkFileIds(prev => prev.filter(id => id !== file.response.id));
|
||||||
{source && source === 'link' && (
|
console.log('Server file deleted:', file.response.id);
|
||||||
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'>
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to delete file:', error);
|
||||||
|
messageApi.error(t('common.deleteFailed') || 'Failed to delete file');
|
||||||
|
return false; // Don't remove file when deletion fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also allow removal in other cases (such as failed uploads)
|
||||||
|
return true;
|
||||||
|
}} />
|
||||||
|
)}
|
||||||
|
{source && source === 'link' && (
|
||||||
|
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'>
|
||||||
|
|
||||||
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
||||||
{t('knowledgeBase.webLink')}
|
{t('knowledgeBase.webLink')}
|
||||||
</div>
|
</div>
|
||||||
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} />
|
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} />
|
||||||
<div className='rb:text-sm rb:text-gray-500 rb:mt-3'>
|
<div className='rb:text-sm rb:text-gray-500 rb:mt-3'>
|
||||||
{t('knowledgeBase.webLinkDesc',{count: 5})}
|
{t('knowledgeBase.webLinkDesc',{count: 5})}
|
||||||
</div>
|
</div>
|
||||||
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
|
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
|
||||||
{t('knowledgeBase.selectorTutorial')}
|
{t('knowledgeBase.selectorTutorial')}
|
||||||
</div>
|
</div>
|
||||||
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
|
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{source && source === 'text' && (
|
{source && source === 'text' && (
|
||||||
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'>
|
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'>
|
||||||
<Form form={form} layout="vertical">
|
<Form form={form} layout="vertical">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="title"
|
name="title"
|
||||||
label={t('knowledgeBase.title')}
|
label={t('knowledgeBase.title')}
|
||||||
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterTitle') }]}
|
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterTitle') }]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('knowledgeBase.pleaseEnterTitle')} />
|
<Input placeholder={t('knowledgeBase.pleaseEnterTitle')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="content"
|
name="content"
|
||||||
label={t('knowledgeBase.customContent')}
|
label={t('knowledgeBase.customContent')}
|
||||||
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterContent') }]}
|
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterContent') }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
placeholder={t('knowledgeBase.pleaseEnterContent')}
|
placeholder={t('knowledgeBase.pleaseEnterContent')}
|
||||||
rows={8}
|
rows={8}
|
||||||
showCount
|
showCount
|
||||||
maxLength={5000}
|
maxLength={5000}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
{/* <div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
{/* <div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
||||||
{t('knowledgeBase.customText')}
|
{t('knowledgeBase.customText')}
|
||||||
</div>
|
</div>
|
||||||
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
|
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
|
||||||
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
|
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
|
||||||
{t('knowledgeBase.customContent')}
|
{t('knowledgeBase.customContent')}
|
||||||
</div>
|
</div>
|
||||||
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} /> */}
|
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} /> */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{current === 1 && (
|
{current === 1 && (
|
||||||
<div className='rb:flex rb:flex-col rb:mt-10 rb:px-40'>
|
<div className='rb:flex rb:flex-col rb:py-6 rb:px-40'>
|
||||||
{rechunkFileIds.length > 0 && (
|
{rechunkFileIds.length > 0 && (
|
||||||
<div className='rb:bg-[#F0F3F8] rb:border rb:border-[#DFE4ED] rb:rounded rb:px-3 rb:py-2 rb:mb-4 rb:text-xs rb:text-gray-600 rb:flex rb:flex-wrap rb:gap-2'>
|
<div className='rb:bg-[#F0F3F8] rb:border rb:border-[#DFE4ED] rb:rounded rb:px-3 rb:py-2 rb:mb-4 rb:text-xs rb:text-gray-600 rb:flex rb:flex-wrap rb:gap-2'>
|
||||||
<span className='rb:text-gray-700 rb:font-medium'>{t('knowledgeBase.rechunking')}:</span>
|
<span className='rb:text-gray-700 rb:font-medium'>{t('knowledgeBase.rechunking')}:</span>
|
||||||
{rechunkFileIds.map((id) => (
|
{rechunkFileIds.map((id) => (
|
||||||
<span key={id} className='rb:px-2 rb:py-0.5 rb:bg-white rb:border rb:border-[#DFE4ED] rb:rounded'>{id}</span>
|
<span key={id} className='rb:px-2 rb:py-0.5 rb:bg-white rb:border rb:border-[#DFE4ED] rb:rounded'>{id}</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className='rb:text-base rb:font-medium rb:text-gray-800 rb:mt-4'>
|
|
||||||
{t('knowledgeBase.fileParsingSettings')}
|
|
||||||
</div>
|
|
||||||
<div className='rb:mt-4'>
|
|
||||||
<div
|
|
||||||
className={`rb:flex rb:items-center rb:w-full rb:border rb:rounded-lg rb:p-4 rb:cursor-pointer ${
|
|
||||||
pdfEnhancementEnabled ? 'rb:border-blue-500' : 'rb:border-gray-300'
|
|
||||||
}`}
|
|
||||||
// onClick={() => setPdfEnhancementEnabled(!pdfEnhancementEnabled)}
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
checked={pdfEnhancementEnabled}
|
|
||||||
onChange={(e) => setPdfEnhancementEnabled(e.target.checked)}
|
|
||||||
className='rb:mr-3'
|
|
||||||
/>
|
|
||||||
<span className='rb:text-base rb:font-medium rb:text-gray-800 rb:pl-[22px]'>
|
|
||||||
{t('knowledgeBase.pdfEnhancementAnalysis')}
|
|
||||||
</span>
|
|
||||||
{pdfEnhancementEnabled && (
|
|
||||||
<div className='rb:ml-10'>
|
|
||||||
<Select
|
|
||||||
value={pdfEnhancementMethod}
|
|
||||||
onChange={(value) => setPdfEnhancementMethod(value)}
|
|
||||||
className='rb:w-48'
|
|
||||||
options={[
|
|
||||||
{ value: 'deepdoc', label: 'DeepDoc' },
|
|
||||||
{ value: 'mineru', label: 'MinerU' },
|
|
||||||
{ value: 'textln', label: 'TextLN' }
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div className='rb:text-base rb:font-medium rb:text-gray-800 rb:mt-4'>
|
||||||
|
{t('knowledgeBase.fileParsingSettings')}
|
||||||
</div>
|
</div>
|
||||||
|
<div className='rb:mt-4'>
|
||||||
</div>
|
<div
|
||||||
<div className='rb:text-base rb:font-medium rb:text-gray-800 rb:mt-6'>
|
className={`rb:flex rb:items-center rb:w-full rb:border rb:rounded-lg rb:p-4 rb:cursor-pointer ${
|
||||||
{t('knowledgeBase.dataProcessingSettings')}
|
pdfEnhancementEnabled ? 'rb:border-gray-900' : 'rb:border-gray-300'
|
||||||
</div>
|
}`}
|
||||||
<div className='rb:font-medium rb:text-gray-500 rb:mt-4 rb:mb-3'>
|
// onClick={() => setPdfEnhancementEnabled(!pdfEnhancementEnabled)}
|
||||||
{t('knowledgeBase.processingMethod')}
|
>
|
||||||
</div>
|
<Checkbox
|
||||||
<Radio.Group
|
checked={pdfEnhancementEnabled}
|
||||||
value={processingMethod}
|
onChange={(e) => setPdfEnhancementEnabled(e.target.checked)}
|
||||||
onChange={(e) => setProcessingMethod(e.target.value)}
|
className='rb:mr-3'
|
||||||
style={style}
|
/>
|
||||||
>
|
<span className='rb:text-base rb:font-medium rb:text-gray-800 rb:pl-[22px]'>
|
||||||
<Radio value='directBlock' style={getActiveRadioStyle(processingMethod === 'directBlock')}>
|
{t('knowledgeBase.pdfEnhancementAnalysis')}
|
||||||
<Flex gap='small' vertical>
|
</span>
|
||||||
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
{pdfEnhancementEnabled && (
|
||||||
{t('knowledgeBase.directBlock')}
|
<div className='rb:ml-10'>
|
||||||
</span>
|
<Select
|
||||||
</Flex>
|
value={pdfEnhancementMethod}
|
||||||
</Radio>
|
onChange={(value) => setPdfEnhancementMethod(value)}
|
||||||
<Radio value='qaExtract' style={getActiveRadioStyle(processingMethod === 'qaExtract')}>
|
className='rb:w-48'
|
||||||
<Flex gap='small' vertical>
|
options={[
|
||||||
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
{ value: 'deepdoc', label: 'DeepDoc' },
|
||||||
{t('knowledgeBase.qaExtract')}
|
{ value: 'mineru', label: 'MinerU' },
|
||||||
</span>
|
{ value: 'textln', label: 'TextLN' }
|
||||||
</Flex>
|
]}
|
||||||
</Radio>
|
/>
|
||||||
</Radio.Group>
|
|
||||||
<div className='rb:font-medium rb:text-gray-500 rb:mt-4 rb:mb-3'>
|
|
||||||
{t('knowledgeBase.parameterSettings')}
|
|
||||||
</div>
|
|
||||||
<Radio.Group
|
|
||||||
value={parameterSettings}
|
|
||||||
onChange={(e) => setParameterSettings(e.target.value)}
|
|
||||||
style={style}
|
|
||||||
>
|
|
||||||
<Radio value='defaultSettings' style={getActiveRadioStyle(parameterSettings === 'defaultSettings')}>
|
|
||||||
<Flex gap='small' vertical>
|
|
||||||
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
|
||||||
{t('knowledgeBase.default')}
|
|
||||||
</span>
|
|
||||||
<span className='rb:text-3 rb:text-gray-500'>{t('knowledgeBase.defaultSettings')}</span>
|
|
||||||
</Flex>
|
|
||||||
</Radio>
|
|
||||||
<Radio value='customSettings' style={getActiveRadioStyle(parameterSettings === 'customSettings')}>
|
|
||||||
<Flex gap='small' vertical>
|
|
||||||
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
|
||||||
{t('knowledgeBase.customize')}
|
|
||||||
</span>
|
|
||||||
<span className='rb:text-3 rb:text-gray-500'>{t('knowledgeBase.customSettings')}</span>
|
|
||||||
</Flex>
|
|
||||||
</Radio>
|
|
||||||
</Radio.Group>
|
|
||||||
{parameterSettings === 'customSettings' && (
|
|
||||||
<div className='rb:flex rb:flex-col rb:mt-5'>
|
|
||||||
<div className='rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
|
||||||
{t('knowledgeBase.delimiter')}
|
|
||||||
</div>
|
</div>
|
||||||
<DelimiterSelector value={delimiter} onChange={setDelimiter} className='rb:mb-5'/>
|
)}
|
||||||
<SliderInput label={t('knowledgeBase.suggestedBlockSize')} max={1024} min={1} step={1} value={blockSize} onChange={handleChange} />
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className='rb:text-base rb:font-medium rb:text-gray-800 rb:mt-6'>
|
||||||
)}
|
{t('knowledgeBase.dataProcessingSettings')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div className='rb:font-medium rb:text-gray-500 rb:mt-4 rb:mb-3'>
|
||||||
|
{t('knowledgeBase.processingMethod')}
|
||||||
{/* 暂时隐藏第三步:数据预览 */}
|
</div>
|
||||||
{/* {current === stepIndexMap.dataPreview && (
|
<Radio.Group
|
||||||
<div className='rb:grid rb:grid-cols-2 rb:rounded-xl rb:border rb:border-[#DFE4ED] rb:h-[calc(100%-160px)] rb:bg-[#FBFDFF] rb:mt-4'>
|
value={processingMethod}
|
||||||
<div className='rb:border-r rb:h-full rb:overflow-hidden rb:border-[#DFE4ED]'>
|
onChange={(e) => setProcessingMethod(e.target.value)}
|
||||||
<div className='rb:h-11 rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:px-4 rb:py-3 rb:border-b rb:border-[#DFE4ED]'>
|
style={style}
|
||||||
{t('knowledgeBase.fileList')}
|
>
|
||||||
</div>
|
<Radio value='directBlock' style={getActiveRadioStyle(processingMethod === 'directBlock')}>
|
||||||
<div className='rb:flex rb:flex-col rb:h-[calc(100%-44px)] rb:overflow-y-auto'>
|
<Flex gap='small' vertical>
|
||||||
{data.map((item, index) => (
|
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
||||||
<div key={index} className={`rb:h-11 rb:w-full rb:text-sm rb:text-gray-800 rb:px-4 rb:py-3 rb:hover:text-[#155EEF] rb:cursor-pointer ${curSelectedFileId === index ? styles.textBg + ' ' + styles.active : ''}`}
|
{t('knowledgeBase.directBlock')}
|
||||||
onClick={() => handlePreview(item, index)}>
|
</span>
|
||||||
{item.file_name}
|
</Flex>
|
||||||
</div>
|
</Radio>
|
||||||
))
|
<Radio value='qaExtract' style={getActiveRadioStyle(processingMethod === 'qaExtract')}>
|
||||||
}
|
<Flex gap='small' vertical>
|
||||||
|
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
||||||
</div>
|
{t('knowledgeBase.qaExtract')}
|
||||||
</div>
|
</span>
|
||||||
<div className='rb:h-full rb:overflow-hidden'>
|
</Flex>
|
||||||
<div className='rb:flex rb:items-center rb:justify-between rb:h-11 rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:px-4 rb:py-3 rb:border-b rb:border-[#DFE4ED]'>
|
</Radio>
|
||||||
{t('knowledgeBase.dataPreview')}
|
</Radio.Group>
|
||||||
<span className='rb:text-sm rb:text-gray-500'>{t('knowledgeBase.maxPreviewChunks', {count: total, max: chunkData.length})}</span>
|
<div className='rb:font-medium rb:text-gray-500 rb:mt-4 rb:mb-3'>
|
||||||
</div>
|
{t('knowledgeBase.parameterSettings')}
|
||||||
<Spin spinning={previewLoading}>
|
</div>
|
||||||
<div className='rb:flex rb:flex-col rb:h-[calc(100%-44px)] rb:overflow-y-auto'>
|
<Radio.Group
|
||||||
{chunkData.length > 0 ? (
|
value={parameterSettings}
|
||||||
chunkData.map((item, index) => (
|
onChange={(e) => setParameterSettings(e.target.value)}
|
||||||
<div key={index} className='rb:text-sm rb:text-gray-800 rb:px-4 rb:py-3'
|
style={style}
|
||||||
dangerouslySetInnerHTML={{ __html: item.page_content }}
|
>
|
||||||
/>
|
<Radio value='defaultSettings' style={getActiveRadioStyle(parameterSettings === 'defaultSettings')}>
|
||||||
))
|
<Flex gap='small' vertical>
|
||||||
) : (
|
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
||||||
<NoData title={t('knowledgeBase.noChunksToPreview')}
|
{t('knowledgeBase.default')}
|
||||||
subTitle={t('knowledgeBase.clickToPreview')}
|
</span>
|
||||||
image={noDataIcon}
|
<span className='rb:text-3 rb:text-gray-500'>{t('knowledgeBase.defaultSettings')}</span>
|
||||||
/>
|
</Flex>
|
||||||
)}
|
</Radio>
|
||||||
|
<Radio value='customSettings' style={getActiveRadioStyle(parameterSettings === 'customSettings')}>
|
||||||
|
<Flex gap='small' vertical>
|
||||||
|
<span className='rb:text-base rb:font-medium rb:text-gray-800'>
|
||||||
|
{t('knowledgeBase.customize')}
|
||||||
|
</span>
|
||||||
|
<span className='rb:text-3 rb:text-gray-500'>{t('knowledgeBase.customSettings')}</span>
|
||||||
|
</Flex>
|
||||||
|
</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
{parameterSettings === 'customSettings' && (
|
||||||
|
<div className='rb:flex rb:flex-col rb:mt-5'>
|
||||||
|
<div className='rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
|
||||||
|
{t('knowledgeBase.delimiter')}
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
<DelimiterSelector value={delimiter} onChange={setDelimiter} className='rb:mb-5'/>
|
||||||
</div>
|
<SliderInput label={t('knowledgeBase.suggestedBlockSize')} max={1024} min={1} step={1} value={blockSize} onChange={handleChange} />
|
||||||
</div>
|
</div>
|
||||||
)} */}
|
|
||||||
|
)}
|
||||||
{current === 2 && (
|
|
||||||
// <Spin spinning={pollingLoading} tip={t('knowledgeBase.processingDocuments') || '正在处理文档...'}>
|
|
||||||
<div className='rb:text-sm rb:text-gray-500 rb:mt-4 rb:h-[calc(100%-160px)] rb:overflow-y-auto'>
|
|
||||||
{rechunkFileIds.length > 0 ? (
|
|
||||||
<Table
|
|
||||||
ref={tableRef}
|
|
||||||
apiUrl={`/documents/${knowledgeBaseId}/documents`}
|
|
||||||
apiParams={{
|
|
||||||
document_ids: rechunkFileIds.join(','),
|
|
||||||
}}
|
|
||||||
columns={columns}
|
|
||||||
rowKey="id"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Table
|
|
||||||
ref={tableRef}
|
|
||||||
columns={columns}
|
|
||||||
rowKey="id"
|
|
||||||
initialData={[]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
// </Spin>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={`rb:flex rb:gap-3 rb:mt-6 ${current === 1 || (source == 'link' && current === 0) || (source == 'text' && current === 0) ? 'rb:pl-40 rb:mt-10' : ''}`}>
|
|
||||||
{current !== 0 && (
|
|
||||||
<Button onClick={handlePrev} disabled={current === 0 || pollingLoading}>
|
|
||||||
{t('common.previous') || 'Prev'}
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
<Button
|
|
||||||
type='primary'
|
{/* 暂时隐藏第三步:数据预览 */}
|
||||||
onClick={current === 2 ? handleStartUpload : handleNext}
|
{/* {current === stepIndexMap.dataPreview && (
|
||||||
disabled={pollingLoading || (current === 0 && rechunkFileIds.length === 0)}
|
<div className='rb:grid rb:grid-cols-2 rb:rounded-xl rb:border rb:border-[#DFE4ED] rb:h-[calc(100%-160px)] rb:bg-[#FBFDFF] rb:mt-4'>
|
||||||
>
|
<div className='rb:border-r rb:h-full rb:overflow-hidden rb:border-[#DFE4ED]'>
|
||||||
{current === 2 ? t('knowledgeBase.startUploading') || 'Start Upload' : t('common.next') || 'Next'}
|
<div className='rb:h-11 rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:px-4 rb:py-3 rb:border-b rb:border-[#DFE4ED]'>
|
||||||
</Button>
|
{t('knowledgeBase.fileList')}
|
||||||
|
</div>
|
||||||
|
<div className='rb:flex rb:flex-col rb:h-[calc(100%-44px)] rb:overflow-y-auto'>
|
||||||
|
{data.map((item, index) => (
|
||||||
|
<div key={index} className={`rb:h-11 rb:w-full rb:text-sm rb:text-gray-800 rb:px-4 rb:py-3 rb:hover:text-[#155EEF] rb:cursor-pointer ${curSelectedFileId === index ? styles.textBg + ' ' + styles.active : ''}`}
|
||||||
|
onClick={() => handlePreview(item, index)}>
|
||||||
|
{item.file_name}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='rb:h-full rb:overflow-hidden'>
|
||||||
|
<div className='rb:flex rb:items-center rb:justify-between rb:h-11 rb:w-full rb:text-sm rb:font-medium rb:text-gray-800 rb:px-4 rb:py-3 rb:border-b rb:border-[#DFE4ED]'>
|
||||||
|
{t('knowledgeBase.dataPreview')}
|
||||||
|
<span className='rb:text-sm rb:text-gray-500'>{t('knowledgeBase.maxPreviewChunks', {count: total, max: chunkData.length})}</span>
|
||||||
|
</div>
|
||||||
|
<Spin spinning={previewLoading}>
|
||||||
|
<div className='rb:flex rb:flex-col rb:h-[calc(100%-44px)] rb:overflow-y-auto'>
|
||||||
|
{chunkData.length > 0 ? (
|
||||||
|
chunkData.map((item, index) => (
|
||||||
|
<div key={index} className='rb:text-sm rb:text-gray-800 rb:px-4 rb:py-3'
|
||||||
|
dangerouslySetInnerHTML={{ __html: item.page_content }}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<NoData title={t('knowledgeBase.noChunksToPreview')}
|
||||||
|
subTitle={t('knowledgeBase.clickToPreview')}
|
||||||
|
image={noDataIcon}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)} */}
|
||||||
|
|
||||||
|
{current === 2 && (
|
||||||
|
// <Spin spinning={pollingLoading} tip={t('knowledgeBase.processingDocuments') || '正在处理文档...'}>
|
||||||
|
<div className='rb:text-sm rb:text-gray-500 rb:mt-4 rb:h-[calc(100%-160px)] rb:overflow-y-auto rb:px-6 rb:py-6'>
|
||||||
|
{rechunkFileIds.length > 0 ? (
|
||||||
|
<Table
|
||||||
|
ref={tableRef}
|
||||||
|
apiUrl={`/documents/${knowledgeBaseId}/documents`}
|
||||||
|
apiParams={{
|
||||||
|
document_ids: rechunkFileIds.join(','),
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Table
|
||||||
|
ref={tableRef}
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
initialData={[]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
// </Spin>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={`rb:flex rb:p-6 rb:gap-3 rb:mt-6 ${current === 1 || (source == 'link' && current === 0) || (source == 'text' && current === 0) ? 'rb:pl-40 rb:mt-10' : ''}`}>
|
||||||
|
{current !== 0 && (
|
||||||
|
<Button onClick={handlePrev} disabled={current === 0 || pollingLoading}>
|
||||||
|
{t('common.previous') || 'Prev'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
type='primary'
|
||||||
|
onClick={current === 2 ? handleStartUpload : handleNext}
|
||||||
|
disabled={pollingLoading || (current === 0 && rechunkFileIds.length === 0)}
|
||||||
|
>
|
||||||
|
{current === 2 ? t('knowledgeBase.startUploading') || 'Start Upload' : t('common.next') || 'Next'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>);
|
</>);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
.customTree .ant-tree-node-content-wrapper {
|
.customTree .ant-tree-node-content-wrapper {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
color: #171719 !important;
|
||||||
height: 40px !important;
|
height: 40px !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
@@ -28,15 +29,18 @@
|
|||||||
|
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:before,
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:before,
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:hover:before {
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:hover:before {
|
||||||
background: #FFFFFF !important;
|
background: #171719 !important;
|
||||||
}
|
}
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper,
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper,
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:hover{
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-node-content-wrapper:hover{
|
||||||
color: #000 !important;
|
color: #FFFFFF !important;
|
||||||
}
|
}
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-switcher,
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-switcher,
|
||||||
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-draggable-icon{
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-draggable-icon{
|
||||||
color: #000;
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.customTree.ant-tree.ant-tree-directory .ant-tree-treenode-selected .ant-tree-switcher img {
|
||||||
|
filter: brightness(0) invert(1) !important;
|
||||||
}
|
}
|
||||||
.customTree .ant-tree-switcher {
|
.customTree .ant-tree-switcher {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
@@ -111,3 +115,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Steps 已完成步骤圆内字体颜色 */
|
||||||
|
.custom-steps .ant-steps-item-finish .ant-steps-item-icon .ant-steps-icon {
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ const Private: FC = () => {
|
|||||||
const document = record as KnowledgeBaseDocumentData;
|
const document = record as KnowledgeBaseDocumentData;
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className="rb:text-blue-600 rb:cursor-pointer rb:hover:underline"
|
className="rb:text-gray-900 rb:font-medium rb:cursor-pointer rb:hover:underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (knowledgeBaseId && document.id) {
|
if (knowledgeBaseId && document.id) {
|
||||||
navigate(`/knowledge-base/${knowledgeBaseId}/DocumentDetails`,{
|
navigate(`/knowledge-base/${knowledgeBaseId}/DocumentDetails`,{
|
||||||
@@ -765,9 +765,9 @@ const Private: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
<div className="rb:flex rb:h-full rb:gap-4">
|
<div className="rb:flex rb:h-full rb:bg-white rb:rounded-xl">
|
||||||
{folder && (
|
{folder && (
|
||||||
<div className="rb:w-64 rb:flex-shrink-0 rb:h-[calc(100%+40px)] rb:mt-[-16px] rb:border-r rb:border-[#EAECEE] rb:p-4 rb:bg-transparent">
|
<div className="rb:w-64 rb:py-4 rb:flex-shrink-0 rb:h-[calc(100%+40px)] rb:border-r rb:border-[#EAECEE] rb:p-4 rb:bg-transparent">
|
||||||
<FolderTree
|
<FolderTree
|
||||||
multiple
|
multiple
|
||||||
className="customTree"
|
className="customTree"
|
||||||
@@ -783,7 +783,7 @@ const Private: FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className='rb:flex-1 rb:min-w-0'>
|
<div className='rb:flex-1 rb:min-w-0 rb:p-4'>
|
||||||
<div className="rb:flex rb:items-center rb:justify-between rb:mb-4">
|
<div className="rb:flex rb:items-center rb:justify-between rb:mb-4">
|
||||||
|
|
||||||
<div className="rb:flex-col">
|
<div className="rb:flex-col">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useEffect, useState, useRef, type FC } from 'react';
|
import { useEffect, useState, useRef, type FC } from 'react';
|
||||||
import { useParams, useLocation } from 'react-router-dom';
|
import { useParams, useLocation } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Popover } from 'antd';
|
||||||
import type { KnowledgeBaseListItem, RecallTestDrawerRef } from '@/views/KnowledgeBase/types';
|
import type { KnowledgeBaseListItem, RecallTestDrawerRef } from '@/views/KnowledgeBase/types';
|
||||||
import RecallTest from '../components/RecallTest';
|
import RecallTest from '../components/RecallTest';
|
||||||
import InfoPanel, { type InfoItem } from '../components/InfoPanel';
|
import InfoPanel, { type InfoItem } from '../components/InfoPanel';
|
||||||
@@ -27,7 +28,7 @@ const Share: FC = () => {
|
|||||||
const recallTestRef = useRef<RecallTestDrawerRef>(null);
|
const recallTestRef = useRef<RecallTestDrawerRef>(null);
|
||||||
const [infoItems, setInfoItems] = useState<InfoItem[]>([]);
|
const [infoItems, setInfoItems] = useState<InfoItem[]>([]);
|
||||||
const [knowledgeBaseFolderPath, setKnowledgeBaseFolderPath] = useState<BreadcrumbItem[]>([]);
|
const [knowledgeBaseFolderPath, setKnowledgeBaseFolderPath] = useState<BreadcrumbItem[]>([]);
|
||||||
|
const [viewInfo,setViewInfo] = useState<boolean>(false);
|
||||||
const { updateBreadcrumbs } = useBreadcrumbManager({
|
const { updateBreadcrumbs } = useBreadcrumbManager({
|
||||||
breadcrumbType: 'detail'
|
breadcrumbType: 'detail'
|
||||||
});
|
});
|
||||||
@@ -160,7 +161,17 @@ const Share: FC = () => {
|
|||||||
<span className='rb:text-gray-500 rb:text-sm rb:ml-2 rb:font-normal'>(ID: {knowledgeBase.id})</span></h1>
|
<span className='rb:text-gray-500 rb:text-sm rb:ml-2 rb:font-normal'>(ID: {knowledgeBase.id})</span></h1>
|
||||||
|
|
||||||
{/* <p className="rb:text-gray-600 rb:mt-2">{knowledgeBase.description || t('knowledgeBase.noDescription')}</p> */}
|
{/* <p className="rb:text-gray-600 rb:mt-2">{knowledgeBase.description || t('knowledgeBase.noDescription')}</p> */}
|
||||||
<span className='rb:text-gray-800 rb:text-xs rb:border rb:border-[#369F21] rb:bg-[rgba(54,159,33,0.2)] rb:px-1 rb:py-[2px] rb:rounded'>{knowledgeBase.permission_id}</span>
|
<span className='rb:text-white rb:text-xs rb:bg-blue-500 rb:px-1 rb:py-[2px] rb:rounded'>{knowledgeBase.permission_id}</span>
|
||||||
|
<Popover
|
||||||
|
content={<InfoPanel title={t('knowledgeBase.knowledgeBaseInfo')} items={infoItems} />}
|
||||||
|
trigger="hover"
|
||||||
|
placement="bottomLeft"
|
||||||
|
arrow={false}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className='rb:border rb:border-[#171719] rb:px-1 rb:py-[2px] rb:rounded rb:text-gray-900 rb:text-xs rb:cursor-pointer'
|
||||||
|
>{t('knowledgeBase.viewBasicInfo')}</span>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<div className="rb:flex rb:w-full rb:items-center rb:mb-5 rb:gap-2">
|
<div className="rb:flex rb:w-full rb:items-center rb:mb-5 rb:gap-2">
|
||||||
<img src={shareUserIcon} className='rb:size-4 rb:ml-2' />
|
<img src={shareUserIcon} className='rb:size-4 rb:ml-2' />
|
||||||
@@ -178,15 +189,11 @@ const Share: FC = () => {
|
|||||||
<RecallTest ref={recallTestRef} />
|
<RecallTest ref={recallTestRef} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='rb:w-80 rb:border rb:overflow-y-auto rb:border-[#DFE4ED] rb:bg-white rb:rounded-xl rb:p-4'>
|
{/* <div className='rb:w-80 rb:border rb:overflow-y-auto rb:border-[#DFE4ED] rb:bg-white rb:rounded-xl rb:p-4'>
|
||||||
<InfoPanel
|
|
||||||
title={t('knowledgeBase.knowledgeBaseInfo')}
|
</div> */}
|
||||||
items={infoItems}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -270,8 +270,8 @@ const KnowledgeGraph: FC<KnowledgeGraphProps> = ({ data, loading = false }) => {
|
|||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<RbCard
|
<RbCard
|
||||||
title={t('knowledgeBase.knowledgeGraph')}
|
title={t('knowledgeBase.knowledgeGraph')}
|
||||||
headerType="borderless"
|
variant="outlined"
|
||||||
headerClassName="rb:text-[18px]! rb:leading-[24px]"
|
headerClassName="rb:text-sm! rb:leading-11 rb:bg-[#FAFAFA]! rb:w-full rb:ml-0! rb:px-3!"
|
||||||
>
|
>
|
||||||
<div className="rb:h-124 rb:relative">
|
<div className="rb:h-124 rb:relative">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -435,7 +435,7 @@ const KnowledgeGraph: FC<KnowledgeGraphProps> = ({ data, loading = false }) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="rb:bg-[#F0F3F8] rb:flex rb:items-center rb:gap-6 rb:rounded-[0px_0px_12px_12px] rb:p-[14px_40px] rb:m-[0_-20px_-16px_-16px]">
|
<div className="rb:bg-[#FAFAFA] rb:border-box rb:border-t rb:border-gray-200 rb:flex rb:items-center rb:justify-between rb:gap-6 rb:rounded-[0px_0px_12px_12px] rb:p-[14px_40px] rb:m-[0_-16px_-20px_-16px]">
|
||||||
{operations.map((item) => (
|
{operations.map((item) => (
|
||||||
<div key={item.name} className="rb:flex rb:items-center rb:text-[#5B6167] rb:leading-5">
|
<div key={item.name} className="rb:flex rb:items-center rb:text-[#5B6167] rb:leading-5">
|
||||||
<img src={item.icon} className="rb:w-5 rb:h-5 rb:mr-1" />
|
<img src={item.icon} className="rb:w-5 rb:h-5 rb:mr-1" />
|
||||||
|
|||||||
@@ -108,11 +108,11 @@ const RecallTest = forwardRef<RecallTestDrawerRef>(({},ref) => {
|
|||||||
<span className='rb:text-[#155eef]'>{ t('knowledgeBase.loadSampleQuestions')}</span>
|
<span className='rb:text-[#155eef]'>{ t('knowledgeBase.loadSampleQuestions')}</span>
|
||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
<Form form={form} >
|
<Form form={form} layout="vertical">
|
||||||
<Form.Item name="query">
|
<Form.Item name="query">
|
||||||
<TextArea rows={4} placeholder={t('knowledgeBase.testQuestionPlaceholder')}/>
|
<TextArea rows={4} placeholder={t('knowledgeBase.testQuestionPlaceholder')}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<div className='rb:grid rb:grid-cols-2 rb:gap-x-4'>
|
<div className='rb:grid rb:grid-cols-5 rb:gap-x-4'>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="retrieve_type"
|
name="retrieve_type"
|
||||||
label={t('knowledgeBase.retrieveMode')}
|
label={t('knowledgeBase.retrieveMode')}
|
||||||
@@ -179,7 +179,7 @@ const RecallTest = forwardRef<RecallTestDrawerRef>(({},ref) => {
|
|||||||
{/* <Form.Item name="hybrid" valuePropName="checked" initialValue={true} label={t('knowledgeBase.hybrid') || 'Hybrid'}>
|
{/* <Form.Item name="hybrid" valuePropName="checked" initialValue={true} label={t('knowledgeBase.hybrid') || 'Hybrid'}>
|
||||||
<Switch checkedChildren={t('common.yes') || 'Yes'} unCheckedChildren={t('common.no') || 'No'} />
|
<Switch checkedChildren={t('common.yes') || 'Yes'} unCheckedChildren={t('common.no') || 'No'} />
|
||||||
</Form.Item> */}
|
</Form.Item> */}
|
||||||
<Form.Item>
|
<Form.Item className="rb:flex rb:items-end rb:justify-end">
|
||||||
<Button type="primary" onClick={handleStartTest} loading={loading}>{ t('knowledgeBase.startTesting')}</Button>
|
<Button type="primary" onClick={handleStartTest} loading={loading}>{ t('knowledgeBase.startTesting')}</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { forwardRef, useImperativeHandle, useState, useRef, useLayoutEffect, useCallback } from 'react';
|
import { forwardRef, useImperativeHandle, useState, useRef, useLayoutEffect, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import RbDrawer from '@/components/RbDrawer';
|
import RbDrawer from '@/components/RbDrawer';
|
||||||
@@ -51,6 +50,7 @@ const RecallTestDrawer = forwardRef<RecallTestDrawerRef>(({},ref) => {
|
|||||||
title={t('knowledgeBase.recallTest')}
|
title={t('knowledgeBase.recallTest')}
|
||||||
open={open}
|
open={open}
|
||||||
onClose={() => setOpen(false)}
|
onClose={() => setOpen(false)}
|
||||||
|
width={1000}
|
||||||
>
|
>
|
||||||
<RecallTest ref={setRecallTestRef} />
|
<RecallTest ref={setRecallTestRef} />
|
||||||
</RbDrawer>
|
</RbDrawer>
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ const RecallTestResult = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${item.metadata?.sort_id || index}-${index}`}
|
key={`${item.metadata?.sort_id || index}-${index}`}
|
||||||
className={`rb:flex rb:flex-col rb:mb-4 rb:rounded-lg rb:border rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:p-4 rb:pt-2 rb:pb-3 rb:relative rb:group ${editable ? 'rb:cursor-pointer rb:transition-all hover:rb:border-[#155EEF] hover:rb:shadow-md' : ''}`}
|
className={`rb:flex rb:flex-col rb:mb-4 rb:rounded-xl rb:bg-[#F6F6F6] rb:p-4 rb:pt-2 rb:pb-3 rb:relative rb:group ${editable ? 'rb:cursor-pointer rb:transition-all hover:rb:border-[#155EEF] hover:rb:shadow-md' : ''}`}
|
||||||
onClick={(e) => handleItemClick(e, item, index)}
|
onClick={(e) => handleItemClick(e, item, index)}
|
||||||
>
|
>
|
||||||
{editable && (
|
{editable && (
|
||||||
@@ -183,16 +183,16 @@ const RecallTestResult = ({
|
|||||||
{scorePercentage.toFixed(1)}% {t('knowledgeBase.similarity')}
|
{scorePercentage.toFixed(1)}% {t('knowledgeBase.similarity')}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className={`rb:flex rb:mt-2 rb:flex-col rb:items-end rb:justify-end rb:gap-1 ${!showScore ? 'rb:w-full' : ''}`}>
|
<div className={`rb:flex rb:mt-2 rb:flex rb:items-end rb:justify-end rb:gap-4 ${!showScore ? 'rb:w-full' : ''}`}>
|
||||||
<span className='rb:text-gray-800'>
|
<span className='rb:text-gray-800'>
|
||||||
<FileOutlined /> {item.metadata?.file_name || '-'}
|
<FileOutlined /> {item.metadata?.file_name || '-'}
|
||||||
</span>
|
</span>
|
||||||
<span className='rb:text-gray-500 rb:text-xs rb:bg-[#F0F3F8] rb:px-1 rb:py-[2px] rb:rounded'>
|
<span className='rb:text-gray-500 rb:text-xs rb:bg-[#DFDFDF] rb:px-1 rb:py-[2px] rb:rounded'>
|
||||||
chunk_{item.metadata?.sort_id || index}
|
chunk_{item.metadata?.sort_id || index}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='rb:flex rb:text-left rb:px-4 rb:py-3 rb:bg-[#F0F3F8] rb:rounded-lg rb:mt-2'>
|
<div className='rb:flex rb:text-left rb:px-4 rb:py-3 rb:bg-white rb:rounded-lg rb:mt-2'>
|
||||||
<div className='rb:text-gray-800 rb:text-sm rb:whitespace-pre-wrap rb:break-words rb:w-full'>
|
<div className='rb:text-gray-800 rb:text-sm rb:whitespace-pre-wrap rb:break-words rb:w-full'>
|
||||||
{(() => {
|
{(() => {
|
||||||
const qaContent = parseQAContent(item.page_content);
|
const qaContent = parseQAContent(item.page_content);
|
||||||
|
|||||||
Reference in New Issue
Block a user