diff --git a/web/src/components/chunk-method-dialog/index.tsx b/web/src/components/chunk-method-dialog/index.tsx index dfdcab52c..8c1bb855e 100644 --- a/web/src/components/chunk-method-dialog/index.tsx +++ b/web/src/components/chunk-method-dialog/index.tsx @@ -240,6 +240,11 @@ export function ChunkMethodDialog({ name: 'parseType', defaultValue: pipelineId ? 2 : 1, }); + useEffect(() => { + if (parseType === 1) { + form.setValue('pipeline_id', ''); + } + }, [parseType, form]); return ( diff --git a/web/src/components/data-pipeline-select/index.tsx b/web/src/components/data-pipeline-select/index.tsx index 80c74705f..76dd15fa1 100644 --- a/web/src/components/data-pipeline-select/index.tsx +++ b/web/src/components/data-pipeline-select/index.tsx @@ -75,7 +75,7 @@ export function DataFlowSelect(props: IProps) { tooltip={t('dataFlowTip')} className="text-sm text-text-primary whitespace-wrap " > - {t('dataFlow')} + {t('dataPipeline')} {toDataPipeline && (
{ return ( - + { + e.preventDefault(); // Prevent clicking the tooltip from triggering form save + }} + > @@ -107,7 +112,7 @@ export const AntToolTip: React.FC = ({ {visible && title && (
In a Tag column, comma is used to separate tags.

Lines of texts that fail to follow the above rules will be ignored. `, - useRaptor: 'Use RAPTOR to enhance retrieval', + useRaptor: 'RAPTOR', useRaptorTip: 'Enable RAPTOR for multi-hop question-answering tasks. See https://ragflow.io/docs/dev/enable_raptor for details.', prompt: 'Prompt', @@ -466,7 +466,7 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s topnTags: 'Top-N Tags', tags: 'Tags', addTag: 'Add tag', - useGraphRag: 'Extract knowledge graph', + useGraphRag: 'Knowledge graph', useGraphRagTip: 'Construct a knowledge graph over file chunks of the current knowledge base to enhance multi-hop question-answering involving nested logic. See https://ragflow.io/docs/dev/construct_knowledge_graph for details.', graphRagMethod: 'Method', @@ -474,7 +474,7 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s General: Use prompts provided by github.com/microsoft/graphrag to extract entities and relationships`, resolution: 'Entity resolution', resolutionTip: `An entity deduplication switch. When enabled, the LLM will combine similar entities - e.g., '2025' and 'the year of 2025', or 'IT' and 'Information Technology' - to construct a more accurate graph`, - community: 'Community reports generation', + community: 'Community reports', communityTip: 'In a knowledge graph, a community is a cluster of entities linked by relationships. You can have the LLM generate an abstract for each community, known as a community report. See here for more information: https://www.microsoft.com/en-us/research/blog/graphrag-improving-global-search-via-dynamic-community-selection/', theDocumentBeingParsedCannotBeDeleted: @@ -1791,5 +1791,12 @@ Important structured information may include: names, dates, locations, events, k summary: 'Augmented Context', }, }, + datasetOverview: { + downloadTip: 'Files being downloaded from data sources. ', + processingTip: 'Files being processed by data flows.', + totalFiles: 'Total Files', + downloading: 'Downloading', + processing: 'Processing', + }, }, }; diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index faa35320f..7d79476ae 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1696,5 +1696,12 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 filenameEmbeddingWeight: '文件名嵌入权重', switchPromptMessage: '提示词将发生变化,请确认是否放弃已有提示词?', }, + datasetOverview: { + downloadTip: '正在从数据源下载文件。', + processingTip: '正在由数据流处理文件。', + totalFiles: '文件总数', + downloading: '正在下载', + processing: '正在处理', + }, }, }; diff --git a/web/src/pages/dataflow-result/components/parse-editer/hook.ts b/web/src/pages/dataflow-result/components/parse-editer/hook.ts index 77acbbaf6..6ec503acd 100644 --- a/web/src/pages/dataflow-result/components/parse-editer/hook.ts +++ b/web/src/pages/dataflow-result/components/parse-editer/hook.ts @@ -5,8 +5,8 @@ export const useParserInit = ({ initialValue, }: { initialValue: - | Pick - | Pick; + | IJsonContainerProps['initialValue'] + | IObjContainerProps['initialValue']; }) => { const [content, setContent] = useState(initialValue); diff --git a/web/src/pages/dataflow-result/components/parse-editer/json-parser.tsx b/web/src/pages/dataflow-result/components/parse-editer/json-parser.tsx index 33b988f5a..e86999b78 100644 --- a/web/src/pages/dataflow-result/components/parse-editer/json-parser.tsx +++ b/web/src/pages/dataflow-result/components/parse-editer/json-parser.tsx @@ -8,7 +8,7 @@ import { IJsonContainerProps } from './interface'; export const parserKeyMap = { json: 'text', chunks: 'text', -}; +} as const; export const ArrayContainer = (props: IJsonContainerProps) => { const { @@ -33,24 +33,15 @@ export const ArrayContainer = (props: IJsonContainerProps) => { editDivRef, } = useParserInit({ initialValue }); + const parserKey = parserKeyMap[content.key as keyof typeof parserKeyMap]; + const handleEdit = useCallback( (e?: any, index?: number) => { - setContent((pre) => ({ - ...pre, - value: pre.value.map((item, i) => { - if (i === index) { - return { - ...item, - [parserKeyMap[content.key]]: unescapeNewlines(e.target.innerText), - }; - } - return item; - }), - })); setActiveEditIndex(index); }, [setContent, setActiveEditIndex], ); + const handleSave = useCallback( (e: any) => { const saveData = { @@ -59,7 +50,7 @@ export const ArrayContainer = (props: IJsonContainerProps) => { if (index === activeEditIndex) { return { ...item, - [parserKeyMap[content.key]]: e.target.innerText, + [parserKey]: e.target.textContent || '', }; } else { return item; @@ -75,26 +66,28 @@ export const ArrayContainer = (props: IJsonContainerProps) => { useEffect(() => { if (activeEditIndex !== undefined && editDivRef.current) { editDivRef.current.focus(); - editDivRef.current.textContent = escapeNewlines( - content.value[activeEditIndex][parserKeyMap[content.key]], - ); + editDivRef.current.textContent = + content.value[activeEditIndex][parserKey]; } - }, [activeEditIndex, content]); + }, [editDivRef, activeEditIndex, content, parserKey]); return ( <> {content.value?.map((item, index) => { - if (item[parserKeyMap[content.key]] === '') { + if ( + item[parserKeyMap[content.key as keyof typeof parserKeyMap]] === '' + ) { return null; } return (
{isChunck && !isReadonly && ( { onBlur={handleSave} className={cn( 'w-full bg-transparent text-text-secondary border-none focus-visible:border-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:outline-none p-0', + className, )} >
@@ -120,7 +114,7 @@ export const ArrayContainer = (props: IJsonContainerProps) => { {activeEditIndex !== index && (
{ } }} > - {escapeNewlines(item[parserKeyMap[content.key]])} + {item[parserKeyMap[content.key]]}
)} diff --git a/web/src/pages/dataflow-result/components/parse-editer/object-parser.tsx b/web/src/pages/dataflow-result/components/parse-editer/object-parser.tsx index 938aed6e3..bfb4b33f5 100644 --- a/web/src/pages/dataflow-result/components/parse-editer/object-parser.tsx +++ b/web/src/pages/dataflow-result/components/parse-editer/object-parser.tsx @@ -25,22 +25,19 @@ export const ObjectContainer = (props: IObjContainerProps) => { editDivRef, } = useParserInit({ initialValue }); - const handleEdit = useCallback( - (e?: any) => { - setContent((pre) => ({ - ...pre, - value: escapeNewlines(e.target.innerText), - })); - setActiveEditIndex(1); - }, - [setContent, setActiveEditIndex], - ); + const handleEdit = useCallback(() => { + // setContent((pre) => ({ + // ...pre, + // value: escapeNewlines(e.target.innerText), + // })); + setActiveEditIndex(1); + }, [setContent, setActiveEditIndex]); const handleSave = useCallback( (e: any) => { const saveData = { ...content, - value: e.target.innerText, + value: e.target.textContent, }; onSave(saveData); setActiveEditIndex(undefined); @@ -51,9 +48,9 @@ export const ObjectContainer = (props: IObjContainerProps) => { useEffect(() => { if (activeEditIndex !== undefined && editDivRef.current) { editDivRef.current.focus(); - editDivRef.current.textContent = escapeNewlines(content.value); + editDivRef.current.textContent = content.value; } - }, [activeEditIndex, content, escapeNewlines]); + }, [activeEditIndex, content]); return ( <> @@ -90,7 +87,7 @@ export const ObjectContainer = (props: IObjContainerProps) => { } }} > - {escapeNewlines(content.value)} + {content.value}
)} diff --git a/web/src/pages/dataset/dataset-overview/index.tsx b/web/src/pages/dataset/dataset-overview/index.tsx index 623e7f780..39a89b80d 100644 --- a/web/src/pages/dataset/dataset-overview/index.tsx +++ b/web/src/pages/dataset/dataset-overview/index.tsx @@ -1,6 +1,7 @@ import { FilterCollection } from '@/components/list-filter-bar/interface'; import SvgIcon from '@/components/svg-icon'; import { useIsDarkTheme } from '@/components/theme-provider'; +import { AntToolTip } from '@/components/ui/tooltip'; import { useFetchDocumentList } from '@/hooks/use-document-request'; import { t } from 'i18next'; import { CircleQuestionMark } from 'lucide-react'; @@ -17,19 +18,30 @@ interface StatCardProps { value: number; icon: JSX.Element; children?: JSX.Element; + tooltip?: string; } interface CardFooterProcessProps { success: number; failed: number; } -const StatCard: FC = ({ title, value, children, icon }) => { +const StatCard: FC = ({ + title, + value, + children, + icon, + tooltip, +}) => { return (

{title} - + {tooltip && ( + + + + )}

{icon}
@@ -51,15 +63,19 @@ const CardFooterProcess: FC = ({
-
-
{t('knowledgeDetails.success')}
+
+
+ {t('knowledgeDetails.success')} +
{success || 0}
-
{t('knowledgeDetails.failed')}
+
+ {t('knowledgeDetails.failed')} +
{failed || 0}
@@ -189,7 +205,7 @@ const FileLogsPage: FC = () => { {/* Stats Cards */}
{ {topAllData.totalFiles.precent > 0 ? '+' : ''} {topAllData.totalFiles.precent}%{' '} - from last week + + from last week +
{ ) } + tooltip={t('datasetOverview.downloadTip')} > { /> { ) } + tooltip={t('datasetOverview.processingTip')} > - {t('chunkMethod')} + {t('dataPipeline')}
diff --git a/web/src/pages/dataset/dataset/parsing-status-cell.tsx b/web/src/pages/dataset/dataset/parsing-status-cell.tsx index 89319755c..b029ceed7 100644 --- a/web/src/pages/dataset/dataset/parsing-status-cell.tsx +++ b/web/src/pages/dataset/dataset/parsing-status-cell.tsx @@ -99,7 +99,7 @@ export function ParsingStatusCell({ - {t('knowledgeDetails.chunkMethod')} + {t('knowledgeDetails.dataPipeline')} {t('knowledgeDetails.setMetaData')} diff --git a/web/src/pages/dataset/sidebar/index.tsx b/web/src/pages/dataset/sidebar/index.tsx index 361b66ac1..c612f2059 100644 --- a/web/src/pages/dataset/sidebar/index.tsx +++ b/web/src/pages/dataset/sidebar/index.tsx @@ -1,3 +1,4 @@ +import { IconFontFill } from '@/components/icon-font'; import { RAGFlowAvatar } from '@/components/ragflow-avatar'; import { Button } from '@/components/ui/button'; import { useSecondPathName } from '@/hooks/route-hook'; @@ -9,13 +10,7 @@ import { cn, formatBytes } from '@/lib/utils'; import { Routes } from '@/routes'; import { formatPureDate } from '@/utils/date'; import { isEmpty } from 'lodash'; -import { - Banknote, - DatabaseZap, - FileSearch2, - FolderOpen, - GitGraph, -} from 'lucide-react'; +import { Banknote, DatabaseZap, FileSearch2, FolderOpen } from 'lucide-react'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useHandleMenuClick } from './hooks'; @@ -35,29 +30,29 @@ export function SideBar({ refreshCount }: PropType) { const items = useMemo(() => { const list = [ { - icon: DatabaseZap, + icon: , label: t(`knowledgeDetails.overview`), key: Routes.DataSetOverview, }, { - icon: FolderOpen, + icon: , label: t(`knowledgeDetails.subbarFiles`), key: Routes.DatasetBase, }, { - icon: FileSearch2, + icon: , label: t(`knowledgeDetails.testing`), key: Routes.DatasetTesting, }, { - icon: Banknote, + icon: , label: t(`knowledgeDetails.configuration`), key: Routes.DataSetSetting, }, ]; if (!isEmpty(routerData?.graph)) { list.push({ - icon: GitGraph, + icon: , label: t(`knowledgeDetails.knowledgeGraph`), key: Routes.KnowledgeGraph, }); @@ -105,7 +100,7 @@ export function SideBar({ refreshCount }: PropType) { )} onClick={handleMenuClick(item.key)} > - + {item.icon} {item.label} ); diff --git a/web/src/pages/datasets/dataset-creating-dialog.tsx b/web/src/pages/datasets/dataset-creating-dialog.tsx index 04442eab0..c2bbf3705 100644 --- a/web/src/pages/datasets/dataset-creating-dialog.tsx +++ b/web/src/pages/datasets/dataset-creating-dialog.tsx @@ -1,3 +1,4 @@ +import { DataFlowSelect } from '@/components/data-pipeline-select'; import { ButtonLoading } from '@/components/ui/button'; import { Dialog, @@ -18,11 +19,10 @@ import { Input } from '@/components/ui/input'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { IModalProps } from '@/interfaces/common'; import { zodResolver } from '@hookform/resolvers/zod'; +import { useEffect } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; - -import { DataFlowSelect } from '@/components/data-pipeline-select'; import { ChunkMethodItem, EmbeddingModelItem, @@ -95,6 +95,13 @@ export function InputForm({ onOk }: IModalProps) { control: form.control, name: 'parseType', }); + + useEffect(() => { + console.log('parseType', parseType); + if (parseType === 1) { + form.setValue('pipeline_id', ''); + } + }, [parseType, form]); const { navigateToAgents } = useNavigatePage(); return (