From 7e1d94001049057ccf4daa7c83ad0638f3fb3ae0 Mon Sep 17 00:00:00 2001 From: Zhongnan Su Date: Wed, 10 Apr 2024 17:13:53 -0700 Subject: [PATCH] [MD] Add OpenSearch cluster group label to top of options in DataSourceSelectable dropdown (#6400) Signed-off-by: Zhongnan Su --- CHANGELOG.md | 1 + .../components/data_source_menu/types.ts | 5 +++ .../data_source_selectable.test.tsx.snap | 5 +++ .../data_source_selectable.test.tsx | 44 ++++++++++++++++++- .../data_source_selectable.tsx | 20 ++++++++- 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 966d0f18e2b4..12391cc13614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Workspace] Add APIs to support plugin state in request ([#6303](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6303)) - [Workspace] Filter left nav menu items according to the current workspace ([#6234](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6234)) - [Multiple Datasource] Refactor data source selector component to include placeholder and add tests ([#6372](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6372)) +- [MD] Add OpenSearch cluster group label to top of single selectable dropdown ([#6400](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6400)) ### 🐛 Bug Fixes diff --git a/src/plugins/data_source_management/public/components/data_source_menu/types.ts b/src/plugins/data_source_management/public/components/data_source_menu/types.ts index 32edbddf09a7..17aa35d8b8d0 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/types.ts +++ b/src/plugins/data_source_management/public/components/data_source_menu/types.ts @@ -16,6 +16,11 @@ export interface DataSourceOption { label?: string; } +export interface DataSourceGroupLabelOption extends DataSourceOption { + label: string; + isGroupLabel: true; +} + export interface DataSourceBaseConfig { fullWidth: boolean; disabled?: boolean; diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap index adc2929a7bc8..851d37b3d71b 100644 --- a/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap +++ b/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap @@ -51,6 +51,11 @@ exports[`DataSourceSelectable should filter options if configured 1`] = ` onChange={[Function]} options={ Array [ + Object { + "id": "opensearchClusterGroupLabel", + "isGroupLabel": true, + "label": "OpenSearch cluster", + }, Object { "checked": "on", "id": "", diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx index efa1215ed11a..78b63a57144c 100644 --- a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx +++ b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx @@ -7,11 +7,12 @@ import { ShallowWrapper, shallow, mount } from 'enzyme'; import { SavedObjectsClientContract } from '../../../../../core/public'; import { notificationServiceMock } from '../../../../../core/public/mocks'; import React from 'react'; -import { DataSourceSelectable } from './data_source_selectable'; +import { DataSourceSelectable, opensearchClusterGroupLabel } from './data_source_selectable'; import { AuthType } from '../../types'; import { getDataSourcesWithFieldsResponse, mockResponseForSavedObjectsCalls } from '../../mocks'; -import { getByRole, render } from '@testing-library/react'; +import { render } from '@testing-library/react'; import * as utils from '../utils'; +import { EuiSelectable } from '@elastic/eui'; describe('DataSourceSelectable', () => { let component: ShallowWrapper, React.Component<{}, {}, any>>; @@ -391,4 +392,43 @@ describe('DataSourceSelectable', () => { expect(onSelectedDataSource).toBeCalledWith([{ id: 'test2', label: 'test2' }]); expect(onSelectedDataSource).toHaveBeenCalled(); }); + + it('should render opensearch cluster group label at the top of options, when there are options availiable', async () => { + const onSelectedDataSource = jest.fn(); + component = shallow( + + ); + + component.instance().componentDidMount!(); + await nextTick(); + const optionsProp = component.find(EuiSelectable).prop('options'); + expect(optionsProp[0]).toEqual(opensearchClusterGroupLabel); + }); + + it('should not render opensearch cluster group label, when there is no option availiable', async () => { + const onSelectedDataSource = jest.fn(); + spyOn(utils, 'getDefaultDataSource').and.returnValue([]); + component = shallow( + + ); + + component.instance().componentDidMount!(); + await nextTick(); + const optionsProp = component.find(EuiSelectable).prop('options'); + expect(optionsProp).toEqual([]); + }); }); diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx index 88cee94cf6af..40a7edce7558 100644 --- a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx +++ b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx @@ -25,7 +25,7 @@ import { getDataSourcesWithFields, getDefaultDataSource, getFilteredDataSources import { LocalCluster } from '../data_source_selector/data_source_selector'; import { SavedObject } from '../../../../../core/public'; import { DataSourceAttributes } from '../../types'; -import { DataSourceOption } from '../data_source_menu/types'; +import { DataSourceGroupLabelOption, DataSourceOption } from '../data_source_menu/types'; interface DataSourceSelectableProps { savedObjectsClient: SavedObjectsClientContract; @@ -50,6 +50,12 @@ interface SelectedDataSourceOption extends DataSourceOption { checked?: string; } +export const opensearchClusterGroupLabel: DataSourceGroupLabelOption = { + id: 'opensearchClusterGroupLabel', + label: 'OpenSearch cluster', + isGroupLabel: true, +}; + export class DataSourceSelectable extends React.Component< DataSourceSelectableProps, DataSourceSelectableState @@ -207,6 +213,16 @@ export class DataSourceSelectable extends React.Component< } } + getOptionsWithGroupLabel = (dataSourceOptions: DataSourceOption[]): DataSourceOption[] => { + let optionsWithGroupLabel: DataSourceOption[] = []; + if (dataSourceOptions.length === 0) { + optionsWithGroupLabel = []; + } else { + optionsWithGroupLabel = [opensearchClusterGroupLabel, ...dataSourceOptions]; + } + return optionsWithGroupLabel; + }; + render() { const button = ( <> @@ -248,7 +264,7 @@ export class DataSourceSelectable extends React.Component< searchProps={{ placeholder: 'Search', }} - options={this.state.dataSourceOptions} + options={this.getOptionsWithGroupLabel(this.state.dataSourceOptions)} onChange={(newOptions) => this.onChange(newOptions)} singleSelection={true} data-test-subj={'dataSourceSelectable'}