mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 12:44:07 -08:00
fix(editor): Fix copy/paste issue when switch node is in workflow (#8103)
## Summary Fix bug where copy/pasting a node breaks the view. Issue seems to be that copied workflow does not have Switch node when workflow is rerendering.. <img width="1942" alt="Screenshot 2023-12-19 at 18 16 23" src="https://github.com/n8n-io/n8n/assets/4711238/ad53b8ae-3693-4733-8f6b-7bc9e7b9d216"> ## Related tickets and issues [Linear ticket ADO-1504](https://linear.app/n8n/issue/ADO-1504/unwanted-nodes-connections-after-copypaste-of-n8n-form-trigger) ## Review / Merge checklist - [X] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [x] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. > A feature is not complete without tests.
This commit is contained in:
parent
19b7f1ffb1
commit
4b86926752
|
@ -325,4 +325,33 @@ describe('Undo/Redo', () => {
|
||||||
WorkflowPage.getters.nodeConnections().should('have.length', 2);
|
WorkflowPage.getters.nodeConnections().should('have.length', 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to copy and paste pinned data nodes in workflows with dynamic Switch node', () => {
|
||||||
|
cy.fixture('Test_workflow_form_switch.json').then((data) => {
|
||||||
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
WorkflowPage.actions.zoomToFit();
|
||||||
|
|
||||||
|
WorkflowPage.getters.canvasNodes().should('have.length', 2);
|
||||||
|
WorkflowPage.getters.nodeConnections().should('have.length', 1);
|
||||||
|
cy.get(WorkflowPage.getters.getEndpointSelector('input', 'Switch')).should('have.length', 1);
|
||||||
|
cy.get(WorkflowPage.getters.getEndpointSelector('input', 'Switch'))
|
||||||
|
.should('have.css', 'left', `637px`)
|
||||||
|
.should('have.css', 'top', `501px`);
|
||||||
|
|
||||||
|
cy.fixture('Test_workflow_form_switch.json').then((data) => {
|
||||||
|
cy.get('body').paste(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
WorkflowPage.getters.canvasNodes().should('have.length', 4);
|
||||||
|
WorkflowPage.getters.nodeConnections().should('have.length', 2);
|
||||||
|
|
||||||
|
WorkflowPage.actions.hitUndo();
|
||||||
|
|
||||||
|
WorkflowPage.getters.canvasNodes().should('have.length', 2);
|
||||||
|
WorkflowPage.getters.nodeConnections().should('have.length', 1);
|
||||||
|
cy.get(WorkflowPage.getters.getEndpointSelector('input', 'Switch')).should('have.length', 1);
|
||||||
|
cy.get(WorkflowPage.getters.getEndpointSelector('input', 'Switch'))
|
||||||
|
.should('have.css', 'left', `637px`)
|
||||||
|
.should('have.css', 'top', `501px`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
78
cypress/fixtures/Test_workflow_form_switch.json
Normal file
78
cypress/fixtures/Test_workflow_form_switch.json
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"name": "My workflow 8",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"path": "d1cba915-ca18-4425-bcfb-133205fc815a",
|
||||||
|
"formTitle": "test",
|
||||||
|
"formFields": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"fieldLabel": "test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "9e685367-fb94-4376-a9a4-7f311d9f7e2d",
|
||||||
|
"name": "n8n Form Trigger",
|
||||||
|
"type": "n8n-nodes-base.formTrigger",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
620,
|
||||||
|
580
|
||||||
|
],
|
||||||
|
"webhookId": "d1cba915-ca18-4425-bcfb-133205fc815a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {},
|
||||||
|
"id": "0f4dfe66-51c0-4378-9eab-680f8140a572",
|
||||||
|
"name": "Switch",
|
||||||
|
"type": "n8n-nodes-base.switch",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
800,
|
||||||
|
580
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pinData": {
|
||||||
|
"n8n Form Trigger": [
|
||||||
|
{
|
||||||
|
"json": {
|
||||||
|
"name": "First item",
|
||||||
|
"code": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"json": {
|
||||||
|
"name": "Second item",
|
||||||
|
"code": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"connections": {
|
||||||
|
"n8n Form Trigger": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Switch",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"active": false,
|
||||||
|
"settings": {
|
||||||
|
"executionOrder": "v1"
|
||||||
|
},
|
||||||
|
"versionId": "d6c14bc8-a69f-47bb-b5ba-fe6e9db0a3a4",
|
||||||
|
"id": "UQSimcMQJGbTeTLG",
|
||||||
|
"meta": {
|
||||||
|
"instanceId": "a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0"
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
|
@ -351,9 +351,6 @@ export class WorkflowPage extends BasePage {
|
||||||
hitCopy: () => {
|
hitCopy: () => {
|
||||||
cy.get('body').type(META_KEY, { delay: 500, release: false }).type('c');
|
cy.get('body').type(META_KEY, { delay: 500, release: false }).type('c');
|
||||||
},
|
},
|
||||||
hitPaste: () => {
|
|
||||||
cy.get('body').type(META_KEY, { delay: 500, release: false }).type('P');
|
|
||||||
},
|
|
||||||
hitPinNodeShortcut: () => {
|
hitPinNodeShortcut: () => {
|
||||||
cy.get('body').type('p');
|
cy.get('body').type('p');
|
||||||
},
|
},
|
||||||
|
|
|
@ -377,9 +377,10 @@ export default defineComponent({
|
||||||
styles['--configurable-node-input-count'] = nonMainInputs.length + spacerCount;
|
styles['--configurable-node-input-count'] = nonMainInputs.length + spacerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const outputs =
|
let outputs = [] as Array<ConnectionTypes | INodeOutputConfiguration>;
|
||||||
NodeHelpers.getNodeOutputs(this.workflow, this.node, this.nodeType) ||
|
if (this.workflow.nodes[this.node.name]) {
|
||||||
([] as Array<ConnectionTypes | INodeOutputConfiguration>);
|
outputs = NodeHelpers.getNodeOutputs(this.workflow, this.node, this.nodeType);
|
||||||
|
}
|
||||||
|
|
||||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,9 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, {
|
||||||
},
|
},
|
||||||
isConfigNode() {
|
isConfigNode() {
|
||||||
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
||||||
|
if (!workflow.nodes[node.name]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const nodeType = this.getNodeType(nodeTypeName);
|
const nodeType = this.getNodeType(nodeTypeName);
|
||||||
if (!nodeType) {
|
if (!nodeType) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue