diff --git a/examples/multiple_data_source_examples/public/components/data_source_view_example.tsx b/examples/multiple_data_source_examples/public/components/data_source_view_example.tsx index b80a65bb1b1a..fb2d51f430d1 100644 --- a/examples/multiple_data_source_examples/public/components/data_source_view_example.tsx +++ b/examples/multiple_data_source_examples/public/components/data_source_view_example.tsx @@ -18,6 +18,7 @@ import { CoreStart, MountPoint } from 'opensearch-dashboards/public'; import { DataSourceManagementPluginSetup, DataSourceViewConfig, + DataSourceSelection, } from 'src/plugins/data_source_management/public'; import { ComponentProp } from './types'; import { COLUMNS } from './constants'; @@ -88,6 +89,7 @@ export const DataSourceViewExample = ({ setSelectedDataSources(ds); }, }} + dataSourceSelection={new DataSourceSelection()} /> ); }, [setActionMenu, notifications, savedObjects]); diff --git a/src/plugins/data_source_management/public/index.ts b/src/plugins/data_source_management/public/index.ts index 0cc7370d2cdc..442991d1d58c 100644 --- a/src/plugins/data_source_management/public/index.ts +++ b/src/plugins/data_source_management/public/index.ts @@ -24,3 +24,4 @@ export { DataSourceMultiSelectableConfig, createDataSourceMenu, } from './components/data_source_menu'; +export { DataSourceSelection } from './service/data_source_selection_service'; diff --git a/src/plugins/data_source_management/public/service/data_source_selection_service.test.ts b/src/plugins/data_source_management/public/service/data_source_selection_service.test.ts new file mode 100644 index 000000000000..b199092979e3 --- /dev/null +++ b/src/plugins/data_source_management/public/service/data_source_selection_service.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +import { DataSourceSelection } from './data_source_selection_service'; +import { generateComponentId } from '../components/utils'; + +describe('DataSourceSelection service', () => { + it('basic set, get and remove', async () => { + const dataSourceSelection = new DataSourceSelection(); + const id = generateComponentId(); + const dataSource = { id: 'id', label: 'label' }; + expect(dataSourceSelection.getSelectionValue().get(id)).toBe(undefined); + dataSourceSelection.selectDataSource(id, [dataSource]); + expect(dataSourceSelection.getSelectionValue().get(id)).toStrictEqual([dataSource]); + dataSourceSelection.remove(id); + expect(dataSourceSelection.getSelectionValue().get(id)).toBe(undefined); + }); + + it('multiple set and get', async () => { + const dataSourceSelection = new DataSourceSelection(); + const id1 = generateComponentId(); + const id2 = generateComponentId(); + + const dataSource = { id: 'id', label: 'label' }; + expect(dataSourceSelection.getSelectionValue().get(id1)).toBe(undefined); + expect(dataSourceSelection.getSelectionValue().get(id2)).toBe(undefined); + dataSourceSelection.selectDataSource(id1, [dataSource]); + dataSourceSelection.selectDataSource(id2, [dataSource]); + expect(dataSourceSelection.getSelectionValue().get(id1)).toStrictEqual([dataSource]); + expect(dataSourceSelection.getSelectionValue().get(id2)).toStrictEqual([dataSource]); + dataSourceSelection.remove(id1); + expect(dataSourceSelection.getSelectionValue().get(id1)).toBe(undefined); + expect(dataSourceSelection.getSelectionValue().get(id2)).toStrictEqual([dataSource]); + }); + + it('support subscribing selected observable', (done) => { + const dataSourceSelection = new DataSourceSelection(); + const selectedDataSource$ = dataSourceSelection.getSelection$(); + const id = generateComponentId(); + const dataSource = { id: 'id', label: 'label' }; + dataSourceSelection.selectDataSource(id, [dataSource]); + selectedDataSource$.subscribe((newValue) => { + expect(newValue.get(id)).toStrictEqual([dataSource]); + done(); + }); + }); +}); diff --git a/src/plugins/data_source_management/public/service/data_source_selection_service.ts b/src/plugins/data_source_management/public/service/data_source_selection_service.ts index 39d19a6ad5a5..daddfacea0b8 100644 --- a/src/plugins/data_source_management/public/service/data_source_selection_service.ts +++ b/src/plugins/data_source_management/public/service/data_source_selection_service.ts @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import uuid from 'uuid'; import { BehaviorSubject } from 'rxjs'; import { DataSourceOption } from '../components/data_source_menu/types'; @@ -30,8 +29,4 @@ export class DataSourceSelection { public getSelection$ = () => { return this.selectedDataSource$; }; - - public generateComponentId = () => { - return uuid.v4(); - }; } diff --git a/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu.test.tsx.snap b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu.test.tsx.snap index 7a7063db0601..fac09bca1b93 100644 --- a/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu.test.tsx.snap +++ b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu.test.tsx.snap @@ -45,6 +45,23 @@ exports[`TopNavMenu mounts the data source menu as well as top nav menu 1`] = ` } } componentType="DataSourceView" + dataSourceSelection={ + DataSourceSelection { + "getSelection$": [Function], + "getSelectionValue": [Function], + "remove": [Function], + "selectDataSource": [Function], + "selectedDataSource$": BehaviorSubject { + "_isScalar": false, + "_value": Map {}, + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, + } + } /> @@ -71,6 +88,23 @@ exports[`TopNavMenu mounts the data source menu if showDataSourceMenu is true 1` } } componentType="DataSourceView" + dataSourceSelection={ + DataSourceSelection { + "getSelection$": [Function], + "getSelectionValue": [Function], + "remove": [Function], + "selectDataSource": [Function], + "selectedDataSource$": BehaviorSubject { + "_isScalar": false, + "_value": Map {}, + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, + } + } /> diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx index a63aaf4d60d2..82495dcc1e30 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx @@ -36,6 +36,7 @@ import { TopNavMenu } from './top_nav_menu'; import { TopNavMenuData } from './top_nav_menu_data'; import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers'; import * as testUtils from '../../../data_source_management/public/components/utils'; +import { DataSourceSelection } from '../../../data_source_management/public/service/data_source_selection_service'; const dataShim = { ui: { @@ -63,6 +64,7 @@ describe('TopNavMenu', () => { run: jest.fn(), }, ]; + const dataSourceSelection = new DataSourceSelection(); it('Should render nothing when no config is provided', () => { const component = shallowWithIntl(); @@ -122,6 +124,7 @@ describe('TopNavMenu', () => { spyOn(testUtils, 'getApplication').and.returnValue({ id: 'test2' }); spyOn(testUtils, 'getUiSettings').and.returnValue({ id: 'test2' }); spyOn(testUtils, 'getHideLocalCluster').and.returnValue(true); + spyOn(testUtils, 'getDataSourceSelection').and.returnValue(dataSourceSelection); const component = shallowWithIntl( { fullWidth: true, activeOption: [{ label: 'what', id: '1' }], }, + dataSourceSelection, }} /> ); @@ -144,6 +148,7 @@ describe('TopNavMenu', () => { spyOn(testUtils, 'getApplication').and.returnValue({ id: 'test2' }); spyOn(testUtils, 'getUiSettings').and.returnValue({ id: 'test2' }); spyOn(testUtils, 'getHideLocalCluster').and.returnValue(true); + spyOn(testUtils, 'getDataSourceSelection').and.returnValue(dataSourceSelection); const component = shallowWithIntl( { fullWidth: true, activeOption: [{ label: 'what', id: '1' }], }, + dataSourceSelection: new DataSourceSelection(), }} /> );