mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix(editor): Fix issue that frontend breaks with unkown nodes (#7596)
Because of recent changes does the frontend break when a node is not known. ![Screenshot from 2023-11-03 08-27-43](https://github.com/n8n-io/n8n/assets/6249596/ab340c3c-9b72-4220-b1f8-70d80f7a5522) 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
a994ba5e8d
commit
db56a9ee37
|
@ -370,4 +370,40 @@ describe('Canvas Node Manipulation and Navigation', () => {
|
|||
NDVDialog.actions.close();
|
||||
});
|
||||
});
|
||||
|
||||
it('should render connections correctly if unkown nodes are present', () => {
|
||||
const unknownNodeName = 'Unknown node';
|
||||
cy.createFixtureWorkflow('workflow-with-unknown-nodes.json', 'Unknown nodes');
|
||||
|
||||
WorkflowPage.getters.canvasNodeByName(`${unknownNodeName} 1`).should('exist');
|
||||
WorkflowPage.getters.canvasNodeByName(`${unknownNodeName} 2`).should('exist');
|
||||
WorkflowPage.actions.zoomToFit();
|
||||
|
||||
cy.draganddrop(
|
||||
WorkflowPage.getters.getEndpointSelector('plus', `${unknownNodeName} 1`),
|
||||
WorkflowPage.getters.getEndpointSelector('input', EDIT_FIELDS_SET_NODE_NAME),
|
||||
);
|
||||
|
||||
cy.draganddrop(
|
||||
WorkflowPage.getters.getEndpointSelector('plus', `${unknownNodeName} 2`),
|
||||
WorkflowPage.getters.getEndpointSelector('input', `${EDIT_FIELDS_SET_NODE_NAME}1`),
|
||||
);
|
||||
|
||||
WorkflowPage.actions.executeWorkflow();
|
||||
cy.contains('Node not found').should('be.visible');
|
||||
|
||||
WorkflowPage.getters
|
||||
.canvasNodeByName(`${unknownNodeName} 1`)
|
||||
.find('[data-test-id=delete-node-button]')
|
||||
.click({ force: true });
|
||||
|
||||
WorkflowPage.getters
|
||||
.canvasNodeByName(`${unknownNodeName} 2`)
|
||||
.find('[data-test-id=delete-node-button]')
|
||||
.click({ force: true });
|
||||
|
||||
WorkflowPage.actions.executeWorkflow();
|
||||
|
||||
cy.contains('Node not found').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
90
cypress/fixtures/workflow-with-unknown-nodes.json
Normal file
90
cypress/fixtures/workflow-with-unknown-nodes.json
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"meta": {
|
||||
"instanceId": "15bbf37b6a515ccc2f534cabcd8bd171ca33583ff7744b1e9420e5ce68e615bb"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "40720511-19b6-4421-bdb0-3fb6efef4bc5",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
280,
|
||||
320
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "acdd1bdc-c642-4ea6-ad67-f4201b640cfa",
|
||||
"name": "Unknown node 1",
|
||||
"type": "n8n-nodes-base.thisNodeDoesntExist",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
400,
|
||||
500
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "acdd1bdc-c642-4ea6-ad67-f4201b640ffa",
|
||||
"name": "Unknown node 2",
|
||||
"type": "n8n-nodes-base.thisNodeDoesntExistEither",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
600,
|
||||
500
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "fbe5163b-7474-4741-980a-e4956789be0a",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
500,
|
||||
320
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "163313b9-64ff-4ffc-b00f-09b267d8132c",
|
||||
"name": "Edit Fields1",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
720,
|
||||
320
|
||||
]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -365,37 +365,39 @@ export default defineComponent({
|
|||
top: this.position[1] + 'px',
|
||||
};
|
||||
|
||||
const workflow = this.workflowsStore.getCurrentWorkflow();
|
||||
const inputs =
|
||||
NodeHelpers.getNodeInputs(workflow, this.node, this.nodeType) ||
|
||||
([] as Array<ConnectionTypes | INodeInputConfiguration>);
|
||||
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||
if (this.node && this.nodeType) {
|
||||
const workflow = this.workflowsStore.getCurrentWorkflow();
|
||||
const inputs =
|
||||
NodeHelpers.getNodeInputs(workflow, this.node, this.nodeType) ||
|
||||
([] as Array<ConnectionTypes | INodeInputConfiguration>);
|
||||
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||
|
||||
const nonMainInputs = inputTypes.filter((input) => input !== NodeConnectionType.Main);
|
||||
if (nonMainInputs.length) {
|
||||
const requiredNonMainInputs = inputs.filter(
|
||||
(input) => typeof input !== 'string' && input.required,
|
||||
);
|
||||
const nonMainInputs = inputTypes.filter((input) => input !== NodeConnectionType.Main);
|
||||
if (nonMainInputs.length) {
|
||||
const requiredNonMainInputs = inputs.filter(
|
||||
(input) => typeof input !== 'string' && input.required,
|
||||
);
|
||||
|
||||
let spacerCount = 0;
|
||||
if (NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS) {
|
||||
const requiredNonMainInputsCount = requiredNonMainInputs.length;
|
||||
const optionalNonMainInputsCount = nonMainInputs.length - requiredNonMainInputsCount;
|
||||
spacerCount = requiredNonMainInputsCount > 0 && optionalNonMainInputsCount > 0 ? 1 : 0;
|
||||
let spacerCount = 0;
|
||||
if (NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS) {
|
||||
const requiredNonMainInputsCount = requiredNonMainInputs.length;
|
||||
const optionalNonMainInputsCount = nonMainInputs.length - requiredNonMainInputsCount;
|
||||
spacerCount = requiredNonMainInputsCount > 0 && optionalNonMainInputsCount > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
styles['--configurable-node-input-count'] = nonMainInputs.length + spacerCount;
|
||||
}
|
||||
|
||||
styles['--configurable-node-input-count'] = nonMainInputs.length + spacerCount;
|
||||
const outputs =
|
||||
NodeHelpers.getNodeOutputs(workflow, this.node, this.nodeType) ||
|
||||
([] as Array<ConnectionTypes | INodeOutputConfiguration>);
|
||||
|
||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||
|
||||
const mainOutputs = outputTypes.filter((output) => output === NodeConnectionType.Main);
|
||||
styles['--node-main-output-count'] = mainOutputs.length;
|
||||
}
|
||||
|
||||
const outputs =
|
||||
NodeHelpers.getNodeOutputs(workflow, this.node, this.nodeType) ||
|
||||
([] as Array<ConnectionTypes | INodeOutputConfiguration>);
|
||||
|
||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||
|
||||
const mainOutputs = outputTypes.filter((output) => output === NodeConnectionType.Main);
|
||||
styles['--node-main-output-count'] = mainOutputs.length;
|
||||
|
||||
return styles;
|
||||
},
|
||||
nodeClass(): object {
|
||||
|
|
Loading…
Reference in a new issue