From 3abc7eedc3bf919dfa26f139a7965ea032e09b0b Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 14 May 2024 14:46:44 -0300 Subject: [PATCH] Fix duplicate group bug (#1859) * fix duplicate group bug * remove commented console.log --- .../components/PageComponent/index.tsx | 41 ++++++------- src/frontend/src/stores/flowStore.ts | 59 +++++++++---------- src/frontend/src/utils/reactflowUtils.ts | 1 - 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index cb1a6e553..1c6951726 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -51,19 +51,19 @@ export default function Page({ }): JSX.Element { const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const autoSaveCurrentFlow = useFlowsManagerStore( - (state) => state.autoSaveCurrentFlow + (state) => state.autoSaveCurrentFlow, ); const types = useTypesStore((state) => state.types); const templates = useTypesStore((state) => state.templates); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); const [showCanvas, setSHowCanvas] = useState( - Object.keys(templates).length > 0 && Object.keys(types).length > 0 + Object.keys(templates).length > 0 && Object.keys(types).length > 0, ); const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( - (state) => state.setReactFlowInstance + (state) => state.setReactFlowInstance, ); const nodes = useFlowStore((state) => state.nodes); const edges = useFlowStore((state) => state.edges); @@ -80,10 +80,10 @@ export default function Page({ const paste = useFlowStore((state) => state.paste); const resetFlow = useFlowStore((state) => state.resetFlow); const lastCopiedSelection = useFlowStore( - (state) => state.lastCopiedSelection + (state) => state.lastCopiedSelection, ); const setLastCopiedSelection = useFlowStore( - (state) => state.setLastCopiedSelection + (state) => state.setLastCopiedSelection, ); const onConnect = useFlowStore((state) => state.onConnect); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); @@ -106,7 +106,7 @@ export default function Page({ clonedSelection!, clonedNodes, clonedEdges, - getRandomName() + getRandomName(), ); const newGroupNode = generateNodeFromFlow(newFlow, getNodeId); const newEdges = reconnectEdges(newGroupNode, removedEdges); @@ -114,8 +114,8 @@ export default function Page({ ...clonedNodes.filter( (oldNodes) => !clonedSelection?.nodes.some( - (selectionNode) => selectionNode.id === oldNodes.id - ) + (selectionNode) => selectionNode.id === oldNodes.id, + ), ), newGroupNode, ]); @@ -125,8 +125,8 @@ export default function Page({ !clonedSelection!.nodes.some( (selectionNode) => selectionNode.id === oldEdge.target || - selectionNode.id === oldEdge.source - ) + selectionNode.id === oldEdge.source, + ), ), ...newEdges, ]); @@ -141,7 +141,8 @@ export default function Page({ const setNode = useFlowStore((state) => state.setNode); useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { - const selectedNode = nodes.filter((obj) => obj.selected); + const selectedNode = lastSelection?.nodes ?? []; + const selectedEdges = lastSelection?.edges ?? []; if ( selectionMenuVisible && (event.ctrlKey || event.metaKey) && @@ -174,11 +175,11 @@ export default function Page({ ) { event.preventDefault(); paste( - { nodes: selectedNode, edges: [] }, + { nodes: selectedNode, edges: selectedEdges }, { x: position.current.x, y: position.current.y, - } + }, ); } if (!isWrappedWithClass(event, "noundo")) { @@ -274,7 +275,7 @@ export default function Page({ useEffect(() => { setSHowCanvas( - Object.keys(templates).length > 0 && Object.keys(types).length > 0 + Object.keys(templates).length > 0 && Object.keys(types).length > 0, ); }, [templates, types]); @@ -283,7 +284,7 @@ export default function Page({ takeSnapshot(); onConnect(params); }, - [takeSnapshot, onConnect] + [takeSnapshot, onConnect], ); const onNodeDragStart: NodeDragHandler = useCallback(() => { @@ -324,7 +325,7 @@ export default function Page({ // Extract the data from the drag event and parse it as a JSON object const data: { type: string; node?: APIClassType } = JSON.parse( - event.dataTransfer.getData("nodedata") + event.dataTransfer.getData("nodedata"), ); const newId = getNodeId(data.type); @@ -340,7 +341,7 @@ export default function Page({ }; paste( { nodes: [newNode], edges: [] }, - { x: event.clientX, y: event.clientY } + { x: event.clientX, y: event.clientY }, ); } else if (event.dataTransfer.types.some((types) => types === "Files")) { takeSnapshot(); @@ -369,7 +370,7 @@ export default function Page({ } }, // Specify dependencies for useCallback - [getNodeId, setNodes, takeSnapshot, paste] + [getNodeId, setNodes, takeSnapshot, paste], ); const onEdgeUpdateStart = useCallback(() => { @@ -385,7 +386,7 @@ export default function Page({ setEdges((els) => updateEdge(oldEdge, newConnection, els)); } }, - [setEdges] + [setEdges], ); const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => { @@ -418,7 +419,7 @@ export default function Page({ (flow: OnSelectionChangeParams): void => { setLastSelection(flow); }, - [] + [], ); const onPaneClick = useCallback((flow) => { diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 0c3328add..44879aba8 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -49,7 +49,7 @@ import FlowPage from "../pages/FlowPage"; // this is our useStore hook that we can use in our components to get parts of the store and call actions const useFlowStore = create((set, get) => ({ onFlowPage: false, - setOnFlowPage:(FlowPage=>set({onFlowPage:FlowPage})), + setOnFlowPage: (FlowPage) => set({ onFlowPage: FlowPage }), flowState: undefined, flowBuildStatus: {}, nodes: [], @@ -80,7 +80,7 @@ const useFlowStore = create((set, get) => ({ updateFlowPool: ( nodeId: string, data: FlowPoolObjectType | ChatOutputType | chatInputType, - buildId?: string + buildId?: string, ) => { let newFlowPool = cloneDeep({ ...get().flowPool }); if (!newFlowPool[nodeId]) { @@ -152,7 +152,7 @@ const useFlowStore = create((set, get) => ({ edges: applyEdgeChanges(changes, get().edges), }); }, - setNodes: (change,skipSave=false) => { + setNodes: (change, skipSave = false) => { let newChange = typeof change === "function" ? change(get().nodes) : change; let newEdges = cleanEdges(newChange, get().edges); const { inputs, outputs } = getInputsAndOutputs(newChange); @@ -171,11 +171,11 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( newChange, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); } }, - setEdges: (change,skipSave=false) => { + setEdges: (change, skipSave = false) => { let newChange = typeof change === "function" ? change(get().edges) : change; set({ edges: newChange, @@ -187,7 +187,7 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( get().nodes, newChange, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); } }, @@ -205,7 +205,7 @@ const useFlowStore = create((set, get) => ({ return newChange; } return node; - }) + }), ); }, getNode: (id: string) => { @@ -216,8 +216,8 @@ const useFlowStore = create((set, get) => ({ get().nodes.filter((node) => typeof nodeId === "string" ? node.id !== nodeId - : !nodeId.includes(node.id) - ) + : !nodeId.includes(node.id), + ), ); }, deleteEdge: (edgeId) => { @@ -225,13 +225,11 @@ const useFlowStore = create((set, get) => ({ get().edges.filter((edge) => typeof edgeId === "string" ? edge.id !== edgeId - : !edgeId.includes(edge.id) - ) + : !edgeId.includes(edge.id), + ), ); }, paste: (selection, position) => { - function updateGroup() {} - if ( selection.nodes.some((node) => node.data.type === "ChatInput") && checkChatInput(get().nodes) @@ -268,8 +266,6 @@ const useFlowStore = create((set, get) => ({ let newId = getNodeId(node.data.type); idsMap[node.id] = newId; - updateGroupRecursion(node, selection.edges); - // Create a new node object const newNode: NodeType = { id: newId, @@ -283,6 +279,7 @@ const useFlowStore = create((set, get) => ({ id: newId, }, }; + updateGroupRecursion(newNode, selection.edges); // Add the new node to the list of nodes in state newNodes = newNodes @@ -295,7 +292,7 @@ const useFlowStore = create((set, get) => ({ let source = idsMap[edge.source]; let target = idsMap[edge.target]; const sourceHandleObject: sourceHandleType = scapeJSONParse( - edge.sourceHandle! + edge.sourceHandle!, ); let sourceHandle = scapedJSONStringfy({ ...sourceHandleObject, @@ -305,7 +302,7 @@ const useFlowStore = create((set, get) => ({ edge.data.sourceHandle = sourceHandleObject; const targetHandleObject: targetHandleType = scapeJSONParse( - edge.targetHandle! + edge.targetHandle!, ); let targetHandle = scapedJSONStringfy({ ...targetHandleObject, @@ -326,7 +323,7 @@ const useFlowStore = create((set, get) => ({ className: "stroke-gray-900 ", selected: false, }, - newEdges.map((edge) => ({ ...edge, selected: false })) + newEdges.map((edge) => ({ ...edge, selected: false })), ); }); get().setEdges(newEdges); @@ -345,10 +342,10 @@ const useFlowStore = create((set, get) => ({ }); const newNodes = get().nodes.filter( - (node) => !nodesIdsSelected.includes(node.id) + (node) => !nodesIdsSelected.includes(node.id), ); const newEdges = get().edges.filter( - (edge) => !edgesIdsSelected.includes(edge.id) + (edge) => !edgesIdsSelected.includes(edge.id), ); set({ nodes: newNodes, edges: newEdges }); @@ -406,7 +403,7 @@ const useFlowStore = create((set, get) => ({ style: { stroke: "#555" }, className: "stroke-foreground stroke-connection", }, - oldEdges + oldEdges, ); return newEdges; @@ -416,7 +413,7 @@ const useFlowStore = create((set, get) => ({ .autoSaveCurrentFlow( get().nodes, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); }, unselectAll: () => { @@ -447,7 +444,7 @@ const useFlowStore = create((set, get) => ({ function validateSubgraph(nodes: string[]) { const errorsObjs = validateNodes( get().nodes.filter((node) => nodes.includes(node.id)), - get().edges + get().edges, ); const errors = errorsObjs.map((obj) => obj.errors).flat(); @@ -466,7 +463,7 @@ const useFlowStore = create((set, get) => ({ function handleBuildUpdate( vertexBuildData: VertexBuildTypeAPI, status: BuildStatus, - runId: string + runId: string, ) { if (vertexBuildData && vertexBuildData.inactivated_vertices) { get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); @@ -484,11 +481,11 @@ const useFlowStore = create((set, get) => ({ // next_vertices_ids should be next_vertices_ids without the inactivated vertices const next_vertices_ids = vertexBuildData.next_vertices_ids.filter( - (id) => !vertexBuildData.inactivated_vertices?.includes(id) + (id) => !vertexBuildData.inactivated_vertices?.includes(id), ); const nextVertices: VertexLayerElementType[] = zip( next_vertices_ids, - vertexBuildData.top_level_vertices + vertexBuildData.top_level_vertices, ).map(([id, reference]) => ({ id: id!, reference })); const newLayers = [ @@ -507,13 +504,13 @@ const useFlowStore = create((set, get) => ({ }); get().updateBuildStatus( vertexBuildData.top_level_vertices, - BuildStatus.TO_BUILD + BuildStatus.TO_BUILD, ); } get().addDataToFlowPool( { ...vertexBuildData, buildId: runId }, - vertexBuildData.id + vertexBuildData.id, ); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); @@ -522,7 +519,7 @@ const useFlowStore = create((set, get) => ({ const newFlowBuildStatus = { ...get().flowBuildStatus }; // filter out the vertices that are not status const verticesToUpdate = verticesIds?.filter( - (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT + (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT, ); if (verticesToUpdate) { @@ -587,7 +584,7 @@ const useFlowStore = create((set, get) => ({ verticesLayers: VertexLayerElementType[][]; runId: string; verticesToRun: string[]; - } | null + } | null, ) => { set({ verticesBuild: vertices }); }, @@ -612,7 +609,7 @@ const useFlowStore = create((set, get) => ({ // that are going to be built verticesIds: get().verticesBuild!.verticesIds.filter( // keep the vertices that are not in the list of vertices to remove - (vertex) => !vertices.includes(vertex) + (vertex) => !vertices.includes(vertex), ), }, }); diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 83772ee0d..64f876f95 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -994,7 +994,6 @@ export function updateEdgesIds( if (targetHandle.proxy && idsMap[targetHandle.proxy!.id]) { targetHandle.proxy!.id = idsMap[targetHandle.proxy!.id]; } - console.log("edge", edge); edge.data.targetHandle = targetHandle; edge.targetHandle = scapedJSONStringfy(targetHandle); });