feat: 移动调试交互组件位置

This commit is contained in:
sd0ric4
2025-03-27 13:37:14 +08:00
parent f268e92b0d
commit 70524804b1
2 changed files with 5 additions and 5 deletions

View File

@@ -0,0 +1,184 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Box } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '@/pageComponents/app/detail/WorkflowComponents/context';
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
import { initWorkflowEdgeStatus } from '@fastgpt/global/core/workflow/runtime/utils';
import {
UserInputInteractive,
UserSelectInteractive
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import {
SelectOptionsComponent,
SelectOption,
FormInputComponent,
FormItem
} from '@/components/core/chat/components/Form/FormComponents';
const useInteractiveDebug = (
interactive: UserSelectInteractive | UserInputInteractive,
nodeId?: string
) => {
const { onStartNodeDebug, workflowDebugData } = useContextSelector(WorkflowContext, (v) => ({
onStartNodeDebug: v.onStartNodeDebug,
workflowDebugData: v.workflowDebugData
}));
const interactiveData = useMemo(() => {
return {
...interactive,
memoryEdges: interactive?.memoryEdges || [],
entryNodeIds: interactive?.entryNodeIds || [],
nodeOutputs: interactive?.nodeOutputs || []
};
}, [interactive]);
const createMockHistory = useCallback((): ChatItemType[] => {
return [
{
obj: ChatRoleEnum.AI,
value: [
{
type: ChatItemValueTypeEnum.interactive,
interactive: interactiveData
}
]
}
];
}, [interactiveData]);
const startDebug = useCallback(
(userContent: string, nodeUpdater: (node: any) => any) => {
if (!nodeId || !workflowDebugData) return;
const updatedQuery: UserChatItemValueItemType[] = [
...(workflowDebugData.query || []),
{
type: ChatItemValueTypeEnum.text,
text: { content: userContent }
}
];
const mockHistory = createMockHistory();
const updatedRuntimeEdges = initWorkflowEdgeStatus(
workflowDebugData.runtimeEdges,
mockHistory
);
const updatedRuntimeNodes = workflowDebugData.runtimeNodes.map((node) =>
node.nodeId === nodeId ? nodeUpdater(node) : node
);
onStartNodeDebug({
entryNodeId: nodeId,
runtimeNodes: updatedRuntimeNodes,
runtimeEdges: updatedRuntimeEdges,
variables: workflowDebugData.variables,
query: updatedQuery,
history: mockHistory
});
},
[nodeId, workflowDebugData, onStartNodeDebug, createMockHistory]
);
return { workflowDebugData, interactiveData, startDebug };
};
export const RenderUserSelectInteractive = React.memo(function RenderInteractive({
interactive,
nodeId
}: {
interactive: UserSelectInteractive;
nodeId?: string;
}) {
const { startDebug } = useInteractiveDebug(interactive, nodeId);
const handleSelectAndNext = useCallback(
(value: string) => {
startDebug(value || '', (node) => ({
...node,
inputs: node.inputs.map((input: { key: string }) => {
if (input.key === 'userSelect' || input.key === 'selectedOption') {
return { ...input, value };
}
return input;
}),
userSelectedVal: value
}));
},
[startDebug]
);
return (
<Box px={4} py={3}>
<SelectOptionsComponent
options={(interactive.params.userSelectOptions || []) as SelectOption[]}
description={interactive.params.description}
selectedValue={interactive.params.userSelectedVal}
onSelectOption={handleSelectAndNext}
isDisabled={interactive.params.userSelectedVal !== undefined}
/>
</Box>
);
});
export const RenderUserFormInteractive = React.memo(function RenderFormInput({
interactive,
nodeId
}: {
interactive: UserInputInteractive;
nodeId?: string;
}) {
const { t } = useTranslation();
const [isSubmitted, setIsSubmitted] = useState(false);
const { startDebug } = useInteractiveDebug(interactive, nodeId);
const defaultValues = useMemo(() => {
return interactive.params.inputForm?.reduce((acc: Record<string, any>, item) => {
acc[item.label] = !!item.value ? item.value : item.defaultValue;
return acc;
}, {});
}, [interactive.params.inputForm]);
const handleFormSubmit = useCallback(
(formData: Record<string, any>) => {
if (!nodeId) return;
setIsSubmitted(true);
startDebug(JSON.stringify(formData), (node) => ({
...node,
inputs: node.inputs.map((input: { key: string }) => {
const formField = interactive.params.inputForm?.find(
(field) => field.label === input.key || field.key === input.key
);
if (formField) {
return { ...input, value: formData[formField.label] };
}
return input;
}),
formSubmitted: true
}));
},
[nodeId, startDebug, interactive.params.inputForm]
);
useEffect(() => {
if (interactive.params.submitted) {
setIsSubmitted(true);
}
}, [interactive.params.submitted]);
return (
<Box px={4} py={4} bg="white" borderRadius="md">
<FormInputComponent
inputForm={(interactive.params.inputForm || []) as FormItem[]}
description={interactive.params.description}
onSubmit={handleFormSubmit}
isDisabled={isSubmitted || interactive.params.submitted}
defaultValues={defaultValues}
submitButtonText="common:Submit"
submitButtonIcon="core/workflow/debugNext"
/>
</Box>
);
});

View File

@@ -11,7 +11,7 @@ import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d
import {
RenderUserSelectInteractive,
RenderUserFormInteractive
} from '@/components/core/chat/components/InteractiveComponents';
} from './InteractiveComponents/DebugInteractive';
type NodeDebugResponseProps = {
nodeId: string;