Skip to content

Commit

Permalink
feat(editor): Filter component + implement in If node (#7490)
Browse files Browse the repository at this point in the history
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 <[email protected]>
Co-authored-by: Michael Kret <[email protected]>
  • Loading branch information
3 people authored Dec 13, 2023
1 parent 09a5729 commit 8a53434
Show file tree
Hide file tree
Showing 56 changed files with 5,064 additions and 904 deletions.
2 changes: 1 addition & 1 deletion cypress/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
58 changes: 58 additions & 0 deletions cypress/e2e/30-if-node.cy.ts
Original file line number Diff line number Diff line change
@@ -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');
});
});
7 changes: 4 additions & 3 deletions cypress/e2e/4-node-creator.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -360,19 +361,19 @@ 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');
nodeCreatorFeature.getters.searchBar().find('input').clear().type('Edit F');
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');
Expand Down
153 changes: 153 additions & 0 deletions cypress/fixtures/Test_workflow_filter.json
Original file line number Diff line number Diff line change
@@ -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": []
}
29 changes: 24 additions & 5 deletions cypress/pages/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down Expand Up @@ -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'),
Expand Down Expand Up @@ -199,7 +214,6 @@ export class NDV extends BasePage {
.find('span')
.should('include.html', asEncodedHTML(value));
},

refreshResourceMapperColumns: () => {
this.getters.resourceMapperSelectColumn().realHover();
this.getters
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
type SupplyData,
} from 'n8n-workflow';

import type { TextSplitter } from 'langchain/text_splitter';

import { logWrapper } from '../../../utils/logWrapper';
import { N8nBinaryLoader } from '../../../utils/N8nBinaryLoader';
import { getConnectionHintNoticeField, metadataFilterField } from '../../../utils/sharedFields';
Expand All @@ -17,7 +19,6 @@ import { getConnectionHintNoticeField, metadataFilterField } from '../../../util
import 'mammoth'; // for docx
import 'epub2'; // for epub
import 'pdf-parse'; // for pdf
import type { TextSplitter } from 'langchain/text_splitter';

export class DocumentBinaryInputLoader implements INodeType {
description: INodeTypeDescription = {
Expand Down
Loading

0 comments on commit 8a53434

Please sign in to comment.