diff --git a/public/app/features/datasources/components/picker/DataSourceDropdown.tsx b/public/app/features/datasources/components/picker/DataSourceDropdown.tsx index 585c5665098..960c692faa0 100644 --- a/public/app/features/datasources/components/picker/DataSourceDropdown.tsx +++ b/public/app/features/datasources/components/picker/DataSourceDropdown.tsx @@ -16,7 +16,7 @@ import { DataSourceList } from './DataSourceList'; import { DataSourceLogo, DataSourceLogoPlaceHolder } from './DataSourceLogo'; import { DataSourceModal } from './DataSourceModal'; import { PickerContentProps, DataSourceDropdownProps } from './types'; -import { dataSourceLabel } from './utils'; +import { dataSourceLabel, matchDataSourceWithSearch } from './utils'; const INTERACTION_EVENT_NAME = 'dashboards_dspicker_clicked'; const INTERACTION_ITEM = { @@ -166,7 +166,7 @@ const PickerContent = React.forwardRef((prop {...props} current={current} onChange={changeCallback} - filter={(ds) => ds.name.toLowerCase().includes(filterTerm?.toLowerCase() ?? '')} + filter={(ds) => matchDataSourceWithSearch(ds, filterTerm)} > diff --git a/public/app/features/datasources/components/picker/DataSourceModal.tsx b/public/app/features/datasources/components/picker/DataSourceModal.tsx index 5d101c5b4c0..315f8a55aca 100644 --- a/public/app/features/datasources/components/picker/DataSourceModal.tsx +++ b/public/app/features/datasources/components/picker/DataSourceModal.tsx @@ -23,6 +23,7 @@ import { DATASOURCES_ROUTES } from 'app/features/datasources/constants'; import { AccessControlAction } from 'app/types'; import { DataSourceList } from './DataSourceList'; +import { matchDataSourceWithSearch } from './utils'; const INTERACTION_EVENT_NAME = 'dashboards_dspickermodal_clicked'; const INTERACTION_ITEM = { @@ -107,7 +108,7 @@ export function DataSourceModal({ dashboard={false} mixed={false} variables - filter={(ds) => ds.name.includes(search) && !ds.meta.builtIn} + filter={(ds) => matchDataSourceWithSearch(ds, search) && !ds.meta.builtIn} onChange={onChangeDataSource} current={current} /> diff --git a/public/app/features/datasources/components/picker/utils.test.ts b/public/app/features/datasources/components/picker/utils.test.ts index 163ca0f371f..3bd97048735 100644 --- a/public/app/features/datasources/components/picker/utils.test.ts +++ b/public/app/features/datasources/components/picker/utils.test.ts @@ -1,6 +1,6 @@ import { DataSourceInstanceSettings, DataSourceRef } from '@grafana/data'; -import { isDataSourceMatch, getDataSourceCompareFn } from './utils'; +import { isDataSourceMatch, getDataSourceCompareFn, matchDataSourceWithSearch } from './utils'; describe('isDataSourceMatch', () => { const dataSourceInstanceSettings = { uid: 'a' } as DataSourceInstanceSettings; @@ -93,3 +93,39 @@ describe('getDataSouceCompareFn', () => { ] as DataSourceInstanceSettings[]); }); }); + +describe('matchDataSourceWithSearch', () => { + let dataSource: DataSourceInstanceSettings; + + beforeEach(() => { + dataSource = { + name: 'My SQL DB', + } as DataSourceInstanceSettings; + }); + + it('should return true when the search term matches the data source name', () => { + const searchTerm = 'My SQL'; + expect(matchDataSourceWithSearch(dataSource, searchTerm)).toBe(true); + }); + + it('should return true when the search term matches part of the data source name', () => { + const searchTerm = 'SQL'; + expect(matchDataSourceWithSearch(dataSource, searchTerm)).toBe(true); + }); + + it('should return false when the search term does not match the data source name', () => { + const searchTerm = 'Oracle'; + expect(matchDataSourceWithSearch(dataSource, searchTerm)).toBe(false); + }); + + it('should return true when the search term is empty', () => { + const searchTerm = ''; + expect(matchDataSourceWithSearch(dataSource, searchTerm)).toBe(true); + }); + + it('should ignore case when matching the search term', () => { + dataSource.name = 'PostgreSQL DB'; + const searchTerm = 'postgre'; + expect(matchDataSourceWithSearch(dataSource, searchTerm)).toBe(true); + }); +}); diff --git a/public/app/features/datasources/components/picker/utils.ts b/public/app/features/datasources/components/picker/utils.ts index fdca19ecf15..96edb7e5de6 100644 --- a/public/app/features/datasources/components/picker/utils.ts +++ b/public/app/features/datasources/components/picker/utils.ts @@ -87,3 +87,14 @@ export function getDataSourceCompareFn( return cmpDataSources; } + +/** + * Given a data source and a search term, returns true if the data source matches the search term. + * Useful to filter data sources by name containing an string. + * @param ds + * @param searchTerm + * @returns + */ +export function matchDataSourceWithSearch(ds: DataSourceInstanceSettings, searchTerm = '') { + return ds.name.toLowerCase().includes(searchTerm.toLowerCase()); +}