mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-13 13:57:29 -08:00
feat(editor): Add undo/redo creating a node in new canvas (no-changelog) (#10142)
This commit is contained in:
parent
ee676fd934
commit
aa15d22499
|
@ -333,6 +333,19 @@ describe('useCanvasOperations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('revertAddNode', () => {
|
||||||
|
it('deletes node if it exists', async () => {
|
||||||
|
const node = createTestNode();
|
||||||
|
vi.spyOn(workflowsStore, 'getNodeByName').mockReturnValueOnce(node);
|
||||||
|
vi.spyOn(workflowsStore, 'getNodeById').mockReturnValueOnce(node);
|
||||||
|
const removeNodeByIdSpy = vi.spyOn(workflowsStore, 'removeNodeById');
|
||||||
|
|
||||||
|
await canvasOperations.revertAddNode(node.name);
|
||||||
|
|
||||||
|
expect(removeNodeByIdSpy).toHaveBeenCalledWith(node.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('deleteNode', () => {
|
describe('deleteNode', () => {
|
||||||
it('should delete node and track history', () => {
|
it('should delete node and track history', () => {
|
||||||
const removeNodeByIdSpy = vi
|
const removeNodeByIdSpy = vi
|
||||||
|
|
|
@ -395,11 +395,17 @@ export function useCanvasOperations({
|
||||||
options: {
|
options: {
|
||||||
dragAndDrop?: boolean;
|
dragAndDrop?: boolean;
|
||||||
position?: XYPosition;
|
position?: XYPosition;
|
||||||
|
trackHistory?: boolean;
|
||||||
|
trackBulk?: boolean;
|
||||||
} = {},
|
} = {},
|
||||||
) {
|
) {
|
||||||
let insertPosition = options.position;
|
let insertPosition = options.position;
|
||||||
let lastAddedNode: INodeUi | undefined;
|
let lastAddedNode: INodeUi | undefined;
|
||||||
|
|
||||||
|
if (options.trackBulk) {
|
||||||
|
historyStore.startRecordingUndo();
|
||||||
|
}
|
||||||
|
|
||||||
for (const nodeAddData of nodes) {
|
for (const nodeAddData of nodes) {
|
||||||
const { isAutoAdd, openDetail: openNDV, ...node } = nodeAddData;
|
const { isAutoAdd, openDetail: openNDV, ...node } = nodeAddData;
|
||||||
const position = node.position ?? insertPosition;
|
const position = node.position ?? insertPosition;
|
||||||
|
@ -414,7 +420,7 @@ export function useCanvasOperations({
|
||||||
...options,
|
...options,
|
||||||
openNDV,
|
openNDV,
|
||||||
isAutoAdd,
|
isAutoAdd,
|
||||||
trackHistory: true,
|
trackHistory: options.trackHistory,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -433,6 +439,10 @@ export function useCanvasOperations({
|
||||||
// @TODO Figure out what this does and why it's needed
|
// @TODO Figure out what this does and why it's needed
|
||||||
updatePositionForNodeWithMultipleInputs(lastAddedNode);
|
updatePositionForNodeWithMultipleInputs(lastAddedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.trackBulk) {
|
||||||
|
historyStore.stopRecordingUndo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePositionForNodeWithMultipleInputs(node: INodeUi) {
|
function updatePositionForNodeWithMultipleInputs(node: INodeUi) {
|
||||||
|
@ -507,6 +517,15 @@ export function useCanvasOperations({
|
||||||
return nodeData;
|
return nodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function revertAddNode(nodeName: string) {
|
||||||
|
const node = workflowsStore.getNodeByName(nodeName);
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteNode(node.id);
|
||||||
|
}
|
||||||
|
|
||||||
function createConnectionToLastInteractedWithNode(node: INodeUi, options: AddNodeOptions = {}) {
|
function createConnectionToLastInteractedWithNode(node: INodeUi, options: AddNodeOptions = {}) {
|
||||||
const lastInteractedWithNode = uiStore.lastInteractedWithNode;
|
const lastInteractedWithNode = uiStore.lastInteractedWithNode;
|
||||||
if (!lastInteractedWithNode) {
|
if (!lastInteractedWithNode) {
|
||||||
|
@ -1628,6 +1647,7 @@ export function useCanvasOperations({
|
||||||
triggerNodes,
|
triggerNodes,
|
||||||
addNodes,
|
addNodes,
|
||||||
addNode,
|
addNode,
|
||||||
|
revertAddNode,
|
||||||
updateNodePosition,
|
updateNodePosition,
|
||||||
setNodeActive,
|
setNodeActive,
|
||||||
setNodeActiveByName,
|
setNodeActiveByName,
|
||||||
|
|
|
@ -149,6 +149,7 @@ const {
|
||||||
duplicateNodes,
|
duplicateNodes,
|
||||||
revertDeleteNode,
|
revertDeleteNode,
|
||||||
addNodes,
|
addNodes,
|
||||||
|
revertAddNode,
|
||||||
createConnection,
|
createConnection,
|
||||||
revertCreateConnection,
|
revertCreateConnection,
|
||||||
deleteConnection,
|
deleteConnection,
|
||||||
|
@ -784,7 +785,7 @@ async function onAddNodesAndConnections(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await addNodes(nodes, { dragAndDrop, position });
|
await addNodes(nodes, { dragAndDrop, position, trackHistory: true });
|
||||||
|
|
||||||
const offsetIndex = editableWorkflow.value.nodes.length - nodes.length;
|
const offsetIndex = editableWorkflow.value.nodes.length - nodes.length;
|
||||||
const mappedConnections: CanvasConnectionCreateData[] = connections.map(({ from, to }) => {
|
const mappedConnections: CanvasConnectionCreateData[] = connections.map(({ from, to }) => {
|
||||||
|
@ -812,6 +813,10 @@ async function onAddNodesAndConnections(
|
||||||
uiStore.resetLastInteractedWith();
|
uiStore.resetLastInteractedWith();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onRevertAddNode({ node }: { node: INodeUi }) {
|
||||||
|
await revertAddNode(node.name);
|
||||||
|
}
|
||||||
|
|
||||||
async function onSwitchActiveNode(nodeName: string) {
|
async function onSwitchActiveNode(nodeName: string) {
|
||||||
setNodeActiveByName(nodeName);
|
setNodeActiveByName(nodeName);
|
||||||
}
|
}
|
||||||
|
@ -982,7 +987,7 @@ const chatTriggerNodePinnedData = computed(() => {
|
||||||
|
|
||||||
function addUndoRedoEventBindings() {
|
function addUndoRedoEventBindings() {
|
||||||
// historyBus.on('nodeMove', onMoveNode);
|
// historyBus.on('nodeMove', onMoveNode);
|
||||||
// historyBus.on('revertAddNode', onRevertAddNode);
|
historyBus.on('revertAddNode', onRevertAddNode);
|
||||||
historyBus.on('revertRemoveNode', onRevertDeleteNode);
|
historyBus.on('revertRemoveNode', onRevertDeleteNode);
|
||||||
historyBus.on('revertAddConnection', onRevertCreateConnection);
|
historyBus.on('revertAddConnection', onRevertCreateConnection);
|
||||||
historyBus.on('revertRemoveConnection', onRevertDeleteConnection);
|
historyBus.on('revertRemoveConnection', onRevertDeleteConnection);
|
||||||
|
@ -992,7 +997,7 @@ function addUndoRedoEventBindings() {
|
||||||
|
|
||||||
function removeUndoRedoEventBindings() {
|
function removeUndoRedoEventBindings() {
|
||||||
// historyBus.off('nodeMove', onMoveNode);
|
// historyBus.off('nodeMove', onMoveNode);
|
||||||
// historyBus.off('revertAddNode', onRevertAddNode);
|
historyBus.off('revertAddNode', onRevertAddNode);
|
||||||
historyBus.off('revertRemoveNode', onRevertDeleteNode);
|
historyBus.off('revertRemoveNode', onRevertDeleteNode);
|
||||||
historyBus.off('revertAddConnection', onRevertCreateConnection);
|
historyBus.off('revertAddConnection', onRevertCreateConnection);
|
||||||
historyBus.off('revertRemoveConnection', onRevertDeleteConnection);
|
historyBus.off('revertRemoveConnection', onRevertDeleteConnection);
|
||||||
|
|
Loading…
Reference in a new issue