Files
Automata/packages/editor-ui/src/stores/history.ts
Milorad FIlipović b2aba48dfe feat(editor): Add undo/redo support for canvas actions (#4787)
*  Added history store and mixin
*  Implemented node position change undo/redo
*  Implemented move nodes bulk command
*  Not clearing the redo stack after pushing the bulk command
* 🔨 Implemented commands using classes
* 🔥 Removed unnecessary interfaces and actions
* 🔥 Removing unused constants
* 🔨 Refactoring classes file
*  Adding eventBus to command obects
*  Added undo/redo support for adding and removing nodes
*  Implemented initial add/remove connections undo support
*  Covering some corner cases with reconnecting nodes
*  Adding undo support for reconnecting nodes
*  Fixing going back and forward between undo and redo
*  Implemented async command revert
*  Preventing push to undo if bulk redo/undo is in progress
*  Handling re-connecting nodes and stopped pushing empty bulk actions to undo stack
*  Handling adding a node between two connected nodes
*  Handling the case of removing multiple connections on the same index. Adding debounce to undo/redo keyboard calls
*  Removing unnecessary timeouts, adding missing awaits, refactoring
*  Resetting history when opening new workflow, fixing incorrect bulk recording when inserting node
* ✔️ Fixing lint error
*  Minor refactoring + some temporary debugging logs
*  Preserving node properties when undoing it's removal, removing some unused repaint code
*  Added undo/redo support for import workflow and node enable/disable
* 🔥 Removing some unused constant
*  Added undo/redo support for renaming nodes
*  Fixing rename history recording
*  Added undo/redo support for duplicating nodes
* 📈 Implemented telemetry events
* 🔨 A bit of refactoring
*  Fixing edgecases in removing connection and moving nodes
*  Handling case of adding duplicate nodes when going back and forward in history
*  Recording connections added directly to store
*  Moving main history reset after wf is opened
* 🔨 Simplifying rename recording
* 📈 Adding NDV telemetry event, updating existing event name case
* 📈 Updating telemetry events
*  Fixing duplicate connections on undo/redo
*  Stopping undo events from firing constantly on keydown
* 📈 Updated telemetry event for hitting undo in NDV
*  Adding undo support for disabling nodes using keyboard shortcuts
*  Preventing adding duplicate connection commands to history
*  Clearing redo stack when new change is added
*  Preventing adding connection actions to undo stack while redoing them
* 👌 Addressing PR comments part 1
* 👌 Moving undo logic for disabling nodes to `NodeView`
* 👌 Implemented command comparing logic
*  Fix for not clearing redo stack on every user action
*  Fixing recording when moving nodes
*  Fixing undo for moving connections
*  Fixing tracking new nodes after latest merge
*  Fixing broken bulk delete
*  Preventing undo/redo when not on main node view tab
* 👌 Addressing PR comments
* 👌 Addressing PR comment
2022-12-09 15:07:37 +01:00

89 lines
2.2 KiB
TypeScript

import { AddConnectionCommand, COMMANDS, RemoveConnectionCommand } from './../models/history';
import { BulkCommand, Command, Undoable, MoveNodeCommand } from "@/models/history";
import { STORES } from "@/constants";
import { HistoryState } from "@/Interface";
import { defineStore } from "pinia";
const STACK_LIMIT = 100;
export const useHistoryStore = defineStore(STORES.HISTORY, {
state: (): HistoryState => ({
undoStack: [],
redoStack: [],
currentBulkAction: null,
bulkInProgress: false,
}),
actions: {
popUndoableToUndo(): Undoable | undefined {
if (this.undoStack.length > 0) {
return this.undoStack.pop();
}
return undefined;
},
pushCommandToUndo(undoable: Command, clearRedo = true): void {
if (!this.bulkInProgress) {
if (this.currentBulkAction) {
const alreadyIn = this.currentBulkAction.commands.find(c => c.isEqualTo(undoable)) !== undefined;
if (!alreadyIn) {
this.currentBulkAction.commands.push(undoable);
}
} else {
this.undoStack.push(undoable);
}
this.checkUndoStackLimit();
if (clearRedo) {
this.clearRedoStack();
}
}
},
pushBulkCommandToUndo(undoable: BulkCommand, clearRedo = true): void {
this.undoStack.push(undoable);
this.checkUndoStackLimit();
if (clearRedo) {
this.clearRedoStack();
}
},
checkUndoStackLimit() {
if (this.undoStack.length > STACK_LIMIT) {
this.undoStack.shift();
}
},
checkRedoStackLimit() {
if (this.redoStack.length > STACK_LIMIT) {
this.redoStack.shift();
}
},
clearUndoStack() {
this.undoStack = [];
},
clearRedoStack() {
this.redoStack = [];
},
reset() {
this.clearRedoStack();
this.clearUndoStack();
},
popUndoableToRedo(): Undoable | undefined {
if (this.redoStack.length > 0) {
return this.redoStack.pop();
}
return undefined;
},
pushUndoableToRedo(undoable: Undoable): void {
this.redoStack.push(undoable);
this.checkRedoStackLimit();
},
startRecordingUndo() {
this.currentBulkAction = new BulkCommand([]);
},
stopRecordingUndo() {
if (this.currentBulkAction && this.currentBulkAction.commands.length > 0) {
this.undoStack.push(this.currentBulkAction);
this.checkUndoStackLimit();
}
this.currentBulkAction = null;
},
},
});