From 7d8e167488cdb3f4205f3f480f4c888c6ce37e2e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 31 May 2024 17:30:40 +0000 Subject: [PATCH] [Multi Datasource] Unify getDefaultDataSourceId and export (#6843) * Unify getDefaultDataSourceId and export Signed-off-by: tygao * Changeset file for PR #6843 created/updated * test: add tests for utils Signed-off-by: tygao * return utils in setup Signed-off-by: tygao * update interface Signed-off-by: tygao --------- Signed-off-by: tygao Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> (cherry picked from commit c7c47d283a61dd1078d624b4b9d17c24ace27f95) Signed-off-by: github-actions[bot] --- changelogs/fragments/6843.yml | 2 ++ .../public/components/constants.tsx | 2 ++ .../data_source_aggregated_view.tsx | 3 +- .../data_source_multi_selectable.tsx | 3 +- .../data_source_selectable.tsx | 3 +- .../data_source_selector.tsx | 3 +- .../data_source_table/data_source_table.tsx | 11 +++++-- .../data_source_view/data_source_view.tsx | 3 +- .../edit_data_source/edit_data_source.tsx | 8 +++-- .../public/components/utils.test.ts | 32 +++++++++++++++++++ .../public/components/utils.ts | 17 ++++++++-- .../data_source_management/public/index.ts | 1 + .../data_source_management/public/mocks.ts | 2 +- .../data_source_management/public/plugin.ts | 6 ++++ 14 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/6843.yml diff --git a/changelogs/fragments/6843.yml b/changelogs/fragments/6843.yml new file mode 100644 index 000000000000..2c483392bc2d --- /dev/null +++ b/changelogs/fragments/6843.yml @@ -0,0 +1,2 @@ +refactor: +- Unify getDefaultDataSourceId and export ([#6843](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6843)) \ No newline at end of file diff --git a/src/plugins/data_source_management/public/components/constants.tsx b/src/plugins/data_source_management/public/components/constants.tsx index 720e2d175867..23a71ec45ed0 100644 --- a/src/plugins/data_source_management/public/components/constants.tsx +++ b/src/plugins/data_source_management/public/components/constants.tsx @@ -17,3 +17,5 @@ export const NO_DATASOURCES_CONNECTED_MESSAGE = 'No data sources connected yet.' export const CONNECT_DATASOURCES_MESSAGE = 'Connect your data sources to get started.'; export const NO_COMPATIBLE_DATASOURCES_MESSAGE = 'No compatible data sources are available.'; export const ADD_COMPATIBLE_DATASOURCES_MESSAGE = 'Add a compatible data source.'; + +export const DEFAULT_DATA_SOURCE_UI_SETTINGS_ID = 'defaultDataSource'; diff --git a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx index 8eda8143c805..b18bcbb69ea3 100644 --- a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx +++ b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx @@ -18,6 +18,7 @@ import { handleNoAvailableDataSourceError, generateComponentId, getDataSourceSelection, + getDefaultDataSourceId, } from '../utils'; import { SavedObject } from '../../../../../core/public'; import { DataSourceAttributes } from '../../types'; @@ -132,7 +133,7 @@ export class DataSourceAggregatedView extends React.Component< this.setState({ ...this.state, allDataSourcesIdToTitleMap, - defaultDataSource: this.props.uiSettings?.get('defaultDataSource', null) ?? null, + defaultDataSource: getDefaultDataSourceId(this.props.uiSettings) ?? null, showEmptyState: allDataSourcesIdToTitleMap.size === 0, }); }) diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx index 995a5f3ca731..da1b6fe6c5e6 100644 --- a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx @@ -18,6 +18,7 @@ import { handleNoAvailableDataSourceError, generateComponentId, getDataSourceSelection, + getDefaultDataSourceId, } from '../utils'; import { DataSourceBaseState } from '../data_source_menu/types'; import { DataSourceErrorMenu } from '../data_source_error_menu'; @@ -76,7 +77,7 @@ export class DataSourceMultiSelectable extends React.Component< async componentDidMount() { this._isMounted = true; try { - const defaultDataSource = this.props.uiSettings?.get('defaultDataSource', null) ?? null; + const defaultDataSource = getDefaultDataSourceId(this.props.uiSettings) ?? null; let selectedOptions: SelectedDataSourceOption[] = []; const fetchedDataSources = await getDataSourcesWithFields(this.props.savedObjectsClient, [ 'id', 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 b181da74e542..a1cddb1f8c2b 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 @@ -26,6 +26,7 @@ import { handleNoAvailableDataSourceError, generateComponentId, getDataSourceSelection, + getDefaultDataSourceId, } from '../utils'; import { LocalCluster } from '../data_source_selector/data_source_selector'; import { SavedObject } from '../../../../../core/public'; @@ -209,7 +210,7 @@ export class DataSourceSelectable extends React.Component< return; } - const defaultDataSource = this.props.uiSettings?.get('defaultDataSource', null) ?? null; + const defaultDataSource = getDefaultDataSourceId(this.props.uiSettings) ?? null; if (this.props.selectedOption?.length) { this.handleSelectedOption(dataSourceOptions, defaultDataSource); diff --git a/src/plugins/data_source_management/public/components/data_source_selector/data_source_selector.tsx b/src/plugins/data_source_management/public/components/data_source_selector/data_source_selector.tsx index 5d9c1b17fbd9..30c052c4db9d 100644 --- a/src/plugins/data_source_management/public/components/data_source_selector/data_source_selector.tsx +++ b/src/plugins/data_source_management/public/components/data_source_selector/data_source_selector.tsx @@ -14,6 +14,7 @@ import { getFilteredDataSources, generateComponentId, getDataSourceSelection, + getDefaultDataSourceId, } from '../utils'; import { DataSourceAttributes } from '../../types'; import { DataSourceItem } from '../data_source_item'; @@ -164,7 +165,7 @@ export class DataSourceSelector extends React.Component< return; } - const defaultDataSource = this.props.uiSettings?.get('defaultDataSource', null) ?? null; + const defaultDataSource = getDefaultDataSourceId(this.props.uiSettings) ?? null; // 5.1 Empty default option, [], just want to show placeholder if (this.props.defaultOption?.length === 0) { this.setState({ diff --git a/src/plugins/data_source_management/public/components/data_source_table/data_source_table.tsx b/src/plugins/data_source_management/public/components/data_source_table/data_source_table.tsx index 9b9fd9488290..718f83e5e977 100644 --- a/src/plugins/data_source_management/public/components/data_source_table/data_source_table.tsx +++ b/src/plugins/data_source_management/public/components/data_source_table/data_source_table.tsx @@ -29,7 +29,12 @@ import { } from '../../../../opensearch_dashboards_react/public'; import { DataSourceManagementContext, DataSourceTableItem, ToastMessageItem } from '../../types'; import { CreateButton } from '../create_button'; -import { deleteMultipleDataSources, getDataSources, setFirstDataSourceAsDefault } from '../utils'; +import { + deleteMultipleDataSources, + getDataSources, + setFirstDataSourceAsDefault, + getDefaultDataSourceId, +} from '../utils'; import { LoadingMask } from '../loading_mask'; /* Table config */ @@ -149,7 +154,7 @@ export const DataSourceTable = ({ history }: RouteComponentProps) => { {name} - {index.id === uiSettings.get('defaultDataSource', null) ? ( + {index.id === getDefaultDataSourceId(uiSettings) ? ( Default @@ -251,7 +256,7 @@ export const DataSourceTable = ({ history }: RouteComponentProps) => { const setDefaultDataSource = async () => { try { for (const dataSource of selectedDataSources) { - if (uiSettings.get('defaultDataSource') === dataSource.id) { + if (getDefaultDataSourceId(uiSettings) === dataSource.id) { await setFirstDataSourceAsDefault(savedObjects.client, uiSettings, true); } } diff --git a/src/plugins/data_source_management/public/components/data_source_view/data_source_view.tsx b/src/plugins/data_source_management/public/components/data_source_view/data_source_view.tsx index 6080d91d0e4f..f80710b6452e 100644 --- a/src/plugins/data_source_management/public/components/data_source_view/data_source_view.tsx +++ b/src/plugins/data_source_management/public/components/data_source_view/data_source_view.tsx @@ -18,6 +18,7 @@ import { handleDataSourceFetchError, generateComponentId, getDataSourceSelection, + getDefaultDataSourceId, } from '../utils'; import { DataSourceDropDownHeader } from '../drop_down_header'; import { DataSourceItem } from '../data_source_item'; @@ -71,7 +72,7 @@ export class DataSourceView extends React.Component { - await uiSettings.set('defaultDataSource', dataSourceID); + await uiSettings.set(DEFAULT_DATA_SOURCE_UI_SETTINGS_ID, dataSourceID); }; - const isDefaultDataSource = uiSettings.get('defaultDataSource', null) === dataSourceID; + const isDefaultDataSource = getDefaultDataSourceId(uiSettings) === dataSourceID; /* Handle submit - create data source*/ const handleSubmit = async (attributes: DataSourceAttributes) => { @@ -126,7 +128,7 @@ export const EditDataSource: React.FunctionComponent { try { - if (uiSettings.get('defaultDataSource') === dataSourceID) { + if (getDefaultDataSourceId(uiSettings) === dataSourceID) { await setFirstDataSourceAsDefault(savedObjects.client, uiSettings, true); } } catch (e) { diff --git a/src/plugins/data_source_management/public/components/utils.test.ts b/src/plugins/data_source_management/public/components/utils.test.ts index a8349b669157..ceeec875f106 100644 --- a/src/plugins/data_source_management/public/components/utils.test.ts +++ b/src/plugins/data_source_management/public/components/utils.test.ts @@ -22,6 +22,8 @@ import { handleNoAvailableDataSourceError, getDataSourceSelection, setDataSourceSelection, + getDefaultDataSourceId, + getDefaultDataSourceId$, } from './utils'; import { coreMock, notificationServiceMock } from '../../../../core/public/mocks'; import { @@ -59,6 +61,7 @@ import { DataSourceSelectionService, defaultDataSourceSelection, } from '../service/data_source_selection_service'; +import { Observable, of } from 'rxjs'; const { savedObjects } = coreMock.createStart(); const { uiSettings } = coreMock.createStart(); @@ -658,4 +661,33 @@ describe('DataSourceManagement: Utils.ts', () => { expect(result).toEqual(dataSourceSelection); }); }); + describe('getDefaultDataSourceId', () => { + it('should return null if uiSettings is not passed', () => { + mockUiSettingsCalls(uiSettings, 'get', 'id-1'); + const result = getDefaultDataSourceId(); + expect(result).toEqual(null); + }); + + it('should return string value normally', () => { + mockUiSettingsCalls(uiSettings, 'get', 'id-1'); + const result = getDefaultDataSourceId(uiSettings); + expect(result).toEqual('id-1'); + }); + }); + + describe('getDefaultDataSourceId$', () => { + it('should return null if uiSettings is not passed', () => { + mockUiSettingsCalls(uiSettings, 'get', 'id-1'); + const result = getDefaultDataSourceId$(); + expect(result).toEqual(null); + }); + + it('should return observable value normally', () => { + const id$ = of('id-1'); + mockUiSettingsCalls(uiSettings, 'get$', id$); + const result$ = getDefaultDataSourceId$(uiSettings); + expect(result$).toBeInstanceOf(Observable); + expect(result$).toEqual(id$); + }); + }); }); diff --git a/src/plugins/data_source_management/public/components/utils.ts b/src/plugins/data_source_management/public/components/utils.ts index ac048db0587b..2de485d881b6 100644 --- a/src/plugins/data_source_management/public/components/utils.ts +++ b/src/plugins/data_source_management/public/components/utils.ts @@ -31,6 +31,7 @@ import { CONNECT_DATASOURCES_MESSAGE, NO_COMPATIBLE_DATASOURCES_MESSAGE, NO_DATASOURCES_CONNECTED_MESSAGE, + DEFAULT_DATA_SOURCE_UI_SETTINGS_ID, } from './constants'; import { DataSourceSelectionService, @@ -78,7 +79,7 @@ export async function handleSetDefaultDatasource( savedObjectsClient: SavedObjectsClientContract, uiSettings: IUiSettingsClient ) { - if (uiSettings.get('defaultDataSource', null) === null) { + if (getDefaultDataSourceId(uiSettings) === null) { return await setFirstDataSourceAsDefault(savedObjectsClient, uiSettings, false); } } @@ -89,12 +90,12 @@ export async function setFirstDataSourceAsDefault( exists: boolean ) { if (exists) { - uiSettings.remove('defaultDataSource'); + uiSettings.remove(DEFAULT_DATA_SOURCE_UI_SETTINGS_ID); } const listOfDataSources: DataSourceTableItem[] = await getDataSources(savedObjectsClient); if (Array.isArray(listOfDataSources) && listOfDataSources.length >= 1) { const datasourceId = listOfDataSources[0].id; - return await uiSettings.set('defaultDataSource', datasourceId); + return await uiSettings.set(DEFAULT_DATA_SOURCE_UI_SETTINGS_ID, datasourceId); } } @@ -135,6 +136,16 @@ export function getFilteredDataSources( .sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase())); } +export function getDefaultDataSourceId(uiSettings?: IUiSettingsClient) { + if (!uiSettings) return null; + return uiSettings.get(DEFAULT_DATA_SOURCE_UI_SETTINGS_ID, null); +} + +export function getDefaultDataSourceId$(uiSettings?: IUiSettingsClient) { + if (!uiSettings) return null; + return uiSettings.get$(DEFAULT_DATA_SOURCE_UI_SETTINGS_ID, null); +} + export function getDefaultDataSource( dataSourcesOptions: DataSourceOption[], LocalCluster: DataSourceOption, diff --git a/src/plugins/data_source_management/public/index.ts b/src/plugins/data_source_management/public/index.ts index 2607f5b8c7f9..35a0474947d2 100644 --- a/src/plugins/data_source_management/public/index.ts +++ b/src/plugins/data_source_management/public/index.ts @@ -25,3 +25,4 @@ export { createDataSourceMenu, } from './components/data_source_menu'; export { DataSourceSelectionService } from './service/data_source_selection_service'; +export { getDefaultDataSourceId, getDefaultDataSourceId$ } from './components/utils'; diff --git a/src/plugins/data_source_management/public/mocks.ts b/src/plugins/data_source_management/public/mocks.ts index a33a55d6799c..abc4af28dd4c 100644 --- a/src/plugins/data_source_management/public/mocks.ts +++ b/src/plugins/data_source_management/public/mocks.ts @@ -361,7 +361,7 @@ export const mockErrorResponseForSavedObjectsCalls = ( export const mockUiSettingsCalls = ( uiSettings: IUiSettingsClient, - uiSettingsMethodName: 'get' | 'set', + uiSettingsMethodName: 'get' | 'set' | 'get$', response: any ) => { (uiSettings[uiSettingsMethodName] as jest.Mock).mockReturnValue(response); diff --git a/src/plugins/data_source_management/public/plugin.ts b/src/plugins/data_source_management/public/plugin.ts index 2f08b942db15..a371936b8ee7 100644 --- a/src/plugins/data_source_management/public/plugin.ts +++ b/src/plugins/data_source_management/public/plugin.ts @@ -26,6 +26,8 @@ import { setHideLocalCluster, setUiSettings, setDataSourceSelection, + getDefaultDataSourceId, + getDefaultDataSourceId$, } from './components/utils'; import { DataSourceSelectionService } from './service/data_source_selection_service'; @@ -42,6 +44,8 @@ export interface DataSourceManagementPluginSetup { getDataSourceMenu: () => React.ComponentType>; }; dataSourceSelection: DataSourceSelectionService; + getDefaultDataSourceId: typeof getDefaultDataSourceId; + getDefaultDataSourceId$: typeof getDefaultDataSourceId$; } export interface DataSourceManagementPluginStart { @@ -123,6 +127,8 @@ export class DataSourceManagementPlugin DataSourceSelector: createDataSourceSelector(uiSettings, dataSource), getDataSourceMenu: () => createDataSourceMenu(), }, + getDefaultDataSourceId, + getDefaultDataSourceId$, }; }