diff --git a/src/plugins/data/public/data_sources/datasource/datasource.ts b/src/plugins/data/public/data_sources/datasource/datasource.ts index 5899abce8f17..dda3f02255f4 100644 --- a/src/plugins/data/public/data_sources/datasource/datasource.ts +++ b/src/plugins/data/public/data_sources/datasource/datasource.ts @@ -36,7 +36,7 @@ export abstract class DataSource< return this.type; } - getMetadata(): DataSourceMetaData { + getMetadata() { return this.metadata; } 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 4b0487f3194e..bd424211325e 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 @@ -41,7 +41,7 @@ describe('DataSourceSelectable', () => { selectedSources={selectedSourcesMock} onDataSourceSelect={setSelectedSourcesMock} setDataSourceOptionList={setDataSourceOptionListMock} - onFetchDataSetError={onFetchDataSetErrorMock} + onGetDataSetError={onFetchDataSetErrorMock} /> ); }); @@ -55,7 +55,7 @@ describe('DataSourceSelectable', () => { selectedSources={selectedSourcesMock} onDataSourceSelect={setSelectedSourcesMock} setDataSourceOptionList={setDataSourceOptionListMock} - onFetchDataSetError={onFetchDataSetErrorMock} + onGetDataSetError={onFetchDataSetErrorMock} /> ); }); @@ -74,7 +74,7 @@ describe('DataSourceSelectable', () => { selectedSources={selectedSourcesMock} onDataSourceSelect={setSelectedSourcesMock} setDataSourceOptionList={setDataSourceOptionListMock} - onFetchDataSetError={onFetchDataSetErrorMock} + onGetDataSetError={onFetchDataSetErrorMock} /> ); }); 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 5b7fb8bf323c..3e56dc384dca 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 @@ -21,13 +21,8 @@ const DATASOURCE_TYPE_DISPLAY_NAME_MAP: Record = { type DataSetType = ISourceDataSet['data_sets'][number]; -interface DataSetWithSource { - ds: GenericDataSource; - data_sets: DataSetType[]; -} - -// Fetches data sets for a given datasource and returns it along with the source. -const fetchDataSetWithSource = async (ds: GenericDataSource): Promise => { +// Get data sets for a given datasource and returns it along with the source. +const getDataSetWithSource = async (ds: GenericDataSource): Promise => { const dataSet = await ds.getDataSet(); return { ds, @@ -35,9 +30,9 @@ const fetchDataSetWithSource = async (ds: GenericDataSource): Promise - dataSources.map((ds) => fetchDataSetWithSource(ds)); +// Map through all data sources and get their respective data sets. +const getDataSets = (dataSources: GenericDataSource[]) => + dataSources.map((ds) => getDataSetWithSource(ds)); const isIndexPatterns = (dataSet: DataSetType): dataSet is IndexPatternOption => { if (typeof dataSet === 'string') return false; @@ -67,7 +62,7 @@ const getSourceOptions = (dataSource: DataSourceType, dataSet: DataSetType) => { }; }; -// Convert fetched data sets into a structured format suitable for selector rendering. +// Convert data sets into a structured format suitable for selector rendering. const getSourceList = (allDataSets: ISourceDataSet[]) => { const finalList = [] as DataSourceGroup[]; allDataSets.forEach((curDataSet) => { @@ -100,17 +95,17 @@ export const DataSourceSelectable = ({ selectedSources, // current selected datasource in the form of [{ label: xxx, value: xxx }] onDataSourceSelect, setDataSourceOptionList, - onFetchDataSetError, // onFetchDataSetError, Callback for handling data set fetch errors. Ensure it's memoized. + onGetDataSetError, // onGetDataSetError, Callback for handling data set get errors. Ensure it's memoized. singleSelection = true, }: DataSourceSelectableProps) => { - // This effect fetches data sets and prepares the datasource list for UI rendering. + // This effect gets data sets and prepares the datasource list for UI rendering. useEffect(() => { - Promise.all(fetchDataSets(dataSources)) + Promise.all(getDataSets(dataSources)) .then((results) => { setDataSourceOptionList(getSourceList(results)); }) - .catch((e) => onFetchDataSetError(e)); - }, [dataSources, setDataSourceOptionList, onFetchDataSetError]); + .catch((e) => onGetDataSetError(e)); + }, [dataSources, setDataSourceOptionList, onGetDataSetError]); const handleSourceChange = (selectedOptions: any) => onDataSourceSelect(selectedOptions); diff --git a/src/plugins/data/public/data_sources/datasource_selector/types.ts b/src/plugins/data/public/data_sources/datasource_selector/types.ts index 274c8cfd83b9..2d644a551759 100644 --- a/src/plugins/data/public/data_sources/datasource_selector/types.ts +++ b/src/plugins/data/public/data_sources/datasource_selector/types.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiComboBoxOptionOption, EuiComboBoxSingleSelectionShape } from '@elastic/eui'; +import { EuiComboBoxSingleSelectionShape } from '@elastic/eui'; import { GenericDataSource } from '../datasource_services'; export interface DataSourceGroup { @@ -18,13 +18,11 @@ export interface DataSourceOption { ds: GenericDataSource; } -export type DataSourceOptionType = EuiComboBoxOptionOption; - export interface DataSourceSelectableProps { dataSources: GenericDataSource[]; onDataSourceSelect: (dataSourceOption: DataSourceOption[]) => void; singleSelection?: boolean | EuiComboBoxSingleSelectionShape; - onFetchDataSetError: (error: Error) => void; + onGetDataSetError: (error: Error) => void; dataSourceOptionList: DataSourceGroup[]; selectedSources: DataSourceOption[]; setDataSourceOptionList: (dataSourceList: DataSourceGroup[]) => void; diff --git a/src/plugins/data/public/data_sources/datasource_services/datasource_service.test.ts b/src/plugins/data/public/data_sources/datasource_services/datasource_service.test.ts index bff315d84ba7..2c8f393d7093 100644 --- a/src/plugins/data/public/data_sources/datasource_services/datasource_service.test.ts +++ b/src/plugins/data/public/data_sources/datasource_services/datasource_service.test.ts @@ -100,8 +100,8 @@ describe('DataSourceService', () => { const ds1 = new MockDataSource(mockConfig1); const ds2 = new MockDataSource(mockConfig2); service.registerMultipleDataSources([ds1, ds2]); - const filters = { names: ['test_datasource1'] }; - const retrievedDataSources = service.getDataSources(filters); + const filter = { names: ['test_datasource1'] }; + const retrievedDataSources = service.getDataSources(filter); expect(retrievedDataSources).toHaveProperty('test_datasource1'); expect(retrievedDataSources).not.toHaveProperty('test_datasource2'); }); diff --git a/src/plugins/data/public/data_sources/datasource_services/datasource_service.ts b/src/plugins/data/public/data_sources/datasource_services/datasource_service.ts index 3b0efcb4d660..ea7964cb8ec8 100644 --- a/src/plugins/data/public/data_sources/datasource_services/datasource_service.ts +++ b/src/plugins/data/public/data_sources/datasource_services/datasource_service.ts @@ -5,20 +5,20 @@ import { BehaviorSubject } from 'rxjs'; import { - IDataSourceFilters, - IDataSourceRegisterationResult, - DataSourceRegisterationError, + DataSourceRegistrationError, GenericDataSource, + IDataSourceFilter, + IDataSourceRegistrationResult, } from './types'; export class DataSourceService { private static dataSourceService: DataSourceService; // A record to store all registered data sources, using the data source name as the key. private dataSources: Record = {}; - private _dataSourcesSubject: BehaviorSubject>; + private dataSourcesSubject: BehaviorSubject>; private constructor() { - this._dataSourcesSubject = new BehaviorSubject(this.dataSources); + this.dataSourcesSubject = new BehaviorSubject(this.dataSources); } static getInstance(): DataSourceService { @@ -36,7 +36,7 @@ export class DataSourceService { */ async registerMultipleDataSources( datasources: GenericDataSource[] - ): Promise { + ): Promise { return Promise.all(datasources.map((ds) => this.registerDataSource(ds))); } @@ -46,46 +46,41 @@ export class DataSourceService { * * @param ds - The data source to be registered. * @returns A registration result indicating success or failure. - * @throws {DataSourceRegisterationError} Throws an error if a data source with the same name already exists. + * @throws {DataSourceRegistrationError} Throws an error if a data source with the same name already exists. */ - async registerDataSource(ds: GenericDataSource): Promise { + async registerDataSource(ds: GenericDataSource): Promise { const dsName = ds.getName(); if (dsName in this.dataSources) { - throw new DataSourceRegisterationError( + throw new DataSourceRegistrationError( `Unable to register datasource ${dsName}, error: datasource name exists.` ); } else { - this.dataSources = { - ...this.dataSources, - [dsName]: ds, - }; - this._dataSourcesSubject.next(this.dataSources); - return { success: true, info: '' } as IDataSourceRegisterationResult; + this.dataSources[dsName] = ds; + this.dataSourcesSubject.next(this.dataSources); + return { success: true, info: '' } as IDataSourceRegistrationResult; } } public get dataSources$() { - return this._dataSourcesSubject.asObservable(); + return this.dataSourcesSubject.asObservable(); } /** * Retrieve the registered data sources based on provided filters. * If no filters are provided, all registered data sources are returned. * - * @param filters - An optional object with filter criteria (e.g., names of data sources). + * @param filter - An optional object with filter criteria (e.g., names of data sources). * @returns A record of filtered data sources. */ - getDataSources(filters?: IDataSourceFilters): Record { - if (!Array.isArray(filters?.names) || filters.names.length === 0) return this.dataSources; + getDataSources(filter?: IDataSourceFilter): Record { + if (!filter || !Array.isArray(filter.names) || filter.names.length === 0) + return this.dataSources; - return filters.names.reduce>( - (filteredDataSources, dsName) => { - if (dsName in this.dataSources) { - filteredDataSources[dsName] = this.dataSources[dsName]; - } - return filteredDataSources; - }, - {} as Record - ); + return filter.names.reduce>((filteredDataSources, dsName) => { + if (dsName in this.dataSources) { + filteredDataSources[dsName] = this.dataSources[dsName]; + } + return filteredDataSources; + }, {} as Record); } } diff --git a/src/plugins/data/public/data_sources/datasource_services/index.ts b/src/plugins/data/public/data_sources/datasource_services/index.ts index eb9f40c9e2a7..14db278b47a5 100644 --- a/src/plugins/data/public/data_sources/datasource_services/index.ts +++ b/src/plugins/data/public/data_sources/datasource_services/index.ts @@ -5,9 +5,9 @@ export { DataSourceService } from './datasource_service'; export { - IDataSourceFilters, - IDataSourceRegisterationResult, - DataSourceRegisterationError, + IDataSourceFilter, + IDataSourceRegistrationResult, + DataSourceRegistrationError, DataSourceType, GenericDataSource, } from './types'; diff --git a/src/plugins/data/public/data_sources/datasource_services/types.ts b/src/plugins/data/public/data_sources/datasource_services/types.ts index 845329b61a61..022e9b9f178b 100644 --- a/src/plugins/data/public/data_sources/datasource_services/types.ts +++ b/src/plugins/data/public/data_sources/datasource_services/types.ts @@ -14,16 +14,16 @@ import { } from '../datasource'; import { DataSourceService } from './datasource_service'; -export interface IDataSourceFilters { +export interface IDataSourceFilter { names: string[]; } -export interface IDataSourceRegisterationResult { +export interface IDataSourceRegistrationResult { success: boolean; info: string; } -export class DataSourceRegisterationError extends Error { +export class DataSourceRegistrationError extends Error { success: boolean; info: string; constructor(message: string) { diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 16cebbcc78ec..3b559f9e6c63 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -510,11 +510,11 @@ export { DataSourceConfig, } from './data_sources/datasource'; export { - DataSourceRegisterationError, + DataSourceRegistrationError, DataSourceService, DataSourceType, - IDataSourceFilters, - IDataSourceRegisterationResult, + IDataSourceFilter, + IDataSourceRegistrationResult, } from './data_sources/datasource_services'; export { DataSourceSelectable, diff --git a/src/plugins/data_explorer/public/components/sidebar/index.tsx b/src/plugins/data_explorer/public/components/sidebar/index.tsx index 154040b31780..fa3235a08b6a 100644 --- a/src/plugins/data_explorer/public/components/sidebar/index.tsx +++ b/src/plugins/data_explorer/public/components/sidebar/index.tsx @@ -3,13 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { FC, useEffect, useState, useCallback } from 'react'; -import { EuiSplitPanel, EuiPageSideBar } from '@elastic/eui'; -import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; -import { DataExplorerServices } from '../../types'; -import { useTypedDispatch, useTypedSelector, setIndexPattern } from '../../utils/state_management'; +import { EuiPageSideBar, EuiSplitPanel } from '@elastic/eui'; +import { i18n } from '@osd/i18n'; +import React, { FC, useCallback, useEffect, useState } from 'react'; import { DataSourceGroup, DataSourceSelectable, DataSourceType } from '../../../../data/public'; import { DataSourceOption } from '../../../../data/public/'; +import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; +import { DataExplorerServices } from '../../types'; +import { setIndexPattern, useTypedDispatch, useTypedSelector } from '../../utils/state_management'; export const Sidebar: FC = ({ children }) => { const { indexPattern: indexPatternId } = useTypedSelector((state) => state.metadata); @@ -73,9 +74,14 @@ export const Sidebar: FC = ({ children }) => { dispatch(setIndexPattern(selectedDataSources[0].value)); }; - const handleDataSetFetchError = useCallback( + const handleGetDataSetError = useCallback( () => (error: Error) => { - toasts.addError(error, { title: `Data set fetching error: ${error}` }); + toasts.addError(error, { + title: + i18n.translate('dataExplorer.sidebar.failedToGetDataSetErrorDescription', { + defaultMessage: 'Failed to get data set: ', + }) + (error.message || error.name), + }); }, [toasts] ); @@ -90,7 +96,7 @@ export const Sidebar: FC = ({ children }) => { setDataSourceOptionList={setDataSourceOptionList} onDataSourceSelect={handleSourceSelection} selectedSources={selectedSources} - onFetchDataSetError={handleDataSetFetchError} + onGetDataSetError={handleGetDataSetError} />