diff --git a/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.test.tsx b/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.test.tsx index bd424211325e..3e6c99e420d6 100644 --- a/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.test.tsx +++ b/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.test.tsx @@ -4,7 +4,7 @@ */ import React from 'react'; -import { render, act } from '@testing-library/react'; +import { render, act, screen, fireEvent } from '@testing-library/react'; import { DataSourceSelectable } from './datasource_selectable'; import { DataSourceType, GenericDataSource } from '../datasource_services'; import { DataSourceGroup, DataSourceOption } from './types'; @@ -81,4 +81,104 @@ describe('DataSourceSelectable', () => { expect(onFetchDataSetErrorMock).toHaveBeenCalledWith(new Error('Fetch error')); }); + + it('should sort index patterns list alphabetically', async () => { + const mockDataSourceOptionList = [ + { + label: 'Index patterns', + options: [ + { label: 'logstash-*' }, + { label: '000-*' }, + { label: 'p000-1' }, + { label: 'pattern_archive' }, + { label: 'index_main' }, + { label: 'index-2024' }, + ], + }, + ] as any; + + render( + + ); + + const button = screen.getByLabelText('Open list of options'); + fireEvent.click(button); + expect( + screen.getByTestId('comboBoxOptionsList dataExplorerDSSelect-optionsList') + ).toBeInTheDocument(); + const defaultDSOptions = document.querySelectorAll('.euiComboBoxOption__content'); + const optionTexts = Array.from(defaultDSOptions).map((option) => option.innerHTML); + const expectedIndexPatternSortedOrder = [ + '000-*', + 'index_main', + 'index-2024', + 'logstash-*', + 'p000-1', + 'pattern_archive', + ]; + expect(optionTexts).toEqual(expectedIndexPatternSortedOrder); + }); + + it('should sort non index patterns list alphabetically', async () => { + const mockDataSourceOptionList = [ + { + label: 'Amazon S3', + options: [ + { label: 'mys3' }, + { label: '*starred' }, + { label: 'alpha-test-s3' }, + { label: '@special' }, + { label: 's3-2024' }, + { label: 'S3_Archive' }, + ], + }, + ] as any; + + render( + + ); + + const button = screen.getByLabelText('Open list of options'); + fireEvent.click(button); + expect( + screen.getByTestId('comboBoxOptionsList dataExplorerDSSelect-optionsList') + ).toBeInTheDocument(); + const defaultDSOptions = document.querySelectorAll('.euiComboBoxOption__content'); + const optionTexts = Array.from(defaultDSOptions).map((option) => option.innerHTML); + const expectedIndexPatternSortedOrder = [ + '@special', + '*starred', + 'alpha-test-s3', + 'mys3', + 'S3_Archive', + 's3-2024', + ]; + expect(optionTexts).toEqual(expectedIndexPatternSortedOrder); + }); }); diff --git a/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.tsx b/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.tsx index aaab4d57c830..2e6768197136 100644 --- a/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.tsx +++ b/src/plugins/data/public/data_sources/datasource_selector/datasource_selectable.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect, useCallback } from 'react'; +import React, { useEffect, useCallback, useMemo } from 'react'; import { EuiComboBox } from '@elastic/eui'; import { i18n } from '@osd/i18n'; import { ISourceDataSet, IndexPatternOption } from '../datasource'; @@ -118,13 +118,24 @@ export const DataSourceSelectable = ({ [onDataSourceSelect] ); + const memorizedDataSourceOptionList = useMemo(() => { + return dataSourceOptionList.map((dsGroup: DataSourceGroup) => { + return { + ...dsGroup, + options: [...dsGroup.options].sort((ds1, ds2) => { + return ds1.label.localeCompare(ds2.label, undefined, { sensitivity: 'base' }); + }), + }; + }); + }, [dataSourceOptionList]); + return (