feat: added undo and redo functionality

This commit is contained in:
Gerla, J. (Justin)
2025-12-07 15:21:59 +00:00
committed by JobvAlewijk
parent 608bd54617
commit 5e22ed8806
9 changed files with 490 additions and 51 deletions

View File

@@ -7,6 +7,7 @@ import {
MarkerType,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {useEffect} from "react";
import {useShallow} from 'zustand/react/shallow';
import {DndToolbar} from './visualProgrammingUI/components/DragDropSidebar.tsx';
import useFlowStore from './visualProgrammingUI/VisProgStores.tsx';
@@ -41,7 +42,11 @@ const selector = (state: FlowState) => ({
onConnect: state.onConnect,
onReconnectStart: state.onReconnectStart,
onReconnectEnd: state.onReconnectEnd,
onReconnect: state.onReconnect
onReconnect: state.onReconnect,
undo: state.undo,
redo: state.redo,
beginBatchAction: state.beginBatchAction,
endBatchAction: state.endBatchAction
});
// --| define ReactFlow editor |--
@@ -60,9 +65,23 @@ const VisProgUI = () => {
onConnect,
onReconnect,
onReconnectStart,
onReconnectEnd
onReconnectEnd,
undo,
redo,
beginBatchAction,
endBatchAction
} = useFlowStore(useShallow(selector)); // instructs the editor to use the corresponding functions from the FlowStore
// adds ctrl+z and ctrl+y support to respectively undo and redo actions
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.ctrlKey && e.key === 'z') undo();
if (e.ctrlKey && e.key === 'y') redo();
};
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
});
return (
<div className={`${styles.innerEditorContainer} round-lg border-lg`}>
<ReactFlow
@@ -76,6 +95,8 @@ const VisProgUI = () => {
onReconnectStart={onReconnectStart}
onReconnectEnd={onReconnectEnd}
onConnect={onConnect}
onNodeDragStart={beginBatchAction}
onNodeDragStop={endBatchAction}
snapToGrid
fitView
proOptions={{hideAttribution: true}}
@@ -83,6 +104,10 @@ const VisProgUI = () => {
<Panel position="top-center" className={styles.dndPanel}>
<DndToolbar/> {/* contains the drag and drop panel for nodes */}
</Panel>
<Panel position="bottom-center">
<button onClick={() => undo()}>undo</button>
<button onClick={() => redo()}>Redo</button>
</Panel>
<Controls/>
<Background/>
</ReactFlow>
@@ -90,8 +115,6 @@ const VisProgUI = () => {
);
};
/**
* Places the VisProgUI component inside a ReactFlowProvider
*