diff --git a/changelogs/fragments/7059.yml b/changelogs/fragments/7059.yml new file mode 100644 index 00000000000..5ecfa206571 --- /dev/null +++ b/changelogs/fragments/7059.yml @@ -0,0 +1,2 @@ +feat: +- Render the datasource selector component conditionally ([#7059](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7059)) \ No newline at end of file diff --git a/package.json b/package.json index af20207d7e1..fd988236edf 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "start": "scripts/use_node scripts/opensearch_dashboards --dev", "start:docker": "scripts/use_node scripts/opensearch_dashboards --dev --opensearch.hosts=$OPENSEARCH_HOSTS --opensearch.ignoreVersionMismatch=true --server.host=$SERVER_HOST", "start:security": "scripts/use_node scripts/opensearch_dashboards --dev --security", + "start:enhancements": "scripts/use_node scripts/opensearch_dashboards --dev --data.enhancements.enabled=true --uiSettings.overrides['query:enhancements:enabled']=true --uiSettings.overrides['query:dataSource:readOnly']=false", "debug": "scripts/use_node --nolazy --inspect scripts/opensearch_dashboards --dev", "debug-break": "scripts/use_node --nolazy --inspect-brk scripts/opensearch_dashboards --dev", "lint": "yarn run lint:es && yarn run lint:style", diff --git a/src/plugins/data/common/data_frames/types.ts b/src/plugins/data/common/data_frames/types.ts index f8dd04193cf..49633c7ec2c 100644 --- a/src/plugins/data/common/data_frames/types.ts +++ b/src/plugins/data/common/data_frames/types.ts @@ -98,6 +98,6 @@ export interface IDataFrameResponse extends SearchResponse { took: number; } -export interface IDataFrameError { +export interface IDataFrameError extends IDataFrameResponse { error: Error; } diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index b7dc48b404b..744362621ec 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -123,7 +123,7 @@ export const searchSourceRequiredUiSettings = [ UI_SETTINGS.QUERY_STRING_OPTIONS, UI_SETTINGS.SEARCH_INCLUDE_FROZEN, UI_SETTINGS.SORT_OPTIONS, - UI_SETTINGS.DATAFRAME_HYDRATION_STRATEGY, + UI_SETTINGS.QUERY_DATAFRAME_HYDRATION_STRATEGY, ]; export interface SearchSourceDependencies extends FetchHandlers { diff --git a/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx b/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx index 4aabecd3bd6..1cc5acd6f9d 100644 --- a/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx +++ b/src/plugins/data/public/data_sources/datasource_selector/data_selector_refresher.tsx @@ -23,7 +23,7 @@ interface IDataSelectorRefresherProps { export const DataSelectorRefresher: React.FC = React.memo( ({ tooltipText, onRefresh, buttonProps, toolTipProps }) => { return ( - + = Reac {...toolTipProps} > 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 d9cdccc948d..4825c474aaa 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 @@ -162,6 +162,7 @@ export const DataSourceSelectable = ({ return ( :first-child { diff --git a/src/plugins/data/public/ui/query_editor/language_selector.tsx b/src/plugins/data/public/ui/query_editor/language_selector.tsx index 98399e81340..7ea82fe2b24 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.tsx @@ -74,6 +74,7 @@ export const QueryLanguageSelector = (props: Props) => { return ( ; + isDataSourcesVisible: boolean; isSuggestionsVisible: boolean; index: number | null; suggestions: QuerySuggestion[]; @@ -77,7 +77,7 @@ const KEY_CODES = { // eslint-disable-next-line import/no-default-export export default class QueryEditorUI extends Component { public state: State = { - queryEnhancements: new Map(), + isDataSourcesVisible: true, isSuggestionsVisible: false, index: null, suggestions: [], @@ -85,7 +85,7 @@ export default class QueryEditorUI extends Component { queryEditorRect: undefined, }; - public inputRef: HTMLTextAreaElement | null = null; + public inputRef: HTMLElement | null = null; private persistedLog: PersistedLog | undefined; private abortController?: AbortController; @@ -169,7 +169,8 @@ export default class QueryEditorUI extends Component { language, }; - const fields = this.props.settings.getQueryEnhancements(newQuery.language)?.fields; + const enhancement = this.props.settings.getQueryEnhancements(newQuery.language); + const fields = enhancement?.fields; const newSettings: DataSettings = { userQueryLanguage: newQuery.language, userQueryString: newQuery.query, @@ -177,8 +178,7 @@ export default class QueryEditorUI extends Component { }; this.props.settings?.updateSettings(newSettings); - const dateRangeEnhancement = this.props.settings.getQueryEnhancements(language)?.searchBar - ?.dateRange; + const dateRangeEnhancement = enhancement?.searchBar?.dateRange; const dateRange = dateRangeEnhancement ? { from: dateRangeEnhancement.initialFrom!, @@ -187,6 +187,7 @@ export default class QueryEditorUI extends Component { : undefined; this.onChange(newQuery, dateRange); this.onSubmit(newQuery, dateRange); + this.setState({ isDataSourcesVisible: enhancement?.searchBar?.showDataSourceSelector ?? true }); }; private initPersistedLog = () => { @@ -196,6 +197,15 @@ export default class QueryEditorUI extends Component { : getQueryLog(uiSettings, storage, appName, this.props.query.language); }; + private initDataSourcesVisibility = () => { + if (this.componentIsUnmounting) return; + + const isDataSourcesVisible = + this.props.settings.getQueryEnhancements(this.props.query.language)?.searchBar + ?.showDataSourceSelector ?? true; + this.setState({ isDataSourcesVisible }); + }; + public onMouseEnterSuggestion = (index: number) => { this.setState({ index }); }; @@ -210,6 +220,7 @@ export default class QueryEditorUI extends Component { this.initPersistedLog(); // this.fetchIndexPatterns().then(this.updateSuggestions); + this.initDataSourcesVisibility(); this.handleListUpdate(); window.addEventListener('scroll', this.handleListUpdate, { @@ -265,23 +276,21 @@ export default class QueryEditorUI extends Component {
- + {this.props.prepend} - - - -
- - - - - + + + {this.state.isDataSourcesVisible && ( + +
+ + )} diff --git a/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx b/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx index 713bd3345e9..a41e57eaa93 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor_top_row.tsx @@ -245,6 +245,7 @@ export default function QueryEditorTopRow(props: QueryEditorTopRowProps) { onSubmit={onInputSubmit} getQueryStringInitialValue={getQueryStringInitialValue} persistedLog={persistedLog} + className="osdQueryEditor" dataTestSubj={props.dataTestSubj} queryEditorHeaderRef={queryEditorHeaderRef} queryEditorBannerRef={queryEditorBannerRef} diff --git a/src/plugins/data/public/ui/types.ts b/src/plugins/data/public/ui/types.ts index bd157b7dd62..e273019c390 100644 --- a/src/plugins/data/public/ui/types.ts +++ b/src/plugins/data/public/ui/types.ts @@ -21,6 +21,7 @@ export interface QueryEnhancement { // Leave blank to support all data sources // supportedDataSourceTypes?: Record; searchBar?: { + showDataSourceSelector?: boolean; showQueryInput?: boolean; showFilterBar?: boolean; showDatePicker?: boolean; diff --git a/src/plugins/data/server/search/opensearch_search/get_default_search_params.test.ts b/src/plugins/data/server/search/opensearch_search/get_default_search_params.test.ts new file mode 100644 index 00000000000..4002461387d --- /dev/null +++ b/src/plugins/data/server/search/opensearch_search/get_default_search_params.test.ts @@ -0,0 +1,90 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { getDefaultSearchParams, getAsyncOptions } from './get_default_search_params'; +import { UI_SETTINGS } from '../../../common/constants'; +import { IUiSettingsClient } from 'src/core/server'; + +import { coreMock } from '../../../../../../src/core/server/mocks'; + +describe('getDefaultSearchParams', () => { + let uiSettings: IUiSettingsClient; + + beforeEach(async () => { + const coreContext = coreMock.createRequestHandlerContext(); + uiSettings = coreContext.uiSettings.client; + }); + + describe('getDefaultSearchParams', () => { + describe('maxConcurrentShardRequests', () => { + it('returns as undefined if less than 0', async () => { + uiSettings.get = jest.fn().mockReturnValue(-1); + const result = await getDefaultSearchParams(uiSettings); + expect(result.maxConcurrentShardRequests).toBeUndefined(); + }); + + it('returns as value if greater than 0', async () => { + uiSettings.get = jest.fn().mockReturnValue(5); + const result = await getDefaultSearchParams(uiSettings); + expect(result.maxConcurrentShardRequests).toBe(5); + }); + }); + + describe('ignoreThrottled', () => { + it('returns as true if false', async () => { + uiSettings.get = jest.fn().mockReturnValue(false); + const result = await getDefaultSearchParams(uiSettings); + expect(result.ignoreThrottled).toBe(true); + }); + + it('returns as false if true', async () => { + uiSettings.get = jest.fn().mockReturnValue(true); + const result = await getDefaultSearchParams(uiSettings); + expect(result.ignoreThrottled).toBe(false); + }); + }); + + describe('dataFrameHydrationStrategy', () => { + it('returns correct value', async () => { + uiSettings.get = jest.fn().mockReturnValue('strategy'); + const result = await getDefaultSearchParams(uiSettings); + expect(result.dataFrameHydrationStrategy).toBe('strategy'); + }); + }); + + it('returns correct search params', async () => { + uiSettings.get = jest.fn().mockImplementation((setting: string) => { + switch (setting) { + case UI_SETTINGS.SEARCH_INCLUDE_FROZEN: + return false; + case UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS: + return 5; + case UI_SETTINGS.QUERY_DATAFRAME_HYDRATION_STRATEGY: + return 'strategy'; + default: + return undefined; + } + }); + + const result = await getDefaultSearchParams(uiSettings); + expect(result).toEqual({ + maxConcurrentShardRequests: 5, + ignoreThrottled: true, + dataFrameHydrationStrategy: 'strategy', + ignoreUnavailable: true, + trackTotalHits: true, + }); + }); + }); + + describe('getAsyncOptions', () => { + it('returns correct async options', () => { + expect(getAsyncOptions()).toEqual({ + waitForCompletionTimeout: '100ms', + keepAlive: '1m', + }); + }); + }); +}); diff --git a/src/plugins/data/server/search/opensearch_search/get_default_search_params.ts b/src/plugins/data/server/search/opensearch_search/get_default_search_params.ts index 172acf9f0e2..f280589a569 100644 --- a/src/plugins/data/server/search/opensearch_search/get_default_search_params.ts +++ b/src/plugins/data/server/search/opensearch_search/get_default_search_params.ts @@ -46,7 +46,7 @@ export async function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS ); const dataFrameHydrationStrategy = await uiSettingsClient.get( - UI_SETTINGS.DATAFRAME_HYDRATION_STRATEGY + UI_SETTINGS.QUERY_DATAFRAME_HYDRATION_STRATEGY ); return { maxConcurrentShardRequests: