mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(editor): Filter component + implement in If node (#7490)
New Filter component + implementation in If node (v2) <img width="3283" alt="image" src="https://github.com/n8n-io/n8n/assets/8850410/35c379ef-4b62-4d06-82e7-673d4edcd652"> --------- Co-authored-by: Giulio Andreini <andreini@netseven.it> Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
@@ -41,7 +41,7 @@ export const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger';
|
||||
export const CODE_NODE_NAME = 'Code';
|
||||
export const SET_NODE_NAME = 'Set';
|
||||
export const EDIT_FIELDS_SET_NODE_NAME = 'Edit Fields';
|
||||
export const IF_NODE_NAME = 'IF';
|
||||
export const IF_NODE_NAME = 'If';
|
||||
export const MERGE_NODE_NAME = 'Merge';
|
||||
export const SWITCH_NODE_NAME = 'Switch';
|
||||
export const GMAIL_NODE_NAME = 'Gmail';
|
||||
|
||||
58
cypress/e2e/30-if-node.cy.ts
Normal file
58
cypress/e2e/30-if-node.cy.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { IF_NODE_NAME } from '../constants';
|
||||
import { WorkflowPage, NDV } from '../pages';
|
||||
|
||||
const workflowPage = new WorkflowPage();
|
||||
const ndv = new NDV();
|
||||
|
||||
const FILTER_PARAM_NAME = 'conditions';
|
||||
|
||||
describe('If Node (filter component)', () => {
|
||||
beforeEach(() => {
|
||||
workflowPage.actions.visit();
|
||||
});
|
||||
|
||||
it('should be able to create and delete multiple conditions', () => {
|
||||
workflowPage.actions.addInitialNodeToCanvas(IF_NODE_NAME, { keepNdvOpen: true });
|
||||
|
||||
// Default state
|
||||
ndv.getters.filterComponent(FILTER_PARAM_NAME).should('exist');
|
||||
ndv.getters.filterConditions(FILTER_PARAM_NAME).should('have.length', 1);
|
||||
ndv.getters
|
||||
.filterConditionOperator(FILTER_PARAM_NAME)
|
||||
.find('input')
|
||||
.should('have.value', 'is equal to');
|
||||
|
||||
// Add
|
||||
ndv.actions.addFilterCondition(FILTER_PARAM_NAME);
|
||||
ndv.getters.filterConditionLeft(FILTER_PARAM_NAME, 0).find('input').type('first left');
|
||||
ndv.getters.filterConditionLeft(FILTER_PARAM_NAME, 1).find('input').type('second left');
|
||||
ndv.actions.addFilterCondition(FILTER_PARAM_NAME);
|
||||
ndv.getters.filterConditions(FILTER_PARAM_NAME).should('have.length', 3);
|
||||
|
||||
// Delete
|
||||
ndv.actions.removeFilterCondition(FILTER_PARAM_NAME, 0);
|
||||
ndv.getters.filterConditions(FILTER_PARAM_NAME).should('have.length', 2);
|
||||
ndv.getters
|
||||
.filterConditionLeft(FILTER_PARAM_NAME, 0)
|
||||
.find('input')
|
||||
.should('have.value', 'second left');
|
||||
ndv.actions.removeFilterCondition(FILTER_PARAM_NAME, 1);
|
||||
ndv.getters.filterConditions(FILTER_PARAM_NAME).should('have.length', 1);
|
||||
});
|
||||
|
||||
it('should correctly evaluate conditions', () => {
|
||||
cy.fixture('Test_workflow_filter.json').then((data) => {
|
||||
cy.get('body').paste(JSON.stringify(data));
|
||||
});
|
||||
|
||||
workflowPage.actions.zoomToFit();
|
||||
workflowPage.actions.executeWorkflow();
|
||||
|
||||
workflowPage.actions.openNode('Then');
|
||||
ndv.getters.outputPanel().contains('3 items').should('exist');
|
||||
ndv.actions.close();
|
||||
|
||||
workflowPage.actions.openNode('Else');
|
||||
ndv.getters.outputPanel().contains('1 item').should('exist');
|
||||
});
|
||||
});
|
||||
@@ -2,6 +2,7 @@ import { NodeCreator } from '../pages/features/node-creator';
|
||||
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
|
||||
import { NDV } from '../pages/ndv';
|
||||
import { getVisibleSelect } from '../utils';
|
||||
import { IF_NODE_NAME } from '../constants';
|
||||
|
||||
const nodeCreatorFeature = new NodeCreator();
|
||||
const WorkflowPage = new WorkflowPageClass();
|
||||
@@ -360,7 +361,7 @@ describe('Node Creator', () => {
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Edit Fields (Set)');
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('i');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'IF');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', IF_NODE_NAME);
|
||||
nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Switch');
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('sw');
|
||||
@@ -368,11 +369,11 @@ describe('Node Creator', () => {
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Edit Fields (Set)');
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('i');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'IF');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', IF_NODE_NAME);
|
||||
nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Switch');
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('IF');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'IF');
|
||||
nodeCreatorFeature.getters.nodeItemName().first().should('have.text', IF_NODE_NAME);
|
||||
nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Switch');
|
||||
|
||||
nodeCreatorFeature.getters.searchBar().find('input').clear().type('sw');
|
||||
|
||||
153
cypress/fixtures/Test_workflow_filter.json
Normal file
153
cypress/fixtures/Test_workflow_filter.json
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"name": "Filter test",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "f332a7d1-31b4-4e78-b31e-9e8db945bf3f",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
-60,
|
||||
480
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return [\n {\n \"label\": \"Apple\",\n tags: [],\n meta: {foo: 'bar'}\n },\n {\n \"label\": \"Banana\",\n tags: ['exotic'],\n meta: {}\n },\n {\n \"label\": \"Pear\",\n tags: ['other'],\n meta: {}\n },\n {\n \"label\": \"Orange\",\n meta: {}\n }\n]"
|
||||
},
|
||||
"id": "60697c7f-3948-4790-97ba-8aba03d02ac2",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
160,
|
||||
480
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"options": {
|
||||
"caseSensitive": true,
|
||||
"leftValue": ""
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"leftValue": "={{ $json.tags }}",
|
||||
"rightValue": "exotic",
|
||||
"operator": {
|
||||
"type": "array",
|
||||
"operation": "contains",
|
||||
"rightType": "any"
|
||||
}
|
||||
},
|
||||
{
|
||||
"leftValue": "={{ $json.meta }}",
|
||||
"rightValue": "",
|
||||
"operator": {
|
||||
"type": "object",
|
||||
"operation": "notEmpty",
|
||||
"singleValue": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"leftValue": "={{ $json.label }}",
|
||||
"rightValue": "Pea",
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"operation": "startsWith",
|
||||
"rightType": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"combinator": "or"
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "7531191b-5ac3-45dc-8afb-27ae83d8f33a",
|
||||
"name": "If",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
380,
|
||||
480
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "d8c614ea-0bbf-4b12-ad7d-c9ebe09ce583",
|
||||
"name": "Then",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
600,
|
||||
400
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "69364770-60d2-4ef4-9f29-9570718a9a10",
|
||||
"name": "Else",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
600,
|
||||
580
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "If",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"If": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Then",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Else",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "a6249f48-d88f-4b80-9ed9-79555e522d48",
|
||||
"id": "BWUTRs5RHxVgQ4uT",
|
||||
"meta": {
|
||||
"instanceId": "78577815012af39cf16dad7a787b0898c42fb7514b8a7f99b2136862c2af502c"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -49,9 +49,7 @@ export class NDV extends BasePage {
|
||||
parameterExpressionPreview: (parameterName: string) =>
|
||||
this.getters
|
||||
.nodeParameters()
|
||||
.find(
|
||||
`[data-test-id="parameter-input-${parameterName}"] + [data-test-id="parameter-expression-preview"]`,
|
||||
),
|
||||
.find(`[data-test-id="parameter-expression-preview-${parameterName}"]`),
|
||||
nodeNameContainer: () => cy.getByTestId('node-title-container'),
|
||||
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
||||
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
||||
@@ -79,6 +77,23 @@ export class NDV extends BasePage {
|
||||
cy.getByTestId('columns-parameter-input-options-container'),
|
||||
resourceMapperRemoveAllFieldsOption: () => cy.getByTestId('action-removeAllFields'),
|
||||
sqlEditorContainer: () => cy.getByTestId('sql-editor-container'),
|
||||
filterComponent: (paramName: string) => cy.getByTestId(`filter-${paramName}`),
|
||||
filterCombinator: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-combinator-select').eq(index),
|
||||
filterConditions: (paramName: string) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-condition'),
|
||||
filterCondition: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-condition').eq(index),
|
||||
filterConditionLeft: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-condition-left').eq(index),
|
||||
filterConditionRight: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-condition-right').eq(index),
|
||||
filterConditionOperator: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-operator-select').eq(index),
|
||||
filterConditionRemove: (paramName: string, index = 0) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-remove-condition').eq(index),
|
||||
filterConditionAdd: (paramName: string) =>
|
||||
this.getters.filterComponent(paramName).getByTestId('filter-add-condition'),
|
||||
searchInput: () => cy.getByTestId('ndv-search'),
|
||||
pagination: () => cy.getByTestId('ndv-data-pagination'),
|
||||
nodeVersion: () => cy.getByTestId('node-version'),
|
||||
@@ -199,7 +214,6 @@ export class NDV extends BasePage {
|
||||
.find('span')
|
||||
.should('include.html', asEncodedHTML(value));
|
||||
},
|
||||
|
||||
refreshResourceMapperColumns: () => {
|
||||
this.getters.resourceMapperSelectColumn().realHover();
|
||||
this.getters
|
||||
@@ -210,7 +224,12 @@ export class NDV extends BasePage {
|
||||
|
||||
getVisiblePopper().find('li').last().click();
|
||||
},
|
||||
|
||||
addFilterCondition: (paramName: string) => {
|
||||
this.getters.filterConditionAdd(paramName).click();
|
||||
},
|
||||
removeFilterCondition: (paramName: string, index: number) => {
|
||||
this.getters.filterConditionRemove(paramName, index).click();
|
||||
},
|
||||
setInvalidExpression: ({
|
||||
fieldName,
|
||||
invalidExpression,
|
||||
|
||||
Reference in New Issue
Block a user