From b5960bf525ddcb49c79997ccd7e462941ea3364b Mon Sep 17 00:00:00 2001 From: Mminamiyama Date: Sat, 28 Jun 2025 16:19:32 +0800 Subject: [PATCH] style(workflow): fix line endings and formatting in node panel component --- web/app/components/workflow/run/node.tsx | 586 +++++++++++------------ 1 file changed, 293 insertions(+), 293 deletions(-) diff --git a/web/app/components/workflow/run/node.tsx b/web/app/components/workflow/run/node.tsx index bebceb68ed..f99c4bfd44 100644 --- a/web/app/components/workflow/run/node.tsx +++ b/web/app/components/workflow/run/node.tsx @@ -1,293 +1,293 @@ -'use client' -import { useTranslation } from 'react-i18next' -import type { FC } from 'react' -import { useCallback, useContext, useEffect, useMemo, useState } from 'react' -import { - RiAlertFill, - RiArrowRightSLine, - RiCheckboxCircleFill, - RiErrorWarningLine, - RiLoader2Line, -} from '@remixicon/react' -import BlockIcon from '../block-icon' -import { BlockEnum } from '../types' -import { RetryLogTrigger } from './retry-log' -import { IterationLogTrigger } from './iteration-log' -import { LoopLogTrigger } from './loop-log' -import { AgentLogTrigger } from './agent-log' -import cn from '@/utils/classnames' -import StatusContainer from '@/app/components/workflow/run/status-container' -import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' -import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' -import type { - AgentLogItemWithChildren, - IterationDurationMap, - LoopDurationMap, - LoopVariableMap, - NodeTracing, -} from '@/types/workflow' -import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip' -import { hasRetryNode } from '@/app/components/workflow/utils' -import { useDocLink } from '@/context/i18n' -import Tooltip from '@/app/components/base/tooltip' -import NodePosition from '@/app/components/workflow/nodes/_base/components/node-position' -import type { XYPosition } from 'reactflow' -import { WorkflowHistoryStoreContext } from '@/app/components/workflow/workflow-history-store' - -type Props = { - className?: string - nodeInfo: NodeTracing - allExecutions?: NodeTracing[] - inMessage?: boolean - hideInfo?: boolean - hideProcessDetail?: boolean - onShowIterationDetail?: (detail: NodeTracing[][], iterDurationMap: IterationDurationMap) => void - onShowLoopDetail?: (detail: NodeTracing[][], loopDurationMap: LoopDurationMap, loopVariableMap: LoopVariableMap) => void - onShowRetryDetail?: (detail: NodeTracing[]) => void - onShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void - notShowIterationNav?: boolean - notShowLoopNav?: boolean -} - -const NodePanel: FC = ({ - className, - nodeInfo, - allExecutions, - inMessage = false, - hideInfo = false, - hideProcessDetail, - onShowIterationDetail, - onShowLoopDetail, - onShowRetryDetail, - onShowAgentOrToolLog, - notShowIterationNav, - notShowLoopNav, -}) => { - const { store } = useContext(WorkflowHistoryStoreContext) - let inPublishMode = true - let hasNode = false - let nodePosition: XYPosition = { x: 0, y: 0 } - let nodeWidth = 0 - let nodeHeight = 0 - - if (store) { - inPublishMode = false - const nodes = store.getState().nodes - const currentNodeIndex = nodes.findIndex(node => node.id === nodeInfo.node_id) - const currentNode = nodes[currentNodeIndex] - nodePosition = currentNode?.position ?? { x: -1, y: -1 } - nodeWidth = currentNode?.width ?? -1 - nodeHeight = currentNode?.height ?? -1 - hasNode = !!currentNode - } - - const [collapseState, doSetCollapseState] = useState(true) - const setCollapseState = useCallback((state: boolean) => { - if (hideProcessDetail) - return - doSetCollapseState(state) - }, [hideProcessDetail]) - const { t } = useTranslation() - const docLink = useDocLink() - - const getTime = (time: number) => { - if (time < 1) - return `${(time * 1000).toFixed(3)} ms` - if (time > 60) - return `${Number.parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s` - return `${time.toFixed(3)} s` - } - - const getTokenCount = (tokens: number) => { - if (tokens < 1000) - return tokens - if (tokens >= 1000 && tokens < 1000000) - return `${Number.parseFloat((tokens / 1000).toFixed(3))}K` - if (tokens >= 1000000) - return `${Number.parseFloat((tokens / 1000000).toFixed(3))}M` - } - - useEffect(() => { - setCollapseState(!nodeInfo.expand) - }, [nodeInfo.expand, setCollapseState]) - - const isIterationNode = nodeInfo.node_type === BlockEnum.Iteration && !!nodeInfo.details?.length - const isLoopNode = nodeInfo.node_type === BlockEnum.Loop && !!nodeInfo.details?.length - const isRetryNode = hasRetryNode(nodeInfo.node_type) && !!nodeInfo.retryDetail?.length - const isAgentNode = nodeInfo.node_type === BlockEnum.Agent && !!nodeInfo.agentLog?.length - const isToolNode = nodeInfo.node_type === BlockEnum.Tool && !!nodeInfo.agentLog?.length - - const inputsTitle = useMemo(() => { - let text = t('workflow.common.input') - if (nodeInfo.node_type === BlockEnum.Loop) - text = t('workflow.nodes.loop.initialLoopVariables') - return text.toLocaleUpperCase() - }, [nodeInfo.node_type, t]) - const processDataTitle = t('workflow.common.processData').toLocaleUpperCase() - const outputTitle = useMemo(() => { - let text = t('workflow.common.output') - if (nodeInfo.node_type === BlockEnum.Loop) - text = t('workflow.nodes.loop.finalLoopVariables') - return text.toLocaleUpperCase() - }, [nodeInfo.node_type, t]) - - return ( -
-
-
setCollapseState(!collapseState)} - > - {!hideProcessDetail && ( - - )} - - {nodeInfo.title}
- } - > -
{nodeInfo.title}
- - {nodeInfo.status !== 'running' && !hideInfo && ( -
{nodeInfo.execution_metadata?.total_tokens ? `${getTokenCount(nodeInfo.execution_metadata?.total_tokens || 0)} tokens · ` : ''}{`${getTime(nodeInfo.elapsed_time || 0)}`}
- )} - {nodeInfo.status === 'succeeded' && ( - - )} - {nodeInfo.status === 'failed' && ( - - )} - {nodeInfo.status === 'stopped' && ( - - )} - {nodeInfo.status === 'exception' && ( - - )} - {nodeInfo.status === 'running' && ( -
- Running - -
- )} - {!inPublishMode && ( -
- -
- )} -
- {!collapseState && !hideProcessDetail && ( -
- {/* The nav to the iteration detail */} - {isIterationNode && !notShowIterationNav && onShowIterationDetail && ( - - )} - {/* The nav to the Loop detail */} - {isLoopNode && !notShowLoopNav && onShowLoopDetail && ( - - )} - {isRetryNode && onShowRetryDetail && ( - - )} - { - (isAgentNode || isToolNode) && onShowAgentOrToolLog && ( - - ) - } -
- {(nodeInfo.status === 'stopped') && ( - - {t('workflow.tracing.stopBy', { user: nodeInfo.created_by ? nodeInfo.created_by.name : 'N/A' })} - - )} - {(nodeInfo.status === 'exception') && ( - - {nodeInfo.error} - - {t('workflow.common.learnMore')} - - - )} - {nodeInfo.status === 'failed' && ( - - {nodeInfo.error} - - )} - {nodeInfo.status === 'retry' && ( - - {nodeInfo.error} - - )} -
- {nodeInfo.inputs && ( -
- {inputsTitle}
} - language={CodeLanguage.json} - value={nodeInfo.inputs} - isJSONStringifyBeauty - /> -
- )} - {nodeInfo.process_data && ( -
- {processDataTitle}
} - language={CodeLanguage.json} - value={nodeInfo.process_data} - isJSONStringifyBeauty - /> -
- )} - {nodeInfo.outputs && ( -
- {outputTitle}
} - language={CodeLanguage.json} - value={nodeInfo.outputs} - isJSONStringifyBeauty - tip={} - /> - - )} - - )} - - - ) -} - -export default NodePanel +'use client' +import { useTranslation } from 'react-i18next' +import type { FC } from 'react' +import { useCallback, useContext, useEffect, useMemo, useState } from 'react' +import { + RiAlertFill, + RiArrowRightSLine, + RiCheckboxCircleFill, + RiErrorWarningLine, + RiLoader2Line, +} from '@remixicon/react' +import BlockIcon from '../block-icon' +import { BlockEnum } from '../types' +import { RetryLogTrigger } from './retry-log' +import { IterationLogTrigger } from './iteration-log' +import { LoopLogTrigger } from './loop-log' +import { AgentLogTrigger } from './agent-log' +import cn from '@/utils/classnames' +import StatusContainer from '@/app/components/workflow/run/status-container' +import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' +import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' +import type { + AgentLogItemWithChildren, + IterationDurationMap, + LoopDurationMap, + LoopVariableMap, + NodeTracing, +} from '@/types/workflow' +import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip' +import { hasRetryNode } from '@/app/components/workflow/utils' +import { useDocLink } from '@/context/i18n' +import Tooltip from '@/app/components/base/tooltip' +import NodePosition from '@/app/components/workflow/nodes/_base/components/node-position' +import type { XYPosition } from 'reactflow' +import { WorkflowHistoryStoreContext } from '@/app/components/workflow/workflow-history-store' + +type Props = { + className?: string + nodeInfo: NodeTracing + allExecutions?: NodeTracing[] + inMessage?: boolean + hideInfo?: boolean + hideProcessDetail?: boolean + onShowIterationDetail?: (detail: NodeTracing[][], iterDurationMap: IterationDurationMap) => void + onShowLoopDetail?: (detail: NodeTracing[][], loopDurationMap: LoopDurationMap, loopVariableMap: LoopVariableMap) => void + onShowRetryDetail?: (detail: NodeTracing[]) => void + onShowAgentOrToolLog?: (detail?: AgentLogItemWithChildren) => void + notShowIterationNav?: boolean + notShowLoopNav?: boolean +} + +const NodePanel: FC = ({ + className, + nodeInfo, + allExecutions, + inMessage = false, + hideInfo = false, + hideProcessDetail, + onShowIterationDetail, + onShowLoopDetail, + onShowRetryDetail, + onShowAgentOrToolLog, + notShowIterationNav, + notShowLoopNav, +}) => { + const { store } = useContext(WorkflowHistoryStoreContext) + let inPublishMode = true + let hasNode = false + let nodePosition: XYPosition = { x: 0, y: 0 } + let nodeWidth = 0 + let nodeHeight = 0 + + if (store) { + inPublishMode = false + const nodes = store.getState().nodes + const currentNodeIndex = nodes.findIndex(node => node.id === nodeInfo.node_id) + const currentNode = nodes[currentNodeIndex] + nodePosition = currentNode?.position ?? { x: -1, y: -1 } + nodeWidth = currentNode?.width ?? -1 + nodeHeight = currentNode?.height ?? -1 + hasNode = !!currentNode + } + + const [collapseState, doSetCollapseState] = useState(true) + const setCollapseState = useCallback((state: boolean) => { + if (hideProcessDetail) + return + doSetCollapseState(state) + }, [hideProcessDetail]) + const { t } = useTranslation() + const docLink = useDocLink() + + const getTime = (time: number) => { + if (time < 1) + return `${(time * 1000).toFixed(3)} ms` + if (time > 60) + return `${Number.parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s` + return `${time.toFixed(3)} s` + } + + const getTokenCount = (tokens: number) => { + if (tokens < 1000) + return tokens + if (tokens >= 1000 && tokens < 1000000) + return `${Number.parseFloat((tokens / 1000).toFixed(3))}K` + if (tokens >= 1000000) + return `${Number.parseFloat((tokens / 1000000).toFixed(3))}M` + } + + useEffect(() => { + setCollapseState(!nodeInfo.expand) + }, [nodeInfo.expand, setCollapseState]) + + const isIterationNode = nodeInfo.node_type === BlockEnum.Iteration && !!nodeInfo.details?.length + const isLoopNode = nodeInfo.node_type === BlockEnum.Loop && !!nodeInfo.details?.length + const isRetryNode = hasRetryNode(nodeInfo.node_type) && !!nodeInfo.retryDetail?.length + const isAgentNode = nodeInfo.node_type === BlockEnum.Agent && !!nodeInfo.agentLog?.length + const isToolNode = nodeInfo.node_type === BlockEnum.Tool && !!nodeInfo.agentLog?.length + + const inputsTitle = useMemo(() => { + let text = t('workflow.common.input') + if (nodeInfo.node_type === BlockEnum.Loop) + text = t('workflow.nodes.loop.initialLoopVariables') + return text.toLocaleUpperCase() + }, [nodeInfo.node_type, t]) + const processDataTitle = t('workflow.common.processData').toLocaleUpperCase() + const outputTitle = useMemo(() => { + let text = t('workflow.common.output') + if (nodeInfo.node_type === BlockEnum.Loop) + text = t('workflow.nodes.loop.finalLoopVariables') + return text.toLocaleUpperCase() + }, [nodeInfo.node_type, t]) + + return ( +
+
+
setCollapseState(!collapseState)} + > + {!hideProcessDetail && ( + + )} + + {nodeInfo.title}
+ } + > +
{nodeInfo.title}
+ + {nodeInfo.status !== 'running' && !hideInfo && ( +
{nodeInfo.execution_metadata?.total_tokens ? `${getTokenCount(nodeInfo.execution_metadata?.total_tokens || 0)} tokens · ` : ''}{`${getTime(nodeInfo.elapsed_time || 0)}`}
+ )} + {nodeInfo.status === 'succeeded' && ( + + )} + {nodeInfo.status === 'failed' && ( + + )} + {nodeInfo.status === 'stopped' && ( + + )} + {nodeInfo.status === 'exception' && ( + + )} + {nodeInfo.status === 'running' && ( +
+ Running + +
+ )} + {!inPublishMode && ( +
+ +
+ )} +
+ {!collapseState && !hideProcessDetail && ( +
+ {/* The nav to the iteration detail */} + {isIterationNode && !notShowIterationNav && onShowIterationDetail && ( + + )} + {/* The nav to the Loop detail */} + {isLoopNode && !notShowLoopNav && onShowLoopDetail && ( + + )} + {isRetryNode && onShowRetryDetail && ( + + )} + { + (isAgentNode || isToolNode) && onShowAgentOrToolLog && ( + + ) + } +
+ {(nodeInfo.status === 'stopped') && ( + + {t('workflow.tracing.stopBy', { user: nodeInfo.created_by ? nodeInfo.created_by.name : 'N/A' })} + + )} + {(nodeInfo.status === 'exception') && ( + + {nodeInfo.error} + + {t('workflow.common.learnMore')} + + + )} + {nodeInfo.status === 'failed' && ( + + {nodeInfo.error} + + )} + {nodeInfo.status === 'retry' && ( + + {nodeInfo.error} + + )} +
+ {nodeInfo.inputs && ( +
+ {inputsTitle}
} + language={CodeLanguage.json} + value={nodeInfo.inputs} + isJSONStringifyBeauty + /> +
+ )} + {nodeInfo.process_data && ( +
+ {processDataTitle}
} + language={CodeLanguage.json} + value={nodeInfo.process_data} + isJSONStringifyBeauty + /> +
+ )} + {nodeInfo.outputs && ( +
+ {outputTitle}
} + language={CodeLanguage.json} + value={nodeInfo.outputs} + isJSONStringifyBeauty + tip={} + /> + + )} + + )} + + + ) +} + +export default NodePanel