mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
feat(editor): Add undo/redo create connection in new canvas (no-changelog) (#10141)
This commit is contained in:
parent
7e1eeb4c31
commit
ada1256898
|
@ -708,6 +708,24 @@ describe('useCanvasOperations', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('revertCreateConnection', () => {
|
||||
it('deletes connection if both source and target nodes exist', () => {
|
||||
const connection: [IConnection, IConnection] = [
|
||||
{ node: 'sourceNode', type: NodeConnectionType.Main, index: 0 },
|
||||
{ node: 'targetNode', type: NodeConnectionType.Main, index: 0 },
|
||||
];
|
||||
const testNode = createTestNode();
|
||||
|
||||
const removeConnectionSpy = vi.spyOn(workflowsStore, 'removeConnection');
|
||||
vi.spyOn(workflowsStore, 'getNodeByName').mockReturnValue(testNode);
|
||||
vi.spyOn(workflowsStore, 'getNodeById').mockReturnValue(testNode);
|
||||
|
||||
canvasOperations.revertCreateConnection(connection);
|
||||
|
||||
expect(removeConnectionSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isConnectionAllowed', () => {
|
||||
it('should return false if source and target nodes are the same', () => {
|
||||
const node = mockNode({ id: '1', type: 'testType', name: 'Test Node' });
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
WEBHOOK_NODE_TYPE,
|
||||
} from '@/constants';
|
||||
import {
|
||||
AddConnectionCommand,
|
||||
AddNodeCommand,
|
||||
MoveNodeCommand,
|
||||
RemoveConnectionCommand,
|
||||
|
@ -55,6 +56,7 @@ import {
|
|||
getUniqueNodeName,
|
||||
mapCanvasConnectionToLegacyConnection,
|
||||
mapLegacyConnectionsToCanvasConnections,
|
||||
mapLegacyConnectionToCanvasConnection,
|
||||
parseCanvasConnectionHandleString,
|
||||
} from '@/utils/canvasUtilsV2';
|
||||
import * as NodeViewUtils from '@/utils/nodeViewUtils';
|
||||
|
@ -949,13 +951,21 @@ export function useCanvasOperations({
|
|||
* Connection operations
|
||||
*/
|
||||
|
||||
function createConnection(connection: Connection) {
|
||||
function createConnection(connection: Connection, { trackHistory = false } = {}) {
|
||||
const sourceNode = workflowsStore.getNodeById(connection.source);
|
||||
const targetNode = workflowsStore.getNodeById(connection.target);
|
||||
if (!sourceNode || !targetNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (trackHistory) {
|
||||
historyStore.pushCommandToUndo(
|
||||
new AddConnectionCommand(
|
||||
mapCanvasConnectionToLegacyConnection(sourceNode, targetNode, connection),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const mappedConnection = mapCanvasConnectionToLegacyConnection(
|
||||
sourceNode,
|
||||
targetNode,
|
||||
|
@ -976,6 +986,19 @@ export function useCanvasOperations({
|
|||
uiStore.stateIsDirty = true;
|
||||
}
|
||||
|
||||
function revertCreateConnection(connection: [IConnection, IConnection]) {
|
||||
const sourceNodeName = connection[0].node;
|
||||
const sourceNode = workflowsStore.getNodeByName(sourceNodeName);
|
||||
const targetNodeName = connection[1].node;
|
||||
const targetNode = workflowsStore.getNodeByName(targetNodeName);
|
||||
|
||||
if (!sourceNode || !targetNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
deleteConnection(mapLegacyConnectionToCanvasConnection(sourceNode, targetNode, connection));
|
||||
}
|
||||
|
||||
function deleteConnection(
|
||||
connection: Connection,
|
||||
{ trackHistory = false, trackBulk = true } = {},
|
||||
|
@ -1607,6 +1630,7 @@ export function useCanvasOperations({
|
|||
revertDeleteNode,
|
||||
addConnections,
|
||||
createConnection,
|
||||
revertCreateConnection,
|
||||
deleteConnection,
|
||||
revertDeleteConnection,
|
||||
isConnectionAllowed,
|
||||
|
|
|
@ -74,6 +74,32 @@ export function mapLegacyConnectionsToCanvasConnections(
|
|||
return mappedConnections;
|
||||
}
|
||||
|
||||
export function mapLegacyConnectionToCanvasConnection(
|
||||
sourceNode: INodeUi,
|
||||
targetNode: INodeUi,
|
||||
legacyConnection: [IConnection, IConnection],
|
||||
): Connection {
|
||||
const source = sourceNode.id;
|
||||
const sourceHandle = createCanvasConnectionHandleString({
|
||||
mode: CanvasConnectionMode.Output,
|
||||
type: legacyConnection[0].type,
|
||||
index: legacyConnection[0].index,
|
||||
});
|
||||
const target = targetNode.id;
|
||||
const targetHandle = createCanvasConnectionHandleString({
|
||||
mode: CanvasConnectionMode.Input,
|
||||
type: legacyConnection[1].type,
|
||||
index: legacyConnection[1].index,
|
||||
});
|
||||
|
||||
return {
|
||||
source,
|
||||
sourceHandle,
|
||||
target,
|
||||
targetHandle,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseCanvasConnectionHandleString(handle: string | null | undefined) {
|
||||
const [mode, type, index] = (handle ?? '').split('/');
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ const {
|
|||
revertDeleteNode,
|
||||
addNodes,
|
||||
createConnection,
|
||||
revertCreateConnection,
|
||||
deleteConnection,
|
||||
revertDeleteConnection,
|
||||
setNodeActiveByName,
|
||||
|
@ -689,7 +690,11 @@ async function loadCredentials() {
|
|||
*/
|
||||
|
||||
function onCreateConnection(connection: Connection) {
|
||||
createConnection(connection);
|
||||
createConnection(connection, { trackHistory: true });
|
||||
}
|
||||
|
||||
function onRevertCreateConnection({ connection }: { connection: [IConnection, IConnection] }) {
|
||||
revertCreateConnection(connection);
|
||||
}
|
||||
|
||||
function onCreateConnectionCancelled(event: ConnectStartEvent) {
|
||||
|
@ -974,7 +979,7 @@ function addUndoRedoEventBindings() {
|
|||
// historyBus.on('nodeMove', onMoveNode);
|
||||
// historyBus.on('revertAddNode', onRevertAddNode);
|
||||
historyBus.on('revertRemoveNode', onRevertDeleteNode);
|
||||
// historyBus.on('revertAddConnection', onRevertAddConnection);
|
||||
historyBus.on('revertAddConnection', onRevertCreateConnection);
|
||||
historyBus.on('revertRemoveConnection', onRevertDeleteConnection);
|
||||
historyBus.on('revertRenameNode', onRevertRenameNode);
|
||||
// historyBus.on('enableNodeToggle', onRevertEnableToggle);
|
||||
|
@ -984,7 +989,7 @@ function removeUndoRedoEventBindings() {
|
|||
// historyBus.off('nodeMove', onMoveNode);
|
||||
// historyBus.off('revertAddNode', onRevertAddNode);
|
||||
historyBus.off('revertRemoveNode', onRevertDeleteNode);
|
||||
// historyBus.off('revertAddConnection', onRevertAddConnection);
|
||||
historyBus.off('revertAddConnection', onRevertCreateConnection);
|
||||
historyBus.off('revertRemoveConnection', onRevertDeleteConnection);
|
||||
historyBus.off('revertRenameNode', onRevertRenameNode);
|
||||
// historyBus.off('enableNodeToggle', onRevertEnableToggle);
|
||||
|
|
Loading…
Reference in a new issue