From 62701de9b8b2be68ac7af07a9ddc3370c3c83256 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Tue, 23 May 2023 21:00:12 -0300 Subject: [PATCH] Fixed Undo and Redo on different pages --- .../src/CustomNodes/GenericNode/index.tsx | 1 - src/frontend/src/contexts/tabsContext.tsx | 5 -- src/frontend/src/modals/chatModal/index.tsx | 1 - .../src/modals/codeAreaModal/index.tsx | 2 - src/frontend/src/modals/promptModal/index.tsx | 1 - .../src/pages/FlowPage/hooks/useUndoRedo.ts | 69 ++++++++++++++----- src/frontend/src/pages/FlowPage/index.tsx | 1 - 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 059fdfb81..96890d76e 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -58,7 +58,6 @@ export default function GenericNode({ if (response.status === 200) { let jsonResponse = await response.json(); let jsonResponseParsed = await JSON.parse(jsonResponse); - console.log(jsonResponseParsed); setValidationStatus(jsonResponseParsed); } } catch (error) { diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index 8f0832c3a..f07c500f5 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -58,7 +58,6 @@ export function TabsProvider({ children }: { children: ReactNode }) { } useEffect(() => { //save tabs locally - // console.log(id) save(); }, [flows, id, tabIndex, newNodeId]); @@ -173,8 +172,6 @@ export function TabsProvider({ children }: { children: ReactNode }) { */ function paste(selectionInstance, position){ - console.log(position); - console.log(selectionInstance) let minimumX = Infinity; let minimumY = Infinity; let idsMap = {}; @@ -214,7 +211,6 @@ export function TabsProvider({ children }: { children: ReactNode }) { nodes = nodes .map((e) => ({ ...e, selected: false })) .concat({ ...newNode, selected: false }) - console.log(nodes); }); reactFlowInstance.setNodes(nodes); @@ -250,7 +246,6 @@ export function TabsProvider({ children }: { children: ReactNode }) { }, edges.map((e) => ({ ...e, selected: false })) ); - console.log(edges); }); reactFlowInstance.setEdges(edges); }; diff --git a/src/frontend/src/modals/chatModal/index.tsx b/src/frontend/src/modals/chatModal/index.tsx index d4f3849ee..76aa801f3 100644 --- a/src/frontend/src/modals/chatModal/index.tsx +++ b/src/frontend/src/modals/chatModal/index.tsx @@ -183,7 +183,6 @@ export default function ChatModal({ newWs.onopen = () => { console.log("WebSocket connection established!"); }; - console.log(flow.id); newWs.onmessage = (event) => { const data = JSON.parse(event.data); console.log("Received data:", data); diff --git a/src/frontend/src/modals/codeAreaModal/index.tsx b/src/frontend/src/modals/codeAreaModal/index.tsx index 515e9089e..dc3e5ab1f 100644 --- a/src/frontend/src/modals/codeAreaModal/index.tsx +++ b/src/frontend/src/modals/codeAreaModal/index.tsx @@ -129,9 +129,7 @@ export default function CodeAreaModal({ onClick={() => { checkCode(code) .then((apiReturn) => { - console.log(apiReturn); if (apiReturn.data) { - console.log(apiReturn.data); let importsErrors = apiReturn.data.imports.errors; let funcErrors = apiReturn.data.function.errors; if ( diff --git a/src/frontend/src/modals/promptModal/index.tsx b/src/frontend/src/modals/promptModal/index.tsx index 6ba410f18..5dbeb2264 100644 --- a/src/frontend/src/modals/promptModal/index.tsx +++ b/src/frontend/src/modals/promptModal/index.tsx @@ -109,7 +109,6 @@ export default function PromptAreaModal({ onClick={() => { checkPrompt(myValue) .then((apiReturn) => { - console.log(apiReturn); if (apiReturn.data) { let inputVariables = apiReturn.data.input_variables; diff --git a/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts b/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts index 72dc6699c..85b135b73 100644 --- a/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts +++ b/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts @@ -1,5 +1,7 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useContext, useEffect, useState } from 'react'; import { Edge, Node, useReactFlow } from 'reactflow'; +import { TabsContext } from '../../../contexts/tabsContext'; +import { cloneDeep } from 'lodash'; type UseUndoRedoOptions = { maxHistorySize: number; @@ -30,47 +32,80 @@ export const useUndoRedo: UseUndoRedo = ({ enableShortcuts = defaultOptions.enableShortcuts, } = defaultOptions) => { // the past and future arrays store the states that we can jump to - const [past, setPast] = useState([]); - const [future, setFuture] = useState([]); + const { tabIndex, flows } = useContext(TabsContext); + + const [past, setPast] = useState(flows.map(()=>[])); + const [future, setFuture] = useState(flows.map(()=>[])); + + useEffect(() => { + // whenever the flows variable changes, we need to add one array to the past and future states + setPast((old) => flows.map((f, i)=>old[i] ? old[i] : [])); + setFuture((old) => flows.map((f, i)=>old[i] ? old[i] : [])); + }, [flows]); + const { setNodes, setEdges, getNodes, getEdges } = useReactFlow(); const takeSnapshot = useCallback(() => { // push the current graph to the past state - setPast((past) => [ - ...past.slice(past.length - maxHistorySize + 1, past.length), - { nodes: getNodes(), edges: getEdges() }, - ]); + setPast((old) => { + let newPast = cloneDeep(old); + newPast[tabIndex] = old[tabIndex].slice(old[tabIndex].length - maxHistorySize + 1, old[tabIndex].length); + newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() }); + return newPast; + }); // whenever we take a new snapshot, the redo operations need to be cleared to avoid state mismatches - setFuture([]); - }, [getNodes, getEdges, maxHistorySize]); + setFuture((old) => { + let newFuture = cloneDeep(old); + newFuture[tabIndex] = []; + return newFuture + }); + }, [getNodes, getEdges, past, future, tabIndex, setPast, setFuture, maxHistorySize]); const undo = useCallback(() => { // get the last state that we want to go back to - const pastState = past[past.length - 1]; + const pastState = past[tabIndex][past[tabIndex].length - 1]; if (pastState) { // first we remove the state from the history - setPast((past) => past.slice(0, past.length - 1)); + setPast((old) => { + let newPast = cloneDeep(old); + newPast[tabIndex] = old[tabIndex].slice(0, old[tabIndex].length - 1); + return newPast + }); // we store the current graph for the redo operation - setFuture((future) => [...future, { nodes: getNodes(), edges: getEdges() }]); + setFuture((old) => { + let newFuture = cloneDeep(old); + newFuture[tabIndex] = old[tabIndex] + newFuture[tabIndex].push({ nodes: getNodes(), edges: getEdges() }); + return newFuture + }); // now we can set the graph to the past state setNodes(pastState.nodes); setEdges(pastState.edges); } - }, [setNodes, setEdges, getNodes, getEdges, past]); + }, [setNodes, setEdges, getNodes, getEdges, future, past, setFuture, setPast, tabIndex]); const redo = useCallback(() => { - const futureState = future[future.length - 1]; + const futureState = future[tabIndex][future[tabIndex].length - 1]; if (futureState) { - setFuture((future) => future.slice(0, future.length - 1)); - setPast((past) => [...past, { nodes: getNodes(), edges: getEdges() }]); + setFuture((old) => { + let newFuture = cloneDeep(old); + newFuture[tabIndex] = old[tabIndex].slice(0, old[tabIndex].length - 1); + return newFuture + }); + setPast((old) => { + let newPast = cloneDeep(old); + newPast[tabIndex] = old[tabIndex]; + newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() }); + return newPast + }); setNodes(futureState.nodes); setEdges(futureState.edges); } - }, [setNodes, setEdges, getNodes, getEdges, future]); + }, [future, past, setFuture, setPast, setNodes, setEdges, getNodes, getEdges, future, tabIndex]); useEffect(() => { // this effect is used to attach the global event handlers diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index 57e77159e..e7978cc16 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -56,7 +56,6 @@ export default function FlowPage({ flow }: { flow: FlowType }) { // this effect is used to attach the global event handlers const onKeyDown = (event: KeyboardEvent) => { - console.log("keydownou", lastCopiedSelection, position); if ( (event.ctrlKey || event.metaKey) && event.key === "c" &&