mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
fix(editor): Fixes the issue that Switch Node can not be created (#7516)
Fixes the issue that currently no Switch-Node can be created by for example pressing + on the parent node or via tab when another node is already selected. Github issue / Community forum post (link here to close automatically): --------- Signed-off-by: Oleg Ivaniv <me@olegivaniv.com> Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
parent
742c8a8534
commit
df89685e15
|
@ -30,6 +30,7 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||||
|
|
||||||
it('should add switch node and test connections', () => {
|
it('should add switch node and test connections', () => {
|
||||||
const desiredOutputs = 4;
|
const desiredOutputs = 4;
|
||||||
|
WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
||||||
WorkflowPage.actions.addNodeToCanvas(SWITCH_NODE_NAME, true, true);
|
WorkflowPage.actions.addNodeToCanvas(SWITCH_NODE_NAME, true, true);
|
||||||
|
|
||||||
for (let i = 0; i < desiredOutputs; i++) {
|
for (let i = 0; i < desiredOutputs; i++) {
|
||||||
|
@ -43,9 +44,14 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
||||||
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, false);
|
WorkflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, false);
|
||||||
WorkflowPage.actions.zoomToFit();
|
WorkflowPage.actions.zoomToFit();
|
||||||
}
|
}
|
||||||
|
WorkflowPage.getters.nodeViewBackground().click({ force: true });
|
||||||
|
WorkflowPage.getters.canvasNodePlusEndpointByName(`${EDIT_FIELDS_SET_NODE_NAME}3`).click();
|
||||||
|
WorkflowPage.actions.addNodeToCanvas(SWITCH_NODE_NAME, false);
|
||||||
WorkflowPage.actions.saveWorkflowOnButtonClick();
|
WorkflowPage.actions.saveWorkflowOnButtonClick();
|
||||||
cy.reload();
|
cy.reload();
|
||||||
cy.waitForLoad();
|
cy.waitForLoad();
|
||||||
|
// Make sure outputless switch was connected correctly
|
||||||
|
cy.get(`[data-target-node="${SWITCH_NODE_NAME}1"][data-source-node="${EDIT_FIELDS_SET_NODE_NAME}3"]`).should('be.visible');
|
||||||
// Make sure all connections are there after reload
|
// Make sure all connections are there after reload
|
||||||
for (let i = 0; i < desiredOutputs; i++) {
|
for (let i = 0; i < desiredOutputs; i++) {
|
||||||
const setName = `${EDIT_FIELDS_SET_NODE_NAME}${i > 0 ? i : ''}`;
|
const setName = `${EDIT_FIELDS_SET_NODE_NAME}${i > 0 ? i : ''}`;
|
||||||
|
|
|
@ -265,6 +265,7 @@ import type {
|
||||||
IWorkflowBase,
|
IWorkflowBase,
|
||||||
Workflow,
|
Workflow,
|
||||||
ConnectionTypes,
|
ConnectionTypes,
|
||||||
|
INodeOutputConfiguration,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import {
|
import {
|
||||||
deepCopy,
|
deepCopy,
|
||||||
|
@ -1970,29 +1971,47 @@ export default defineComponent({
|
||||||
this.canvasStore.newNodeInsertPosition = null;
|
this.canvasStore.newNodeInsertPosition = null;
|
||||||
} else {
|
} else {
|
||||||
let yOffset = 0;
|
let yOffset = 0;
|
||||||
|
const workflow = this.getCurrentWorkflow();
|
||||||
|
|
||||||
if (lastSelectedConnection) {
|
if (lastSelectedConnection) {
|
||||||
const sourceNodeType = this.nodeTypesStore.getNodeType(
|
const sourceNodeType = this.nodeTypesStore.getNodeType(
|
||||||
lastSelectedNode.type,
|
lastSelectedNode.type,
|
||||||
lastSelectedNode.typeVersion,
|
lastSelectedNode.typeVersion,
|
||||||
);
|
);
|
||||||
const offsets = [
|
if (sourceNodeType) {
|
||||||
[-100, 100],
|
const offsets = [
|
||||||
[-140, 0, 140],
|
[-100, 100],
|
||||||
[-240, -100, 100, 240],
|
[-140, 0, 140],
|
||||||
];
|
[-240, -100, 100, 240],
|
||||||
if (sourceNodeType && sourceNodeType.outputs.length > 1) {
|
];
|
||||||
const offset = offsets[sourceNodeType.outputs.length - 2];
|
const sourceNodeOutputs = NodeHelpers.getNodeOutputs(
|
||||||
const sourceOutputIndex = lastSelectedConnection.__meta
|
workflow,
|
||||||
? lastSelectedConnection.__meta.sourceOutputIndex
|
lastSelectedNode!,
|
||||||
: 0;
|
sourceNodeType,
|
||||||
yOffset = offset[sourceOutputIndex];
|
);
|
||||||
|
const sourceNodeOutputTypes = NodeHelpers.getConnectionTypes(sourceNodeOutputs);
|
||||||
|
const sourceNodeOutputMainOutputs = sourceNodeOutputTypes.filter(
|
||||||
|
(output) => output === NodeConnectionType.Main,
|
||||||
|
);
|
||||||
|
if (sourceNodeOutputMainOutputs.length > 1) {
|
||||||
|
const offset = offsets[sourceNodeOutputMainOutputs.length - 2];
|
||||||
|
const sourceOutputIndex = lastSelectedConnection.__meta
|
||||||
|
? lastSelectedConnection.__meta.sourceOutputIndex
|
||||||
|
: 0;
|
||||||
|
yOffset = offset[sourceOutputIndex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const workflow = this.getCurrentWorkflow();
|
let outputs: Array<ConnectionTypes | INodeOutputConfiguration> = [];
|
||||||
const workflowNode = workflow.getNode(newNodeData.name);
|
try {
|
||||||
const outputs = NodeHelpers.getNodeOutputs(workflow, workflowNode!, nodeTypeData);
|
// It fails when the outputs are an expression. As those node have
|
||||||
|
// normally no outputs by default and the only reason we need the
|
||||||
|
// outputs here is to calculate the position it is fine to assume
|
||||||
|
// that they have no outputs and are so treated as a regular node
|
||||||
|
// with only "main" outputs.
|
||||||
|
outputs = NodeHelpers.getNodeOutputs(workflow, newNodeData!, nodeTypeData);
|
||||||
|
} catch (e) {}
|
||||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||||
const lastSelectedNodeType = this.nodeTypesStore.getNodeType(
|
const lastSelectedNodeType = this.nodeTypesStore.getNodeType(
|
||||||
lastSelectedNode.type,
|
lastSelectedNode.type,
|
||||||
|
@ -2000,7 +2019,10 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
|
|
||||||
// If node has only scoped outputs, position it below the last selected node
|
// If node has only scoped outputs, position it below the last selected node
|
||||||
if (outputTypes.every((outputName) => outputName !== NodeConnectionType.Main)) {
|
if (
|
||||||
|
outputTypes.length > 0 &&
|
||||||
|
outputTypes.every((outputName) => outputName !== NodeConnectionType.Main)
|
||||||
|
) {
|
||||||
const lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);
|
const lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);
|
||||||
const lastSelectedInputs = NodeHelpers.getNodeInputs(
|
const lastSelectedInputs = NodeHelpers.getNodeInputs(
|
||||||
workflow,
|
workflow,
|
||||||
|
@ -2025,6 +2047,7 @@ export default defineComponent({
|
||||||
[100, 0],
|
[100, 0],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// Has only main outputs or no outputs at all
|
||||||
const inputs = NodeHelpers.getNodeInputs(
|
const inputs = NodeHelpers.getNodeInputs(
|
||||||
workflow,
|
workflow,
|
||||||
lastSelectedNode,
|
lastSelectedNode,
|
||||||
|
|
Loading…
Reference in a new issue