mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-31 17:15:32 +08:00
Fix: Dataset parse logic (#12330)
### What problem does this PR solve? Fix: Dataset logic of parser ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -109,6 +109,19 @@ export const SelectWithSearch = forwardRef<
|
|||||||
}
|
}
|
||||||
}, [options, value]);
|
}, [options, value]);
|
||||||
|
|
||||||
|
const showSearch = useMemo(() => {
|
||||||
|
if (Array.isArray(options) && options.length > 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
const optionsNum = options.reduce((acc, option) => {
|
||||||
|
return acc + (option?.options?.length || 0);
|
||||||
|
}, 0);
|
||||||
|
return optionsNum > 5;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, [options]);
|
||||||
|
|
||||||
const handleSelect = useCallback(
|
const handleSelect = useCallback(
|
||||||
(val: string) => {
|
(val: string) => {
|
||||||
setValue(val);
|
setValue(val);
|
||||||
@ -179,7 +192,7 @@ export const SelectWithSearch = forwardRef<
|
|||||||
align="start"
|
align="start"
|
||||||
>
|
>
|
||||||
<Command className="p-5">
|
<Command className="p-5">
|
||||||
{options && options.length > 5 && (
|
{showSearch && (
|
||||||
<CommandInput
|
<CommandInput
|
||||||
placeholder={t('common.search') + '...'}
|
placeholder={t('common.search') + '...'}
|
||||||
className=" placeholder:text-text-disabled"
|
className=" placeholder:text-text-disabled"
|
||||||
|
|||||||
@ -147,6 +147,8 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
|||||||
action: 'Action',
|
action: 'Action',
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
|
memorySizeTooltip: `Accounts for each message's content + its embedding vector (≈ Content + Dimensions × 8 Bytes).
|
||||||
|
Example: A 1 KB message with 1024-dim embedding uses ~9 KB. The 5 MB default limit holds ~500 such messages.`,
|
||||||
avatar: 'Avatar',
|
avatar: 'Avatar',
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
memorySize: 'Memory size',
|
memorySize: 'Memory size',
|
||||||
|
|||||||
@ -124,7 +124,6 @@ export default {
|
|||||||
forgetMessageTip: '确定遗忘吗?',
|
forgetMessageTip: '确定遗忘吗?',
|
||||||
messageDescription: '记忆提取使用高级设置中的提示词和温度值进行配置。',
|
messageDescription: '记忆提取使用高级设置中的提示词和温度值进行配置。',
|
||||||
copied: '已复制!',
|
copied: '已复制!',
|
||||||
contentEmbed: '内容嵌入',
|
|
||||||
content: '内容',
|
content: '内容',
|
||||||
delMessageWarn: `遗忘后,代理将无法检索此消息。`,
|
delMessageWarn: `遗忘后,代理将无法检索此消息。`,
|
||||||
forgetMessage: '遗忘消息',
|
forgetMessage: '遗忘消息',
|
||||||
@ -138,6 +137,8 @@ export default {
|
|||||||
action: '操作',
|
action: '操作',
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
|
memorySizeTooltip: `记录每条消息的内容 + 其嵌入向量(≈ 内容 + 维度 × 8 字节)。
|
||||||
|
例如:一条带有 1024 维嵌入的 1 KB 消息大约使用 9 KB。5 MB 的默认限制大约可容纳 500 条此类消息。`,
|
||||||
avatar: '头像',
|
avatar: '头像',
|
||||||
description: '描述',
|
description: '描述',
|
||||||
memorySize: '记忆大小',
|
memorySize: '记忆大小',
|
||||||
|
|||||||
@ -79,6 +79,7 @@ export default function Dataset() {
|
|||||||
useRowSelection();
|
useRowSelection();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
chunkNum,
|
||||||
list,
|
list,
|
||||||
visible: reparseDialogVisible,
|
visible: reparseDialogVisible,
|
||||||
hideModal: hideReparseDialogModal,
|
hideModal: hideReparseDialogModal,
|
||||||
@ -218,7 +219,7 @@ export default function Dataset() {
|
|||||||
// hidden={isZeroChunk || isRunning}
|
// hidden={isZeroChunk || isRunning}
|
||||||
hidden={true}
|
hidden={true}
|
||||||
handleOperationIconClick={handleOperationIconClick}
|
handleOperationIconClick={handleOperationIconClick}
|
||||||
chunk_num={0}
|
chunk_num={chunkNum}
|
||||||
visible={reparseDialogVisible}
|
visible={reparseDialogVisible}
|
||||||
hideModal={hideReparseDialogModal}
|
hideModal={hideReparseDialogModal}
|
||||||
></ReparseDialog>
|
></ReparseDialog>
|
||||||
|
|||||||
@ -183,7 +183,7 @@ export function ParsingStatusCell({
|
|||||||
)}
|
)}
|
||||||
{reparseDialogVisible && (
|
{reparseDialogVisible && (
|
||||||
<ReparseDialog
|
<ReparseDialog
|
||||||
hidden={isZeroChunk || isRunning}
|
hidden={isRunning}
|
||||||
// hidden={false}
|
// hidden={false}
|
||||||
handleOperationIconClick={handleOperationIconClick}
|
handleOperationIconClick={handleOperationIconClick}
|
||||||
chunk_num={chunk_num}
|
chunk_num={chunk_num}
|
||||||
|
|||||||
@ -2,12 +2,14 @@ import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
DynamicFormRef,
|
DynamicFormRef,
|
||||||
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
import { DialogProps } from '@radix-ui/react-dialog';
|
import { DialogProps } from '@radix-ui/react-dialog';
|
||||||
import { t } from 'i18next';
|
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
import { ControllerRenderProps } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const ReparseDialog = memo(
|
export const ReparseDialog = memo(
|
||||||
({
|
({
|
||||||
@ -26,18 +28,77 @@ export const ReparseDialog = memo(
|
|||||||
hideModal: () => void;
|
hideModal: () => void;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
// const [formInstance, setFormInstance] = useState<DynamicFormRef | null>(
|
const [defaultValues, setDefaultValues] = useState<any>(null);
|
||||||
// null,
|
const [fields, setFields] = useState<FormFieldConfig[]>([]);
|
||||||
// );
|
const { t } = useTranslation();
|
||||||
|
const handleOperationIconClickRef = useRef(handleOperationIconClick);
|
||||||
|
const hiddenRef = useRef(hidden);
|
||||||
|
|
||||||
// const formCallbackRef = useCallback((node: DynamicFormRef | null) => {
|
useEffect(() => {
|
||||||
// if (node) {
|
handleOperationIconClickRef.current = handleOperationIconClick;
|
||||||
// setFormInstance(node);
|
hiddenRef.current = hidden;
|
||||||
// console.log('Form instance assigned:', node);
|
});
|
||||||
// } else {
|
|
||||||
// console.log('Form instance removed');
|
useEffect(() => {
|
||||||
// }
|
if (hiddenRef.current) {
|
||||||
// }, []);
|
handleOperationIconClickRef.current();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
setDefaultValues({
|
||||||
|
delete: chunk_num > 0,
|
||||||
|
apply_kb: false,
|
||||||
|
});
|
||||||
|
const deleteField = {
|
||||||
|
name: 'delete',
|
||||||
|
label: '',
|
||||||
|
type: FormFieldType.Checkbox,
|
||||||
|
render: (fieldProps: ControllerRenderProps) => (
|
||||||
|
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
||||||
|
<Checkbox
|
||||||
|
{...fieldProps}
|
||||||
|
checked={fieldProps.value}
|
||||||
|
onCheckedChange={(checked: boolean) => {
|
||||||
|
fieldProps.onChange(checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span className="ml-2">
|
||||||
|
{chunk_num > 0
|
||||||
|
? t(`knowledgeDetails.redo`, {
|
||||||
|
chunkNum: chunk_num,
|
||||||
|
})
|
||||||
|
: t('knowledgeDetails.redoAll')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
const applyKBField = {
|
||||||
|
name: 'apply_kb',
|
||||||
|
label: '',
|
||||||
|
type: FormFieldType.Checkbox,
|
||||||
|
defaultValue: false,
|
||||||
|
render: (fieldProps: ControllerRenderProps) => (
|
||||||
|
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
||||||
|
<Checkbox
|
||||||
|
{...fieldProps}
|
||||||
|
checked={fieldProps.value}
|
||||||
|
onCheckedChange={(checked: boolean) => {
|
||||||
|
fieldProps.onChange(checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span className="ml-2">
|
||||||
|
{t('knowledgeDetails.applyAutoMetadataSettings')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
if (chunk_num > 0) {
|
||||||
|
setFields([deleteField, applyKBField]);
|
||||||
|
}
|
||||||
|
if (chunk_num <= 0) {
|
||||||
|
setFields([applyKBField]);
|
||||||
|
}
|
||||||
|
}, [chunk_num, t]);
|
||||||
|
|
||||||
const formCallbackRef = useRef<DynamicFormRef>(null);
|
const formCallbackRef = useRef<DynamicFormRef>(null);
|
||||||
|
|
||||||
@ -68,12 +129,6 @@ export const ReparseDialog = memo(
|
|||||||
}
|
}
|
||||||
}, [formCallbackRef, handleOperationIconClick]);
|
}, [formCallbackRef, handleOperationIconClick]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (hidden) {
|
|
||||||
handleOperationIconClick();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfirmDeleteDialog
|
<ConfirmDeleteDialog
|
||||||
title={t(`knowledgeDetails.parseFile`)}
|
title={t(`knowledgeDetails.parseFile`)}
|
||||||
@ -91,48 +146,8 @@ export const ReparseDialog = memo(
|
|||||||
console.log('submit', data);
|
console.log('submit', data);
|
||||||
}}
|
}}
|
||||||
ref={formCallbackRef}
|
ref={formCallbackRef}
|
||||||
fields={[
|
fields={fields}
|
||||||
{
|
defaultValues={defaultValues}
|
||||||
name: 'delete',
|
|
||||||
label: '',
|
|
||||||
type: FormFieldType.Checkbox,
|
|
||||||
render: (fieldProps) => (
|
|
||||||
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
|
||||||
<Checkbox
|
|
||||||
{...fieldProps}
|
|
||||||
onCheckedChange={(checked: boolean) => {
|
|
||||||
fieldProps.onChange(checked);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<span className="ml-2">
|
|
||||||
{chunk_num > 0
|
|
||||||
? t(`knowledgeDetails.redo`, {
|
|
||||||
chunkNum: chunk_num,
|
|
||||||
})
|
|
||||||
: t('knowledgeDetails.redoAll')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'apply_kb',
|
|
||||||
label: '',
|
|
||||||
type: FormFieldType.Checkbox,
|
|
||||||
render: (fieldProps) => (
|
|
||||||
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
|
||||||
<Checkbox
|
|
||||||
{...fieldProps}
|
|
||||||
onCheckedChange={(checked: boolean) => {
|
|
||||||
fieldProps.onChange(checked);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<span className="ml-2">
|
|
||||||
{t('knowledgeDetails.applyAutoMetadataSettings')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
{/* <DynamicForm.CancelButton
|
{/* <DynamicForm.CancelButton
|
||||||
handleCancel={() => handleOperationIconClick(false)}
|
handleCancel={() => handleOperationIconClick(false)}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@/hooks/use-document-request';
|
} from '@/hooks/use-document-request';
|
||||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||||
import { Ban, CircleCheck, CircleX, Play, Trash2 } from 'lucide-react';
|
import { Ban, CircleCheck, CircleX, Play, Trash2 } from 'lucide-react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { DocumentType, RunningStatus } from './constant';
|
import { DocumentType, RunningStatus } from './constant';
|
||||||
@ -32,6 +32,16 @@ export function useBulkOperateDataset({
|
|||||||
const { setDocumentStatus } = useSetDocumentStatus();
|
const { setDocumentStatus } = useSetDocumentStatus();
|
||||||
const { removeDocument } = useRemoveDocument();
|
const { removeDocument } = useRemoveDocument();
|
||||||
const { visible, showModal, hideModal } = useSetModalState();
|
const { visible, showModal, hideModal } = useSetModalState();
|
||||||
|
|
||||||
|
const chunkNum = useMemo(() => {
|
||||||
|
if (!documents.length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return documents.reduce((acc, cur) => {
|
||||||
|
return acc + cur.chunk_num;
|
||||||
|
}, 0);
|
||||||
|
}, [documents]);
|
||||||
|
|
||||||
const runDocument = useCallback(
|
const runDocument = useCallback(
|
||||||
async (run: number, option?: { delete: boolean; apply_kb: boolean }) => {
|
async (run: number, option?: { delete: boolean; apply_kb: boolean }) => {
|
||||||
const nonVirtualKeys = selectedRowKeys.filter(
|
const nonVirtualKeys = selectedRowKeys.filter(
|
||||||
@ -132,5 +142,5 @@ export function useBulkOperateDataset({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return { list, visible, hideModal, showModal, handleRunClick };
|
return { chunkNum, list, visible, hideModal, showModal, handleRunClick };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,21 +38,27 @@ interface ProcessLogModalProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const InfoItem: React.FC<{
|
const InfoItem: React.FC<{
|
||||||
|
overflowTip?: boolean;
|
||||||
label: string;
|
label: string;
|
||||||
value: string | React.ReactNode;
|
value: string | React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}> = ({ label, value, className = '' }) => {
|
}> = ({ label, value, className = '', overflowTip = false }) => {
|
||||||
return (
|
return (
|
||||||
<div className={`flex flex-col mb-4 ${className}`}>
|
<div className={`flex flex-col mb-4 ${className}`}>
|
||||||
<span className="text-text-secondary text-sm">{label}</span>
|
<span className="text-text-secondary text-sm">{label}</span>
|
||||||
<Tooltip>
|
{overflowTip && (
|
||||||
<TooltipTrigger asChild>
|
<Tooltip>
|
||||||
<span className="text-text-primary mt-1 truncate w-full">
|
<TooltipTrigger asChild>
|
||||||
{value}
|
<span className="text-text-primary mt-1 truncate w-full">
|
||||||
</span>
|
{value}
|
||||||
</TooltipTrigger>
|
</span>
|
||||||
<TooltipContent>{value}</TooltipContent>
|
</TooltipTrigger>
|
||||||
</Tooltip>
|
<TooltipContent>{value}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{!overflowTip && (
|
||||||
|
<span className="text-text-primary mt-1 truncate w-full">{value}</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -139,6 +145,7 @@ const ProcessLogModal: React.FC<ProcessLogModalProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className="w-1/2" key={key}>
|
<div className="w-1/2" key={key}>
|
||||||
<InfoItem
|
<InfoItem
|
||||||
|
overflowTip={true}
|
||||||
label={t(key)}
|
label={t(key)}
|
||||||
value={logInfo[key as keyof typeof logInfo]}
|
value={logInfo[key as keyof typeof logInfo]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -92,6 +92,7 @@ export const MemoryModelForm = () => {
|
|||||||
label: t('memory.config.memorySize') + ' (Bytes)',
|
label: t('memory.config.memorySize') + ' (Bytes)',
|
||||||
type: FormFieldType.Number,
|
type: FormFieldType.Number,
|
||||||
horizontal: true,
|
horizontal: true,
|
||||||
|
tooltip: t('memory.config.memorySizeTooltip'),
|
||||||
// placeholder: t('memory.config.memorySizePlaceholder'),
|
// placeholder: t('memory.config.memorySizePlaceholder'),
|
||||||
required: false,
|
required: false,
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user