From afd637b5eab2bba33fd9ec8b24104bef5e2a4cc0 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Wed, 8 Nov 2023 08:42:53 -0500 Subject: [PATCH] feat(editor): Add workflow filters to querystring (#7456) fixes: https://linear.app/n8n/issue/ADO-1222/feature-save-filters-in-workflows --- cypress/e2e/30-workflow-filters.cy.ts | 118 ++++++++++++++++++ cypress/pages/workflows.ts | 8 ++ .../src/components/N8nUserInfo/UserInfo.vue | 2 +- .../components/N8nUserSelect/UserSelect.vue | 1 + .../editor-ui/src/components/TagsDropdown.vue | 2 + .../layouts/ResourcesListLayout.vue | 15 ++- .../editor-ui/src/views/WorkflowsView.vue | 86 ++++++++++++- 7 files changed, 228 insertions(+), 4 deletions(-) create mode 100644 cypress/e2e/30-workflow-filters.cy.ts diff --git a/cypress/e2e/30-workflow-filters.cy.ts b/cypress/e2e/30-workflow-filters.cy.ts new file mode 100644 index 0000000000..b7f4251aa9 --- /dev/null +++ b/cypress/e2e/30-workflow-filters.cy.ts @@ -0,0 +1,118 @@ +import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows'; +import { WorkflowPage as WorkflowPageClass } from '../pages/workflow'; + +import { MainSidebar } from '../pages'; +import { INSTANCE_OWNER } from '../constants'; + +const WorkflowsPage = new WorkflowsPageClass(); +const WorkflowPages = new WorkflowPageClass(); +const mainSidebar = new MainSidebar(); + +describe('Workflow filters', () => { + before(() => { + cy.enableFeature('sharing', true); + }); + + beforeEach(() => { + cy.visit(WorkflowsPage.url); + }); + + it('Should filter by tags', () => { + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.newWorkflowButtonCard().click(); + cy.createFixtureWorkflow('Test_workflow_1.json', `Workflow 1`); + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.createWorkflowButton().click(); + cy.createFixtureWorkflow('Test_workflow_2.json', `Workflow 2`); + cy.visit(WorkflowsPage.url); + + WorkflowsPage.getters.workflowFilterButton().click(); + WorkflowsPage.getters.workflowTagsDropdown().click(); + WorkflowsPage.getters.workflowTagItem('other-tag-1').click(); + cy.get('body').click(0, 0); + + WorkflowsPage.getters.workflowCards().should('have.length', 1); + WorkflowsPage.getters.workflowCard('Workflow 2').should('contain.text', 'Workflow 2'); + mainSidebar.actions.goToSettings(); + cy.go('back'); + + WorkflowsPage.getters.workflowCards().should('have.length', 1); + WorkflowsPage.getters.workflowCard('Workflow 2').should('contain.text', 'Workflow 2'); + WorkflowsPage.getters.workflowResetFilters().click(); + + WorkflowsPage.getters.workflowCards().each(($el) => { + const workflowName = $el.find('[data-test-id="workflow-card-name"]').text(); + + WorkflowsPage.getters.workflowCardActions(workflowName).click(); + WorkflowsPage.getters.workflowDeleteButton().click(); + + cy.get('button').contains('delete').click(); + }); + }); + + it('Should filter by status', () => { + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.newWorkflowButtonCard().click(); + cy.createFixtureWorkflow('Test_workflow_1.json', `Workflow 1`); + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.createWorkflowButton().click(); + cy.createFixtureWorkflow('Test_workflow_3.json', `Workflow 3`); + WorkflowPages.getters.activatorSwitch().click(); + cy.visit(WorkflowsPage.url); + + WorkflowsPage.getters.workflowFilterButton().click(); + WorkflowsPage.getters.workflowStatusDropdown().click(); + WorkflowsPage.getters.workflowStatusItem('Active').click(); + cy.get('body').click(0, 0); + + WorkflowsPage.getters.workflowCards().should('have.length', 1); + WorkflowsPage.getters.workflowCard('Workflow 3').should('contain.text', 'Workflow 3'); + mainSidebar.actions.goToSettings(); + cy.go('back'); + + WorkflowsPage.getters.workflowCards().should('have.length', 1); + WorkflowsPage.getters.workflowCard('Workflow 3').should('contain.text', 'Workflow 3'); + WorkflowsPage.getters.workflowResetFilters().click(); + + WorkflowsPage.getters.workflowCards().each(($el) => { + const workflowName = $el.find('[data-test-id="workflow-card-name"]').text(); + + WorkflowsPage.getters.workflowCardActions(workflowName).click(); + WorkflowsPage.getters.workflowDeleteButton().click(); + + cy.get('button').contains('delete').click(); + }); + }); + + it('Should filter by owned by', () => { + cy.visit(WorkflowsPage.url); + + WorkflowsPage.getters.newWorkflowButtonCard().click(); + cy.createFixtureWorkflow('Test_workflow_1.json', `Workflow 1`); + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.createWorkflowButton().click(); + cy.createFixtureWorkflow('Test_workflow_3.json', `Workflow 3`); + WorkflowPages.getters.activatorSwitch().click(); + cy.visit(WorkflowsPage.url); + + WorkflowsPage.getters.workflowFilterButton().click(); + WorkflowsPage.getters.workflowOwnershipDropdown().realClick(); + WorkflowsPage.getters.workflowOwner(INSTANCE_OWNER.email).click(); + cy.get('body').click(0, 0); + + WorkflowsPage.getters.workflowCards().should('have.length', 2); + mainSidebar.actions.goToSettings(); + cy.go('back'); + + WorkflowsPage.getters.workflowResetFilters().click(); + + WorkflowsPage.getters.workflowCards().each(($el) => { + const workflowName = $el.find('[data-test-id="workflow-card-name"]').text(); + + WorkflowsPage.getters.workflowCardActions(workflowName).click(); + WorkflowsPage.getters.workflowDeleteButton().click(); + + cy.get('button').contains('delete').click(); + }); + }); +}); diff --git a/cypress/pages/workflows.ts b/cypress/pages/workflows.ts index 416528e85c..5f0b491d5f 100644 --- a/cypress/pages/workflows.ts +++ b/cypress/pages/workflows.ts @@ -23,6 +23,14 @@ export class WorkflowsPage extends BasePage { this.getters.workflowCard(workflowName).findChildByTestId('workflow-card-actions'), workflowDeleteButton: () => cy.getByTestId('action-toggle-dropdown').filter(':visible').contains('Delete'), + workflowFilterButton: () => cy.getByTestId('resources-list-filters-trigger').filter(':visible'), + workflowTagsDropdown: () => cy.getByTestId('tags-dropdown'), + workflowTagItem: (tag: string) => cy.getByTestId('tag').contains(tag), + workflowStatusDropdown: () => cy.getByTestId('status-dropdown'), + workflowStatusItem: (status: string) => cy.getByTestId('status').contains(status), + workflowOwnershipDropdown: () => cy.getByTestId('user-select-trigger'), + workflowOwner: (email: string) => cy.getByTestId('user-email').contains(email), + workflowResetFilters: () => cy.getByTestId('workflows-filter-reset'), // Not yet implemented // myWorkflows: () => cy.getByTestId('my-workflows'), // allWorkflows: () => cy.getByTestId('all-workflows'), diff --git a/packages/design-system/src/components/N8nUserInfo/UserInfo.vue b/packages/design-system/src/components/N8nUserInfo/UserInfo.vue index 747a4b5f93..de1ff1c5af 100644 --- a/packages/design-system/src/components/N8nUserInfo/UserInfo.vue +++ b/packages/design-system/src/components/N8nUserInfo/UserInfo.vue @@ -19,7 +19,7 @@
- {{ email }} + {{ email }}
diff --git a/packages/design-system/src/components/N8nUserSelect/UserSelect.vue b/packages/design-system/src/components/N8nUserSelect/UserSelect.vue index 0d76566831..b79bc2e7df 100644 --- a/packages/design-system/src/components/N8nUserSelect/UserSelect.vue +++ b/packages/design-system/src/components/N8nUserSelect/UserSelect.vue @@ -1,5 +1,6 @@