diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx index 8c160b48a..2825c40de 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx @@ -23,22 +23,12 @@ import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/cons import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useWorkflowUtils } from '../../hooks/useUtils'; -import { WholeResponseContent } from '@/components/core/chat/components/WholeResponseModal'; import { WorkflowNodeEdgeContext } from '../../../context/workflowInitContext'; import { WorkflowEventContext } from '../../../context/workflowEventContext'; import MyImage from '@fastgpt/web/components/common/Image/MyImage'; import MyIconButton from '@fastgpt/web/components/common/Icon/button'; import UseGuideModal from '@/components/common/Modal/UseGuideModal'; -import { - RenderUserSelectInteractive, - RenderUserFormInteractive -} from '@/components/core/chat/components/InteractiveComponents'; -import { - InteractiveBasicType, - UserInputInteractive, - UserSelectInteractive, - WorkflowInteractiveResponseType -} from '@fastgpt/global/core/workflow/template/system/interactive/type'; +import NodeDebugResponse from './RenderDebug/NodeDebugResponse'; type Props = FlowNodeItemType & { children?: React.ReactNode | React.ReactNode[] | string; @@ -672,231 +662,3 @@ const NodeIntro = React.memo(function NodeIntro({ return Render; }); - -const NodeDebugResponse = React.memo(function NodeDebugResponse({ - nodeId, - debugResult -}: { - nodeId: string; - debugResult: FlowNodeItemType['debugResult']; -}) { - const { t } = useTranslation(); - const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); - - // 获取当前节点 - const node = useMemo(() => nodeList.find((node) => node.nodeId === nodeId), [nodeList, nodeId]); - const firstInteractive = useMemo(() => { - if ( - node && - node.flowNodeType === FlowNodeTypeEnum.userSelect && - !node.debugResult?.response?.userSelectResult - ) { - return true; - } - if ( - node && - node.flowNodeType === FlowNodeTypeEnum.formInput && - !node.debugResult?.response?.formInputResult - ) { - return true; - } - return false; // 明确返回值 - }, [node]); - - const { onChangeNode, onStopNodeDebug, onNextNodeDebug, workflowDebugData } = useContextSelector( - WorkflowContext, - (v) => v - ); - - const interactive: UserSelectInteractive | UserInputInteractive | undefined = useMemo(() => { - const description = node?.inputs?.find((input) => input.key === 'description')?.value; - const userSelectOptions = node?.inputs?.find( - (input) => input.key === 'userSelectOptions' - )?.value; - const formInputForms = node?.inputs?.find((input) => input.key === 'userInputForms')?.value; - if (node?.flowNodeType === FlowNodeTypeEnum.userSelect) { - return { - type: 'userSelect', - params: { - description, - userSelectOptions - } - }; - } - if (node?.flowNodeType === FlowNodeTypeEnum.formInput) { - return { - type: 'userInput', - params: { - description, - inputForm: formInputForms - } - }; - } - return undefined; - }, [node]); - - const { openConfirm, ConfirmModal } = useConfirm({ - content: t('common:core.workflow.Confirm stop debug') - }); - - const RenderStatus = useMemo(() => { - const map = { - running: { - bg: 'primary.50', - text: t('common:core.workflow.Running'), - icon: 'core/workflow/running' - }, - success: { - bg: 'green.50', - text: t('common:core.workflow.Success'), - icon: 'core/workflow/runSuccess' - }, - failed: { - bg: 'red.50', - text: t('common:core.workflow.Failed'), - icon: 'core/workflow/runError' - }, - skipped: { - bg: 'myGray.50', - text: t('common:core.workflow.Skipped'), - icon: 'core/workflow/runSkip' - } - }; - - const statusData = map[debugResult?.status || 'running']; - - const response = debugResult?.response; - - const onStop = () => { - openConfirm(onStopNodeDebug)(); - }; - - return !!debugResult && !!statusData ? ( - <> - - - - {statusData.text} - - {debugResult.status !== 'running' && ( - - onChangeNode({ - nodeId, - type: 'attr', - key: 'debugResult', - value: { - ...debugResult, - showResult: !debugResult.showResult - } - }) - } - > - {debugResult.showResult - ? t('common:core.workflow.debug.Hide result') - : t('common:core.workflow.debug.Show result')} - - )} - - {/* Result card */} - {debugResult.showResult && ( - - {/* Status header */} - - - - {t('common:core.workflow.debug.Run result')} - - {workflowDebugData?.nextRunNodes.length !== 0 && ( - - )} - {(debugResult.status === 'success' || debugResult.status === 'skipped') && - !firstInteractive && - !debugResult.isExpired && - workflowDebugData?.nextRunNodes && - workflowDebugData.nextRunNodes.length > 0 && ( - - )} - {!firstInteractive && - workflowDebugData?.nextRunNodes && - workflowDebugData?.nextRunNodes.length === 0 && ( - - )} - - {/* Response list */} - {debugResult.status !== 'skipped' && ( - - {!debugResult.message && !response && !firstInteractive && ( - - )} - {debugResult.message && ( - - {debugResult.message} - - )} - {firstInteractive && interactive && ( - <> - {interactive.type === 'userSelect' && ( - - )} - {interactive.type === 'userInput' && ( - - )} - - )} - {response && } - - )} - - )} - - ) : null; - }, [ - interactive, - firstInteractive, - debugResult, - nodeId, - onChangeNode, - onNextNodeDebug, - onStopNodeDebug, - openConfirm, - t, - workflowDebugData - ]); - - return ( - <> - {RenderStatus} - - - ); -}); diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx new file mode 100644 index 000000000..6d43164d3 --- /dev/null +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx @@ -0,0 +1,248 @@ +import React, { useMemo } from 'react'; +import { Box, Button, Card, Flex } from '@chakra-ui/react'; +import { useTranslation } from 'next-i18next'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; +import { useContextSelector } from 'use-context-selector'; +import { WorkflowContext } from '../../../../context'; +import { WorkflowEventContext } from '../../../../context/workflowEventContext'; +import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; +import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; +import { WholeResponseContent } from '@/components/core/chat/components/WholeResponseModal'; +import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d'; +import { + RenderUserSelectInteractive, + RenderUserFormInteractive +} from '@/components/core/chat/components/InteractiveComponents'; +import { + UserInputInteractive, + UserSelectInteractive +} from '@fastgpt/global/core/workflow/template/system/interactive/type'; + +interface NodeDebugResponseProps { + nodeId: string; + debugResult: FlowNodeItemType['debugResult']; +} + +const NodeDebugResponse = ({ nodeId, debugResult }: NodeDebugResponseProps) => { + const { t } = useTranslation(); + const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); + + const node = useMemo(() => nodeList.find((node) => node.nodeId === nodeId), [nodeList, nodeId]); + const firstInteractive = useMemo(() => { + if ( + node && + node.flowNodeType === FlowNodeTypeEnum.userSelect && + !node.debugResult?.response?.userSelectResult + ) { + return true; + } + if ( + node && + node.flowNodeType === FlowNodeTypeEnum.formInput && + !node.debugResult?.response?.formInputResult + ) { + return true; + } + return false; + }, [node]); + + const { onChangeNode, onStopNodeDebug, onNextNodeDebug, workflowDebugData } = useContextSelector( + WorkflowContext, + (v) => v + ); + + const interactive: UserSelectInteractive | UserInputInteractive | undefined = useMemo(() => { + const description = node?.inputs?.find((input) => input.key === 'description')?.value; + const userSelectOptions = node?.inputs?.find( + (input) => input.key === 'userSelectOptions' + )?.value; + const formInputForms = node?.inputs?.find((input) => input.key === 'userInputForms')?.value; + if (node?.flowNodeType === FlowNodeTypeEnum.userSelect) { + return { + type: 'userSelect', + params: { + description, + userSelectOptions + } + }; + } + if (node?.flowNodeType === FlowNodeTypeEnum.formInput) { + return { + type: 'userInput', + params: { + description, + inputForm: formInputForms + } + }; + } + return undefined; + }, [node]); + + const { openConfirm, ConfirmModal } = useConfirm({ + content: t('common:core.workflow.Confirm stop debug') + }); + + const RenderStatus = useMemo(() => { + const map = { + running: { + bg: 'primary.50', + text: t('common:core.workflow.Running'), + icon: 'core/workflow/running' + }, + success: { + bg: 'green.50', + text: t('common:core.workflow.Success'), + icon: 'core/workflow/runSuccess' + }, + failed: { + bg: 'red.50', + text: t('common:core.workflow.Failed'), + icon: 'core/workflow/runError' + }, + skipped: { + bg: 'myGray.50', + text: t('common:core.workflow.Skipped'), + icon: 'core/workflow/runSkip' + } + }; + + const statusData = map[debugResult?.status || 'running']; + + const response = debugResult?.response; + + const onStop = () => { + openConfirm(onStopNodeDebug)(); + }; + + return !!debugResult && !!statusData ? ( + <> + + + + {statusData.text} + + {debugResult.status !== 'running' && ( + + onChangeNode({ + nodeId, + type: 'attr', + key: 'debugResult', + value: { + ...debugResult, + showResult: !debugResult.showResult + } + }) + } + > + {debugResult.showResult + ? t('common:core.workflow.debug.Hide result') + : t('common:core.workflow.debug.Show result')} + + )} + + {/* Result card */} + {debugResult.showResult && ( + + {/* Status header */} + + + + {t('common:core.workflow.debug.Run result')} + + {workflowDebugData?.nextRunNodes.length !== 0 && ( + + )} + {(debugResult.status === 'success' || debugResult.status === 'skipped') && + !firstInteractive && + !debugResult.isExpired && + workflowDebugData?.nextRunNodes && + workflowDebugData.nextRunNodes.length > 0 && ( + + )} + {!firstInteractive && + workflowDebugData?.nextRunNodes && + workflowDebugData?.nextRunNodes.length === 0 && ( + + )} + + {/* Response list */} + {debugResult.status !== 'skipped' && ( + + {!debugResult.message && !response && !firstInteractive && ( + + )} + {debugResult.message && ( + + {debugResult.message} + + )} + {firstInteractive && interactive && ( + <> + {interactive.type === 'userSelect' && ( + + )} + {interactive.type === 'userInput' && ( + + )} + + )} + {response && } + + )} + + )} + + ) : null; + }, [ + interactive, + firstInteractive, + debugResult, + nodeId, + onChangeNode, + onNextNodeDebug, + onStopNodeDebug, + openConfirm, + t, + workflowDebugData + ]); + + return ( + <> + {RenderStatus} + + + ); +}; + +export default React.memo(NodeDebugResponse);