diff --git a/web/src/components/delimiter-form-field.tsx b/web/src/components/delimiter-form-field.tsx index 271721021..77fded5a3 100644 --- a/web/src/components/delimiter-form-field.tsx +++ b/web/src/components/delimiter-form-field.tsx @@ -1,3 +1,4 @@ +import { cn } from '@/lib/utils'; import { forwardRef } from 'react'; import { useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; @@ -36,6 +37,7 @@ export const DelimiterInput = forwardRef( maxLength={maxLength} defaultValue={defaultValue} ref={ref} + className={cn('bg-bg-base', props.className)} {...props} > ); diff --git a/web/src/components/ui/input.tsx b/web/src/components/ui/input.tsx index 303dc72e9..77f746814 100644 --- a/web/src/components/ui/input.tsx +++ b/web/src/components/ui/input.tsx @@ -31,7 +31,7 @@ const Input = React.forwardRef( {label} diff --git a/web/src/hooks/logic-hooks/navigate-hooks.ts b/web/src/hooks/logic-hooks/navigate-hooks.ts index 6f852ccfa..042489bac 100644 --- a/web/src/hooks/logic-hooks/navigate-hooks.ts +++ b/web/src/hooks/logic-hooks/navigate-hooks.ts @@ -24,6 +24,12 @@ export const useNavigatePage = () => { }, [navigate], ); + const navigateToDatasetOverview = useCallback( + (id: string) => () => { + navigate(`${Routes.DatasetBase}${Routes.DataSetOverview}/${id}`); + }, + [navigate], + ); const navigateToDataFile = useCallback( (id: string) => () => { @@ -160,6 +166,7 @@ export const useNavigatePage = () => { return { navigateToDatasetList, navigateToDataset, + navigateToDatasetOverview, navigateToHome, navigateToProfile, navigateToChatList, diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index c990b8b8d..5fcdf297a 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1672,6 +1672,7 @@ This delimiter is used to split the input text into several text pieces echo of page: '{{page}} /Page', }, dataflowParser: { + result: 'Result', parseSummary: 'Parse Summary', parseSummaryTip: 'Parser:deepdoc', rerunFromCurrentStep: 'Rerun From Current Step', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 119aad5d6..1cce50cc2 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1588,6 +1588,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 page: '{{page}}条/页', }, dataflowParser: { + result: '结果', parseSummary: '解析摘要', parseSummaryTip: '解析器: deepdoc', rerunFromCurrentStep: '从当前步骤重新运行', diff --git a/web/src/pages/dataflow-result/components/parse-editer/interface.ts b/web/src/pages/dataflow-result/components/parse-editer/interface.ts index e45d20972..9da06fd97 100644 --- a/web/src/pages/dataflow-result/components/parse-editer/interface.ts +++ b/web/src/pages/dataflow-result/components/parse-editer/interface.ts @@ -1,6 +1,6 @@ import { CheckedState } from '@radix-ui/react-checkbox'; import { ChunkTextMode } from '../../constant'; -import { IChunk } from '../../interface'; +import { ComponentParams, IChunk } from '../../interface'; import { parserKeyMap } from './json-parser'; export interface FormatPreserveEditorProps { @@ -28,6 +28,7 @@ export type IJsonContainerProps = { value: { [key: string]: string; }[]; + params: ComponentParams; }; isChunck?: boolean; handleCheck: (e: CheckedState, index: number) => void; @@ -52,6 +53,7 @@ export type IObjContainerProps = { key: string; type: string; value: string; + params: ComponentParams; }; isChunck?: boolean; handleCheck: (e: CheckedState, index: number) => void; 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 e86999b78..7af1269b8 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 @@ -1,6 +1,7 @@ import { Checkbox } from '@/components/ui/checkbox'; import { cn } from '@/lib/utils'; -import { useCallback, useEffect } from 'react'; +import { isArray } from 'lodash'; +import { useCallback, useEffect, useMemo } from 'react'; import { ChunkTextMode } from '../../constant'; import styles from '../../index.less'; import { useParserInit } from './hook'; @@ -33,7 +34,13 @@ export const ArrayContainer = (props: IJsonContainerProps) => { editDivRef, } = useParserInit({ initialValue }); - const parserKey = parserKeyMap[content.key as keyof typeof parserKeyMap]; + const parserKey = useMemo(() => { + const key = + content.key === 'chunks' && content.params.field_name + ? content.params.field_name + : parserKeyMap[content.key as keyof typeof parserKeyMap]; + return key; + }, [content]); const handleEdit = useCallback( (e?: any, index?: number) => { @@ -73,67 +80,68 @@ export const ArrayContainer = (props: IJsonContainerProps) => { return ( <> - {content.value?.map((item, index) => { - if ( - item[parserKeyMap[content.key as keyof typeof parserKeyMap]] === '' - ) { - return null; - } - return ( -
- {isChunck && !isReadonly && ( - { - handleCheck(e, index); - }} - checked={selectedChunkIds?.some( - (id) => id.toString() === index.toString(), - )} - > - )} - {activeEditIndex === index && ( -
{ + if ( + item[parserKeyMap[content.key as keyof typeof parserKeyMap]] === '' + ) { + return null; + } + return ( +
+ {isChunck && !isReadonly && ( + { + handleCheck(e, index); + }} + checked={selectedChunkIds?.some( + (id) => id.toString() === index.toString(), + )} + > + )} + {activeEditIndex === index && ( +
- )} - {activeEditIndex !== index && ( -
{ - clickChunk(item); - if (!isReadonly) { - handleEdit(e, index); - } - }} - > - {item[parserKeyMap[content.key]]} -
- )} -
- ); - })} + className, + )} + >
+ )} + {activeEditIndex !== index && ( +
{ + clickChunk(item); + if (!isReadonly) { + handleEdit(e, index); + } + }} + > + {item[parserKey]} +
+ )} +
+ ); + })} ); }; diff --git a/web/src/pages/dataflow-result/hooks.ts b/web/src/pages/dataflow-result/hooks.ts index 8b984d8d8..cd782067a 100644 --- a/web/src/pages/dataflow-result/hooks.ts +++ b/web/src/pages/dataflow-result/hooks.ts @@ -218,18 +218,11 @@ export const useTimelineDataFlow = (data: IPipelineFileLogDetail) => { const nodes: Array = []; console.log('time-->', data); const times = data?.dsl?.components; + const graphNodes = data?.dsl?.graph?.nodes; if (times) { - const getNode = ( - key: string, - index: number, - type: - | TimelineNodeType.begin - | TimelineNodeType.parser - | TimelineNodeType.tokenizer - | TimelineNodeType.characterSplitter - | TimelineNodeType.titleSplitter, - ) => { + const getNode = (key: string, index: number, type: TimelineNodeType) => { const node = times[key].obj; + const graphNode = graphNodes?.find((item) => item.id === key); const name = camelCase( node.component_name, ) as keyof typeof TimelineNodeObj; @@ -247,6 +240,7 @@ export const useTimelineDataFlow = (data: IPipelineFileLogDetail) => { } const timeNode = { ...TimelineNodeObj[name], + title: graphNode?.data?.name, id: index, className: 'w-32', completed: false, @@ -255,6 +249,13 @@ export const useTimelineDataFlow = (data: IPipelineFileLogDetail) => { ), type: tempType, detail: { value: times[key], key: key }, + } as ITimelineNodeObj & { + id: number | string; + className: string; + completed: boolean; + date: string; + type: TimelineNodeType; + detail: { value: IDslComponent; key: string }; }; console.log('timeNodetype-->', type); nodes.push(timeNode); @@ -329,3 +330,30 @@ export function useFetchPipelineResult({ return { pipelineResult }; } + +export const useSummaryInfo = ( + data: IPipelineFileLogDetail, + currentTimeNode: TimelineNode, +) => { + const summaryInfo = useMemo(() => { + if (currentTimeNode.type === TimelineNodeType.parser) { + const setups = + currentTimeNode.detail?.value?.obj?.params?.setups?.[ + data.document_suffix + ]; + if (setups) { + const { output_format, parse_method } = setups; + const res = []; + if (parse_method) { + res.push(`${t('dataflow.parserMethod')}: ${parse_method}`); + } + if (output_format) { + res.push(`${t('dataflow.outputFormat')}: ${output_format}`); + } + return res.join(' '); + } + } + return ''; + }, [data, currentTimeNode]); + return { summaryInfo }; +}; diff --git a/web/src/pages/dataflow-result/index.tsx b/web/src/pages/dataflow-result/index.tsx index a2d2fe913..00eddff14 100644 --- a/web/src/pages/dataflow-result/index.tsx +++ b/web/src/pages/dataflow-result/index.tsx @@ -9,6 +9,7 @@ import { useGetPipelineResultSearchParams, useHandleChunkCardClick, useRerunDataflow, + useSummaryInfo, useTimelineDataFlow, } from './hooks'; @@ -61,7 +62,7 @@ const Chunk = () => { ); const { - navigateToDataset, + navigateToDatasetOverview, navigateToDatasetList, navigateToAgents, navigateToDataflow, @@ -150,7 +151,7 @@ const Chunk = () => { ({} as TimelineNode) ); }, [activeStepId, timelineNodes]); - + const { summaryInfo } = useSummaryInfo(dataset, currentTimeNode); return ( <> @@ -175,7 +176,7 @@ const Chunk = () => { { if (knowledgeId) { - navigateToDataset(knowledgeId)(); + navigateToDatasetOverview(knowledgeId)(); } if (agentId) { navigateToDataflow(agentId)(); @@ -220,7 +221,7 @@ const Chunk = () => { > -
+
{/* {currentTimeNode?.type === TimelineNodeType.splitter && ( { key: string; } } + summaryInfo={summaryInfo} clickChunk={handleChunkCardClick} reRunFunc={handleReRunFunc} /> diff --git a/web/src/pages/dataflow-result/interface.ts b/web/src/pages/dataflow-result/interface.ts index 865044ce2..df3c758c1 100644 --- a/web/src/pages/dataflow-result/interface.ts +++ b/web/src/pages/dataflow-result/interface.ts @@ -1,6 +1,6 @@ import { PipelineResultSearchParams } from './constant'; -interface ComponentParams { +export interface ComponentParams { debug_inputs: Record; delay_after_error: number; description: string; @@ -8,6 +8,7 @@ interface ComponentParams { exception_goto: any; exception_method: any; inputs: Record; + field_name: string; max_retries: number; message_history_window_size: number; outputs: { @@ -30,6 +31,66 @@ export interface IDslComponent { obj: ComponentObject; upstream: Array; } + +interface NodeData { + label: string; + name: string; + form?: { + outputs?: Record< + string, + { + type: string; + value: string | Array> | number; + } + >; + setups?: Array>; + chunk_token_size?: number; + delimiters?: Array<{ + value: string; + }>; + overlapped_percent?: number; + }; +} + +interface EdgeData { + isHovered: boolean; +} + +interface Position { + x: number; + y: number; +} + +interface Measured { + height: number; + width: number; +} + +interface Node { + data: NodeData; + dragging: boolean; + id: string; + measured: Measured; + position: Position; + selected: boolean; + sourcePosition: string; + targetPosition: string; + type: string; +} + +interface Edge { + data: EdgeData; + id: string; + source: string; + sourceHandle: string; + target: string; + targetHandle: string; +} +interface GraphData { + edges: Edge[]; + nodes: Node[]; +} + export interface IPipelineFileLogDetail { avatar: string; create_date: string; @@ -42,6 +103,7 @@ export interface IPipelineFileLogDetail { components: { [key: string]: IDslComponent; }; + graph: GraphData; task_id: string; path: Array; }; diff --git a/web/src/pages/dataflow-result/parser.tsx b/web/src/pages/dataflow-result/parser.tsx index 41f4e2a39..70d2b0253 100644 --- a/web/src/pages/dataflow-result/parser.tsx +++ b/web/src/pages/dataflow-result/parser.tsx @@ -19,6 +19,7 @@ interface IProps { data: { value: IDslComponent; key: string }; reRunLoading: boolean; clickChunk: (chunk: IChunk) => void; + summaryInfo: string; reRunFunc: (data: { value: IDslComponent; key: string }) => void; } const ParserContainer = (props: IProps) => { @@ -31,6 +32,7 @@ const ParserContainer = (props: IProps) => { reRunLoading, clickChunk, isReadonly, + summaryInfo, } = props; const { t } = useTranslation(); const [selectedChunkIds, setSelectedChunkIds] = useState([]); @@ -46,6 +48,7 @@ const ParserContainer = (props: IProps) => { key, type, value, + params: data?.value?.obj?.params, }; }, [data]); @@ -130,7 +133,7 @@ const ParserContainer = (props: IProps) => { const newText = [...initialText.value, { text: text || ' ' }]; setInitialText({ ...initialText, - value: newText, + value: newText as any, }); }, [initialText], @@ -156,15 +159,16 @@ const ParserContainer = (props: IProps) => { {t('dataflowParser.parseSummary')}
- {t('dataflowParser.parseSummaryTip')} + {/* {t('dataflowParser.parseSummaryTip')} */} + {summaryInfo}
)} {isChunck && (
-

{t('chunk.chunkResult')}

+

{t('dataflowParser.result')}

- {t('chunk.chunkResultTip')} + {/* {t('chunk.chunkResultTip')} */}
)} diff --git a/web/src/pages/dataset/dataset-setting/configuration/naive.tsx b/web/src/pages/dataset/dataset-setting/configuration/naive.tsx index fd1b522df..d08e30aa8 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/naive.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/naive.tsx @@ -6,7 +6,6 @@ import { DelimiterFormField } from '@/components/delimiter-form-field'; import { ExcelToHtmlFormField } from '@/components/excel-to-html-form-field'; import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field'; import { MaxTokenNumberFormField } from '@/components/max-token-number-from-field'; -import { TagItems } from '../components/tag-item'; import { ConfigurationFormContainer, MainContainer, @@ -26,7 +25,7 @@ export function NaiveConfiguration() { - + {/* */} );