@@ -56,9 +67,10 @@ export default function ExtraSidebar() {
@@ -67,10 +79,10 @@ export default function ExtraSidebar() {
className={classNames("hover:dark:hover:bg-[#242f47] text-gray-700 w-full justify-center shadow-sm transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 relative inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 rounded-md"
)}
onClick={(event) => {
-
+ openPopUp(
);
}}
>
-
+
@@ -78,7 +90,7 @@ export default function ExtraSidebar() {
className={classNames("hover:dark:hover:bg-[#242f47] text-gray-700 w-full justify-center shadow-sm transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 relative inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 rounded-md"
)}
onClick={(event) => {
-
+ openPopUp( f.id === tabId)} />);
}}
>
@@ -88,7 +100,9 @@ export default function ExtraSidebar() {
diff --git a/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts b/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts
deleted file mode 100644
index 4d2a2f529..000000000
--- a/src/frontend/src/pages/FlowPage/hooks/useUndoRedo.ts
+++ /dev/null
@@ -1,181 +0,0 @@
-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;
- enableShortcuts: boolean;
-};
-
-type UseUndoRedo = (options?: UseUndoRedoOptions) => {
- undo: () => void;
- redo: () => void;
- takeSnapshot: () => void;
- canUndo: boolean;
- canRedo: boolean;
-};
-
-type HistoryItem = {
- nodes: Node[];
- edges: Edge[];
-};
-
-const defaultOptions: UseUndoRedoOptions = {
- maxHistorySize: 100,
- enableShortcuts: true,
-};
-
-// https://redux.js.org/usage/implementing-undo-history
-export const useUndoRedo: UseUndoRedo = ({
- maxHistorySize = defaultOptions.maxHistorySize,
- enableShortcuts = defaultOptions.enableShortcuts,
-} = defaultOptions) => {
- // the past and future arrays store the states that we can jump to
- const { tabId, 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((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((old) => {
- let newFuture = cloneDeep(old);
- newFuture[tabIndex] = [];
- return newFuture;
- });
- }, [
- getNodes,
- getEdges,
- past,
- future,
- tabId,
- setPast,
- setFuture,
- maxHistorySize,
- ]);
-
- const tabIndex = flows.findIndex((f) => f.id === tabId);
-
- const undo = useCallback(() => {
- // get the last state that we want to go back to
- const pastState = past[tabIndex][past[tabIndex].length - 1];
-
- if (pastState) {
- // first we remove the state from the history
- 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((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,
- future,
- past,
- setFuture,
- setPast,
- tabIndex,
- ]);
-
- const redo = useCallback(() => {
- const futureState = future[tabIndex][future[tabIndex].length - 1];
-
- if (futureState) {
- 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);
- }
- }, [
- future,
- past,
- setFuture,
- setPast,
- setNodes,
- setEdges,
- getNodes,
- getEdges,
- future,
- tabIndex,
- ]);
-
- useEffect(() => {
- // this effect is used to attach the global event handlers
- if (!enableShortcuts) {
- return;
- }
-
- const keyDownHandler = (event: KeyboardEvent) => {
- if (
- event.key === "z" &&
- (event.ctrlKey || event.metaKey) &&
- event.shiftKey
- ) {
- redo();
- } else if (event.key === "y" && (event.ctrlKey || event.metaKey)) {
- event.preventDefault(); // prevent the default action
- redo();
- } else if (event.key === "z" && (event.ctrlKey || event.metaKey)) {
- undo();
- }
- };
-
- document.addEventListener("keydown", keyDownHandler);
-
- return () => {
- document.removeEventListener("keydown", keyDownHandler);
- };
- }, [undo, redo, enableShortcuts]);
-
- return {
- undo,
- redo,
- takeSnapshot,
- canUndo: !!past.length,
- canRedo: !!future.length,
- };
-};
-
-export default useUndoRedo;