Skip to content

Commit

Permalink
fix: loop node snapshot & infinite reload (#3349)
Browse files Browse the repository at this point in the history
  • Loading branch information
newfish-cmyk authored Dec 9, 2024
1 parent 1a294c1 commit c64d629
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 81 deletions.
2 changes: 1 addition & 1 deletion packages/web/hooks/useI18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const useI18nLng = () => {
const currentLng = i18n?.language;
await i18n?.changeLanguage?.(lang);

if (currentLng !== lang) {
if (currentLng !== lang && currentLng) {
window?.location?.reload?.();
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,63 +292,7 @@ export const useWorkflow = () => {
const { getIntersectingNodes } = useReactFlow();
const { isDowningCtrl } = useKeyboard();

// Loop node size and position
const resetParentNodeSizeAndPosition = useMemoizedFn((parentId: string) => {
const { childNodes, loopNode } = nodes.reduce(
(acc, node) => {
if (node.data.parentNodeId === parentId) {
acc.childNodes.push(node);
}
if (node.id === parentId) {
acc.loopNode = node;
}
return acc;
},
{ childNodes: [] as Node[], loopNode: undefined as Node<FlowNodeItemType> | undefined }
);

if (!loopNode) return;

const rect = getNodesBounds(childNodes);
// Calculate parent node size with minimum width/height constraints
const width = Math.max(rect.width + 80, 840);
const height = Math.max(rect.height + 80, 600);

const offsetHeight =
loopNode.data.inputs.find((input) => input.key === NodeInputKeyEnum.loopNodeInputHeight)
?.value ?? 83;

// Update parentNode size and position
onChangeNode({
nodeId: parentId,
type: 'updateInput',
key: NodeInputKeyEnum.nodeWidth,
value: {
...Input_Template_Node_Width,
value: width
}
});
onChangeNode({
nodeId: parentId,
type: 'updateInput',
key: NodeInputKeyEnum.nodeHeight,
value: {
...Input_Template_Node_Height,
value: height
}
});
// Update parentNode position
onNodesChange([
{
id: parentId,
type: 'position',
position: {
x: rect.x - 70,
y: rect.y - offsetHeight - 240
}
}
]);
});
const { resetParentNodeSizeAndPosition } = useLoopNode();

/* helper line */
const [helperLineHorizontal, setHelperLineHorizontal] = useState<THelperLine>();
Expand Down Expand Up @@ -704,7 +648,7 @@ export const useWorkflow = () => {
chatConfig: appDetail.chatConfig
});
},
[nodes, edges, appDetail.chatConfig, pushPastSnapshot],
[nodes, edges, appDetail.chatConfig],
{ wait: 500 }
);

Expand All @@ -721,7 +665,73 @@ export const useWorkflow = () => {
helperLineVertical,
onNodeDragStop,
onPaneContextMenu,
onPaneClick,
onPaneClick
};
};

export const useLoopNode = () => {
const nodes = useContextSelector(WorkflowInitContext, (state) => state.nodes);
const onNodesChange = useContextSelector(WorkflowNodeEdgeContext, (state) => state.onNodesChange);
const { onChangeNode } = useContextSelector(WorkflowContext, (v) => v);

const resetParentNodeSizeAndPosition = useMemoizedFn((parentId: string) => {
const { childNodes, loopNode } = nodes.reduce(
(acc, node) => {
if (node.data.parentNodeId === parentId) {
acc.childNodes.push(node);
}
if (node.id === parentId) {
acc.loopNode = node;
}
return acc;
},
{ childNodes: [] as Node[], loopNode: undefined as Node<FlowNodeItemType> | undefined }
);

if (!loopNode) return;

const rect = getNodesBounds(childNodes);
// Calculate parent node size with minimum width/height constraints
const width = Math.max(rect.width + 80, 840);
const height = Math.max(rect.height + 80, 600);

const offsetHeight =
loopNode.data.inputs.find((input) => input.key === NodeInputKeyEnum.loopNodeInputHeight)
?.value ?? 83;

// Update parentNode size and position
onChangeNode({
nodeId: parentId,
type: 'updateInput',
key: NodeInputKeyEnum.nodeWidth,
value: {
...Input_Template_Node_Width,
value: width
}
});
onChangeNode({
nodeId: parentId,
type: 'updateInput',
key: NodeInputKeyEnum.nodeHeight,
value: {
...Input_Template_Node_Height,
value: height
}
});
// Update parentNode position
onNodesChange([
{
id: parentId,
type: 'position',
position: {
x: rect.x - 70,
y: rect.y - offsetHeight - 240
}
}
]);
});

return {
resetParentNodeSizeAndPosition
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils';
import { AppContext } from '../../../../context';
import { isValidArrayReferenceValue } from '@fastgpt/global/core/workflow/utils';
import { ReferenceArrayValueType } from '@fastgpt/global/core/workflow/type/io';
import { useWorkflow } from '../../hooks/useWorkflow';
import { useLoopNode } from '../../hooks/useWorkflow';
import { useSize } from 'ahooks';

const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
Expand All @@ -41,7 +41,7 @@ const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const appDetail = useContextSelector(AppContext, (v) => v.appDetail);

const { resetParentNodeSizeAndPosition } = useWorkflow();
const { resetParentNodeSizeAndPosition } = useLoopNode();

const {
nodeWidth,
Expand All @@ -50,8 +50,12 @@ const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
loopNodeInputHeight = Input_Template_LOOP_NODE_OFFSET
} = useMemo(() => {
return {
nodeWidth: inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value,
nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value,
nodeWidth: Number(
inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value?.toFixed(0)
),
nodeHeight: Number(
inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value?.toFixed(0)
),
loopInputArray: inputs.find((input) => input.key === NodeInputKeyEnum.loopInputArray),
loopNodeInputHeight: inputs.find(
(input) => input.key === NodeInputKeyEnum.loopNodeInputHeight
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { postWorkflowDebug } from '@/web/core/workflow/api';
import {
checkWorkflowNodeAndConnection,
compareSnapshot,
simplifyWorkflowNodes,
storeEdgesRenderEdge,
storeNode2FlowNode
} from '@/web/core/workflow/utils';
Expand Down Expand Up @@ -833,10 +832,10 @@ const WorkflowContextProvider = ({
if (past.length > 1) {
forbiddenSaveSnapshot.current = true;

const firstPast = past[0];
const firstPast = past[1];
resetSnapshot(firstPast);

setFuture((future) => [firstPast, ...future]);
setFuture((future) => [past[0], ...future]);
setPast((past) => past.slice(1));
}
});
Expand Down Expand Up @@ -937,10 +936,10 @@ const WorkflowContextProvider = ({
if (isInit && past.length === 0) {
setPast([
{
nodes: nodes,
edges: edges,
title: t(`app:app.version_initial`),
isSaved: true,
nodes: simplifyWorkflowNodes(nodes),
edges,
chatConfig: e.chatConfig || appDetail.chatConfig
}
]);
Expand Down
14 changes: 2 additions & 12 deletions projects/app/src/web/core/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,6 @@ export const compareSnapshot = (
return nodes
.filter((node) => {
if (!node) return;
if (FlowNodeTypeEnum.systemConfig === node.type) return;

return true;
})
Expand All @@ -634,7 +633,8 @@ export const compareSnapshot = (
key: input.key,
selectedTypeIndex: input.selectedTypeIndex ?? 0,
renderTypeLis: input.renderTypeList,
valueType: input.valueType,
// set to arrayAny for loopInputArray to skip valueType comparison
valueType: input.key === NodeInputKeyEnum.loopInputArray ? 'arrayAny' : input.valueType,
value: input.value ?? undefined
})),
outputs: node.data.outputs.map((item: FlowNodeOutputItemType) => ({
Expand All @@ -661,13 +661,3 @@ export const compareSnapshot = (

return isEqual(node1, node2);
};

// remove node size
export const simplifyWorkflowNodes = (nodes: Node[]) => {
return nodes.map((node) => ({
id: node.id,
type: node.type,
position: node.position,
data: node.data
}));
};

0 comments on commit c64d629

Please sign in to comment.