diff --git a/cypress/e2e/4-node-creator.cy.ts b/cypress/e2e/4-node-creator.cy.ts index fdd4e0e7d2..9797ed309b 100644 --- a/cypress/e2e/4-node-creator.cy.ts +++ b/cypress/e2e/4-node-creator.cy.ts @@ -314,4 +314,153 @@ describe('Node Creator', () => { WorkflowPage.getters.canvasNodes().should('have.length', 3); }); }); + + it('should have most relevenat nodes on top when searching', () => { + nodeCreatorFeature.getters.canvasAddButton().click(); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('email'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Email Trigger (IMAP)'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('Edit Fields (Set)'); + 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().eq(1).should('have.text', 'Switch'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('sw'); + nodeCreatorFeature.getters.searchBar().find('input').clear().type('Edit Fields (Set)'); + 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().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().eq(1).should('have.text', 'Switch'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('sw'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Switch'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('swit'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Switch'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('red'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Redis'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Reddit'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('redd'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Reddit'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('wh'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Webhook'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('web'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Webflow'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Webhook'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('webh'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Webhook'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('func'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Code'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('cod'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Coda'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Code'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('code'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Code'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('js'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Code'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Item Lists'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('fi'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Filter'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('filt'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Filter'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('manu'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Manual Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('sse'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'SSE Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('cmpar'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Compare Datasets'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('fb'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Facebook Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('crn'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Schedule Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('cron'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Schedule Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('sch'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Schedule Trigger'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('time'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Schedule Trigger'); + nodeCreatorFeature.getters.nodeItemName().eq(2).should('have.text', 'Wait'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('mail'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Mailgun'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('mailc'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Mailcheck'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Mailchimp'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('api'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'HTTP Request'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('s3'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'S3'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('no op'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'No Operation, do nothing'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('do no'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'No Operation, do nothing'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('htt'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'HTTP Request'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Webhook'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('http'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'HTTP Request'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Webhook'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('wa'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Wait'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Merge'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('wait'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Wait'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Merge'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('spreadsheet'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Spreadsheet File'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'Google Sheets'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('sheets'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Google Sheets'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('ggle she'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Google Sheets'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('hub'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'HubSpot'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('git'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'Git'); + nodeCreatorFeature.getters.nodeItemName().eq(1).should('have.text', 'GitHub'); + + nodeCreatorFeature.getters.searchBar().find('input').clear().type('gith'); + nodeCreatorFeature.getters.nodeItemName().first().should('have.text', 'GitHub'); + }); }); diff --git a/packages/editor-ui/src/components/Node/NodeCreator/utils.ts b/packages/editor-ui/src/components/Node/NodeCreator/utils.ts index fc00aef0cc..c9b680c78a 100644 --- a/packages/editor-ui/src/components/Node/NodeCreator/utils.ts +++ b/packages/editor-ui/src/components/Node/NodeCreator/utils.ts @@ -64,7 +64,7 @@ export function searchNodes(searchFilter: string, items: INodeCreateElement[]) { const trimmedFilter = searchFilter.toLowerCase().replace('trigger', '').trimEnd(); const result = ( sublimeSearch(trimmedFilter, items, [ - { key: 'properties.displayName', weight: 2 }, + { key: 'properties.displayName', weight: 1.3 }, { key: 'properties.codex.alias', weight: 1 }, ]) || [] ).map(({ item }) => item); diff --git a/packages/editor-ui/src/utils/sortUtils.ts b/packages/editor-ui/src/utils/sortUtils.ts index 785a6b945c..5fc1b5a1b8 100644 --- a/packages/editor-ui/src/utils/sortUtils.ts +++ b/packages/editor-ui/src/utils/sortUtils.ts @@ -4,12 +4,12 @@ // based on https://github.com/forrestthewoods/lib_fts/blob/master/code/fts_fuzzy_match.js -const SEQUENTIAL_BONUS = 30; // bonus for adjacent matches +const SEQUENTIAL_BONUS = 60; // bonus for adjacent matches const SEPARATOR_BONUS = 30; // bonus if match occurs after a separator const CAMEL_BONUS = 30; // bonus if match is uppercase and prev is lower const FIRST_LETTER_BONUS = 15; // bonus if the first letter is matched -const LEADING_LETTER_PENALTY = -15; // penalty applied for every letter in str before the first match +const LEADING_LETTER_PENALTY = -20; // penalty applied for every letter in str before the first match const MAX_LEADING_LETTER_PENALTY = -200; // maximum penalty for leading letters const UNMATCHED_LETTER_PENALTY = -5;