feat(editor): Update command bar wf search to match by any query term (#21798)

This commit is contained in:
Svetoslav Dekov 2025-11-19 09:45:28 +02:00 committed by GitHub
parent 1a142e5aba
commit 55912079d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 175 additions and 0 deletions

View File

@ -139,5 +139,171 @@ describe('components', () => {
expect(screen.queryByPlaceholderText('Type a command...')).not.toBeInTheDocument(),
);
});
describe('matchAnySearchTerm', () => {
it('should match entire query string when matchAnySearchTerm is false', async () => {
const items = [
{
id: 'workflow-1',
title: 'Customer Data Sync',
matchAnySearchTerm: false,
},
{
id: 'workflow-2',
title: 'Email Marketing Campaign',
matchAnySearchTerm: false,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'customer data');
await nextTick();
expect(screen.getByText('Customer Data Sync')).toBeInTheDocument();
expect(screen.queryByText('Email Marketing Campaign')).not.toBeInTheDocument();
});
it('should match any word when matchAnySearchTerm is true', async () => {
const items = [
{
id: 'workflow-1',
title: 'Customer Data Sync',
matchAnySearchTerm: true,
},
{
id: 'workflow-2',
title: 'Email Marketing Campaign',
matchAnySearchTerm: true,
},
{
id: 'workflow-3',
title: 'Sales Report Generator',
matchAnySearchTerm: true,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'customer email');
await nextTick();
expect(screen.getByText('Customer Data Sync')).toBeInTheDocument();
expect(screen.getByText('Email Marketing Campaign')).toBeInTheDocument();
expect(screen.queryByText('Sales Report Generator')).not.toBeInTheDocument();
});
it('should match keywords with matchAnySearchTerm', async () => {
const items = [
{
id: 'workflow-1',
title: 'Data Processor',
keywords: ['excel', 'spreadsheet', 'csv'],
matchAnySearchTerm: true,
},
{
id: 'workflow-2',
title: 'Email Handler',
keywords: ['gmail', 'outlook', 'mail'],
matchAnySearchTerm: true,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'excel gmail');
await nextTick();
expect(screen.getByText('Data Processor')).toBeInTheDocument();
expect(screen.getByText('Email Handler')).toBeInTheDocument();
});
it('should handle multiple spaces in search query', async () => {
const items = [
{
id: 'workflow-1',
title: 'Customer Sync',
matchAnySearchTerm: true,
},
{
id: 'workflow-2',
title: 'Email Campaign',
matchAnySearchTerm: true,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'customer email ');
await nextTick();
expect(screen.getByText('Customer Sync')).toBeInTheDocument();
expect(screen.getByText('Email Campaign')).toBeInTheDocument();
});
it('should match single word with matchAnySearchTerm', async () => {
const items = [
{
id: 'workflow-1',
title: 'Customer Data Sync',
matchAnySearchTerm: true,
},
{
id: 'workflow-2',
title: 'Email Marketing',
matchAnySearchTerm: true,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'customer');
await nextTick();
expect(screen.getByText('Customer Data Sync')).toBeInTheDocument();
expect(screen.queryByText('Email Marketing')).not.toBeInTheDocument();
});
it('should work with mixed matchAnySearchTerm settings', async () => {
const items = [
{
id: 'workflow-1',
title: 'Customer Data Sync',
matchAnySearchTerm: true,
},
{
id: 'workflow-2',
title: 'Customer Email Setup',
matchAnySearchTerm: false,
},
];
render(N8nCommandBar, { props: { items } });
await openCommandBar();
const input = screen.getByPlaceholderText('Type a command...');
await fireEvent.update(input, 'data email');
await nextTick();
expect(screen.getByText('Customer Data Sync')).toBeInTheDocument();
expect(screen.queryByText('Customer Email Setup')).not.toBeInTheDocument();
});
});
});
});

View File

@ -67,6 +67,13 @@ const filteredItems = computed(() => {
.join(' ')
.toLowerCase();
if (item.matchAnySearchTerm) {
return query
.split(' ')
.filter(Boolean)
.some((word) => searchText.includes(word));
}
return searchText.includes(query);
});
}

View File

@ -10,4 +10,5 @@ export interface CommandBarItem {
children?: CommandBarItem[];
placeholder?: string;
hasMoreChildren?: boolean;
matchAnySearchTerm?: boolean;
}

View File

@ -285,6 +285,7 @@ export function useWorkflowNavigationCommands(options: {
return {
id: workflow.id,
matchAnySearchTerm: !isRoot,
title: {
component: CommandBarItemTitle,
props: {