diff --git a/config/opensearch_dashboards.yml b/config/opensearch_dashboards.yml index 40d643b014fd..853a785d26ce 100644 --- a/config/opensearch_dashboards.yml +++ b/config/opensearch_dashboards.yml @@ -247,7 +247,7 @@ # vis_builder.enabled: false # Set the value of this setting to true to enable multiple data source feature. -#data_source.enabled: false +data_source.enabled: true # Set the value of this setting to true to hide local cluster in data source feature. #data_source.hideLocalCluster: false # Set the value of these settings to customize crypto materials to encryption saved credentials diff --git a/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx b/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx index 2e76c2cf23c6..484f3e6630d8 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx +++ b/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx @@ -5,17 +5,18 @@ import React from 'react'; import { EuiHeaderLinks } from '@elastic/eui'; +import { IUiSettingsClient } from 'src/core/public'; import { DataSourceMenu } from './data_source_menu'; import { DataSourceMenuProps } from './types'; import { MountPointPortal } from '../../../../opensearch_dashboards_react/public'; -export function createDataSourceMenu() { +export function createDataSourceMenu(uiSettings: IUiSettingsClient) { return (props: DataSourceMenuProps) => { if (props.setMenuMountPoint) { return ( - + ); diff --git a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx index b56063e5d25f..93ac78b1ab5d 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx +++ b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx @@ -5,6 +5,7 @@ import React, { ReactElement } from 'react'; +import { IUiSettingsClient } from 'src/core/public'; import { DataSourceAggregatedView } from '../data_source_aggregated_view'; import { DataSourceView } from '../data_source_view'; import { DataSourceMultiSelectable } from '../data_source_multi_selectable'; @@ -19,7 +20,7 @@ import { import { DataSourceSelectable } from '../data_source_selectable'; export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null { - const { componentType, componentConfig } = props; + const { componentType, componentConfig, uiSettings } = props; function renderDataSourceView(config: DataSourceViewConfig): ReactElement | null { const { activeOption, fullWidth, savedObjects, notifications } = config; @@ -54,7 +55,10 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | ); } - function renderDataSourceSelectable(config: DataSourceSelectableConfig): ReactElement | null { + function renderDataSourceSelectable( + config: DataSourceSelectableConfig, + ui: IUiSettingsClient + ): ReactElement | null { const { onSelectedDataSources, disabled, @@ -75,6 +79,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | dataSourceFilter={dataSourceFilter} hideLocalCluster={hideLocalCluster || false} fullWidth={fullWidth} + uiSettings={ui} /> ); } @@ -109,7 +114,10 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | case DataSourceComponentType.DataSourceAggregatedView: return renderDataSourceAggregatedView(componentConfig as DataSourceAggregatedViewConfig); case DataSourceComponentType.DataSourceSelectable: - return renderDataSourceSelectable(componentConfig as DataSourceSelectableConfig); + return renderDataSourceSelectable( + componentConfig as DataSourceSelectableConfig, + uiSettings + ); case DataSourceComponentType.DataSourceView: return renderDataSourceView(componentConfig as DataSourceViewConfig); case DataSourceComponentType.DataSourceMultiSelectable: 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 4121edc0c863..51967a323b7c 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 @@ -7,6 +7,7 @@ import { NotificationsStart, SavedObjectsClientContract, SavedObject, + IUiSettingsClient, } from '../../../../../core/public'; import { DataSourceAttributes } from '../../types'; @@ -23,6 +24,7 @@ export interface DataSourceBaseConfig { export interface DataSourceMenuProps { componentType: DataSourceComponentType; componentConfig: T; + uiSettings?: IUiSettingsClient; setMenuMountPoint?: (menuMount: MountPoint | undefined) => void; } @@ -57,6 +59,7 @@ export interface DataSourceSelectableConfig extends DataSourceBaseConfig { activeOption?: DataSourceOption[]; hideLocalCluster?: boolean; dataSourceFilter?: (dataSource: SavedObject) => boolean; + uiSettings?: IUiSettingsClient; } export interface DataSourceMultiSelectableConfig extends DataSourceBaseConfig { 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 e0fccf9aa226..9ade8a684882 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 @@ -12,9 +12,16 @@ import { EuiButtonEmpty, EuiSelectable, EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiBadge, } from '@elastic/eui'; -import { SavedObjectsClientContract, ToastsStart } from 'opensearch-dashboards/public'; -import { getDataSourcesWithFields } from '../utils'; +import { + IUiSettingsClient, + SavedObjectsClientContract, + ToastsStart, +} from 'opensearch-dashboards/public'; +import { getDataSourcesWithFields, getDefaultDataSource } from '../utils'; import { LocalCluster } from '../data_source_selector/data_source_selector'; import { SavedObject } from '../../../../../core/public'; import { DataSourceAttributes } from '../../types'; @@ -29,6 +36,7 @@ interface DataSourceSelectableProps { fullWidth: boolean; selectedOption?: DataSourceOption[]; dataSourceFilter?: (dataSource: SavedObject) => boolean; + uiSettings?: IUiSettingsClient; } interface DataSourceSelectableState { @@ -106,6 +114,23 @@ export class DataSourceSelectable extends React.Component< ...this.state, dataSourceOptions, }); + + const selectedDataSource = getDefaultDataSource( + filteredDataSources, + LocalCluster, + this.props.uiSettings, + this.props.hideLocalCluster, + this.props.selectedOption + ); + if (selectedDataSource.length === 0) { + this.props.notifications.addWarning('No connected data source available.'); + } else { + this.setState({ + ...this.state, + selectedOption: selectedDataSource, + }); + this.props.onSelectedDataSource(selectedDataSource); + } } }) .catch(() => { @@ -157,6 +182,7 @@ export class DataSourceSelectable extends React.Component< ); + const defaultDataSource = this.props.uiSettings?.get('defaultDataSource', null) ?? null; return ( this.onChange(newOptions)} singleSelection={true} data-test-subj={'dataSourceSelectable'} + renderOption={(option) => ( + + {option.label} + {option.id === defaultDataSource && ( + + Default + + )} + + )} > {(list, search) => ( <> diff --git a/src/plugins/data_source_management/public/components/utils.ts b/src/plugins/data_source_management/public/components/utils.ts index b911203cd288..71e934a6777b 100644 --- a/src/plugins/data_source_management/public/components/utils.ts +++ b/src/plugins/data_source_management/public/components/utils.ts @@ -16,6 +16,7 @@ import { noAuthCredentialAuthMethod, } from '../types'; import { AuthenticationMethodRegistry } from '../auth_registry'; +import { DataSourceOption } from './data_source_menu/types'; export async function getDataSources(savedObjectsClient: SavedObjectsClientContract) { return savedObjectsClient @@ -54,6 +55,44 @@ export async function getDataSourcesWithFields( return response?.savedObjects; } +export function getDefaultDataSource( + dataSources: Array>, + LocalCluster: DataSourceOption, + uiSettings?: IUiSettingsClient, + hideLocalCluster?: boolean, + defaultOption?: DataSourceOption[] +) { + const defaultOptionId = defaultOption?.[0]?.id; + const defaultOptionDataSource = dataSources.find( + (dataSource) => dataSource.id === defaultOptionId + ); + + const defaultDataSourceId = uiSettings?.get('defaultDataSource', null) ?? null; + const defaultDataSourceAfterCheck = dataSources.find( + (dataSource) => dataSource.id === defaultDataSourceId + ); + + if (defaultOptionDataSource) { + return [ + { + id: defaultOptionDataSource.id, + label: defaultOption?.[0]?.label || defaultOptionDataSource.attributes?.title, + }, + ]; + } else if (defaultDataSourceAfterCheck) { + return [ + { + id: defaultDataSourceAfterCheck.id, + label: defaultDataSourceAfterCheck.attributes?.title || '', + }, + ]; + } else if (!hideLocalCluster) { + return [LocalCluster]; + } else { + return []; + } +} + export async function handleSetDefaultDatasource( savedObjectsClient: SavedObjectsClientContract, uiSettings: IUiSettingsClient diff --git a/src/plugins/data_source_management/public/plugin.ts b/src/plugins/data_source_management/public/plugin.ts index 9e6da39dc08b..e65599214601 100644 --- a/src/plugins/data_source_management/public/plugin.ts +++ b/src/plugins/data_source_management/public/plugin.ts @@ -57,6 +57,7 @@ export class DataSourceManagementPlugin { management, indexPatternManagement, dataSource }: DataSourceManagementSetupDependencies ) { const opensearchDashboardsSection = management.sections.section.opensearchDashboards; + const uiSettings = core.uiSettings; if (!opensearchDashboardsSection) { throw new Error('`opensearchDashboards` management section not found.'); @@ -103,7 +104,7 @@ export class DataSourceManagementPlugin registerAuthenticationMethod, ui: { DataSourceSelector: createDataSourceSelector(), - getDataSourceMenu: () => createDataSourceMenu(), + getDataSourceMenu: () => createDataSourceMenu(uiSettings), }, }; }