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]);
|
||||
|
||||
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(
|
||||
(val: string) => {
|
||||
setValue(val);
|
||||
@ -179,7 +192,7 @@ export const SelectWithSearch = forwardRef<
|
||||
align="start"
|
||||
>
|
||||
<Command className="p-5">
|
||||
{options && options.length > 5 && (
|
||||
{showSearch && (
|
||||
<CommandInput
|
||||
placeholder={t('common.search') + '...'}
|
||||
className=" placeholder:text-text-disabled"
|
||||
|
||||
@ -147,6 +147,8 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
action: 'Action',
|
||||
},
|
||||
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',
|
||||
description: 'Description',
|
||||
memorySize: 'Memory size',
|
||||
|
||||
@ -124,7 +124,6 @@ export default {
|
||||
forgetMessageTip: '确定遗忘吗?',
|
||||
messageDescription: '记忆提取使用高级设置中的提示词和温度值进行配置。',
|
||||
copied: '已复制!',
|
||||
contentEmbed: '内容嵌入',
|
||||
content: '内容',
|
||||
delMessageWarn: `遗忘后,代理将无法检索此消息。`,
|
||||
forgetMessage: '遗忘消息',
|
||||
@ -138,6 +137,8 @@ export default {
|
||||
action: '操作',
|
||||
},
|
||||
config: {
|
||||
memorySizeTooltip: `记录每条消息的内容 + 其嵌入向量(≈ 内容 + 维度 × 8 字节)。
|
||||
例如:一条带有 1024 维嵌入的 1 KB 消息大约使用 9 KB。5 MB 的默认限制大约可容纳 500 条此类消息。`,
|
||||
avatar: '头像',
|
||||
description: '描述',
|
||||
memorySize: '记忆大小',
|
||||
|
||||
@ -79,6 +79,7 @@ export default function Dataset() {
|
||||
useRowSelection();
|
||||
|
||||
const {
|
||||
chunkNum,
|
||||
list,
|
||||
visible: reparseDialogVisible,
|
||||
hideModal: hideReparseDialogModal,
|
||||
@ -218,7 +219,7 @@ export default function Dataset() {
|
||||
// hidden={isZeroChunk || isRunning}
|
||||
hidden={true}
|
||||
handleOperationIconClick={handleOperationIconClick}
|
||||
chunk_num={0}
|
||||
chunk_num={chunkNum}
|
||||
visible={reparseDialogVisible}
|
||||
hideModal={hideReparseDialogModal}
|
||||
></ReparseDialog>
|
||||
|
||||
@ -183,7 +183,7 @@ export function ParsingStatusCell({
|
||||
)}
|
||||
{reparseDialogVisible && (
|
||||
<ReparseDialog
|
||||
hidden={isZeroChunk || isRunning}
|
||||
hidden={isRunning}
|
||||
// hidden={false}
|
||||
handleOperationIconClick={handleOperationIconClick}
|
||||
chunk_num={chunk_num}
|
||||
|
||||
@ -2,12 +2,14 @@ import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import {
|
||||
DynamicForm,
|
||||
DynamicFormRef,
|
||||
FormFieldConfig,
|
||||
FormFieldType,
|
||||
} from '@/components/dynamic-form';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { DialogProps } from '@radix-ui/react-dialog';
|
||||
import { t } from 'i18next';
|
||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { ControllerRenderProps } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ReparseDialog = memo(
|
||||
({
|
||||
@ -26,18 +28,77 @@ export const ReparseDialog = memo(
|
||||
hideModal: () => void;
|
||||
hidden?: boolean;
|
||||
}) => {
|
||||
// const [formInstance, setFormInstance] = useState<DynamicFormRef | null>(
|
||||
// null,
|
||||
// );
|
||||
const [defaultValues, setDefaultValues] = useState<any>(null);
|
||||
const [fields, setFields] = useState<FormFieldConfig[]>([]);
|
||||
const { t } = useTranslation();
|
||||
const handleOperationIconClickRef = useRef(handleOperationIconClick);
|
||||
const hiddenRef = useRef(hidden);
|
||||
|
||||
// const formCallbackRef = useCallback((node: DynamicFormRef | null) => {
|
||||
// if (node) {
|
||||
// setFormInstance(node);
|
||||
// console.log('Form instance assigned:', node);
|
||||
// } else {
|
||||
// console.log('Form instance removed');
|
||||
// }
|
||||
// }, []);
|
||||
useEffect(() => {
|
||||
handleOperationIconClickRef.current = handleOperationIconClick;
|
||||
hiddenRef.current = hidden;
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
@ -68,12 +129,6 @@ export const ReparseDialog = memo(
|
||||
}
|
||||
}, [formCallbackRef, handleOperationIconClick]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hidden) {
|
||||
handleOperationIconClick();
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ConfirmDeleteDialog
|
||||
title={t(`knowledgeDetails.parseFile`)}
|
||||
@ -91,48 +146,8 @@ export const ReparseDialog = memo(
|
||||
console.log('submit', data);
|
||||
}}
|
||||
ref={formCallbackRef}
|
||||
fields={[
|
||||
{
|
||||
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>
|
||||
),
|
||||
},
|
||||
]}
|
||||
fields={fields}
|
||||
defaultValues={defaultValues}
|
||||
>
|
||||
{/* <DynamicForm.CancelButton
|
||||
handleCancel={() => handleOperationIconClick(false)}
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from '@/hooks/use-document-request';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { Ban, CircleCheck, CircleX, Play, Trash2 } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toast } from 'sonner';
|
||||
import { DocumentType, RunningStatus } from './constant';
|
||||
@ -32,6 +32,16 @@ export function useBulkOperateDataset({
|
||||
const { setDocumentStatus } = useSetDocumentStatus();
|
||||
const { removeDocument } = useRemoveDocument();
|
||||
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(
|
||||
async (run: number, option?: { delete: boolean; apply_kb: boolean }) => {
|
||||
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<{
|
||||
overflowTip?: boolean;
|
||||
label: string;
|
||||
value: string | React.ReactNode;
|
||||
className?: string;
|
||||
}> = ({ label, value, className = '' }) => {
|
||||
}> = ({ label, value, className = '', overflowTip = false }) => {
|
||||
return (
|
||||
<div className={`flex flex-col mb-4 ${className}`}>
|
||||
<span className="text-text-secondary text-sm">{label}</span>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="text-text-primary mt-1 truncate w-full">
|
||||
{value}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{value}</TooltipContent>
|
||||
</Tooltip>
|
||||
{overflowTip && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="text-text-primary mt-1 truncate w-full">
|
||||
{value}
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{value}</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
{!overflowTip && (
|
||||
<span className="text-text-primary mt-1 truncate w-full">{value}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -139,6 +145,7 @@ const ProcessLogModal: React.FC<ProcessLogModalProps> = ({
|
||||
return (
|
||||
<div className="w-1/2" key={key}>
|
||||
<InfoItem
|
||||
overflowTip={true}
|
||||
label={t(key)}
|
||||
value={logInfo[key as keyof typeof logInfo]}
|
||||
/>
|
||||
|
||||
@ -92,6 +92,7 @@ export const MemoryModelForm = () => {
|
||||
label: t('memory.config.memorySize') + ' (Bytes)',
|
||||
type: FormFieldType.Number,
|
||||
horizontal: true,
|
||||
tooltip: t('memory.config.memorySizeTooltip'),
|
||||
// placeholder: t('memory.config.memorySizePlaceholder'),
|
||||
required: false,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user