From 7d4432f6a7b6b616c666b212c8a44ad595e35deb Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Wed, 19 Jun 2024 08:17:41 +0000 Subject: [PATCH 1/4] [Discover-Next] conditionally render selector When selecting a specific language, the data source selector disappears and relies completely on the query editor when enhancements are enabled. If toggled on and then off, everything is working properly. https://github.com/opensearch-project/OpenSearch-Dashboards/issues/7046 Signed-off-by: Kawika Avilla --- package.json | 1 + src/plugins/data/common/data_frames/types.ts | 2 +- .../search/search_source/search_source.ts | 2 +- .../data_selector_refresher.tsx | 4 +- .../datasource_selectable.tsx | 1 + .../ui/query_editor/_language_selector.scss | 10 +--- .../public/ui/query_editor/_query_editor.scss | 22 ++++++++ .../ui/query_editor/language_selector.tsx | 1 + .../public/ui/query_editor/query_editor.tsx | 52 +++++++++++-------- .../ui/query_editor/query_editor_top_row.tsx | 1 + src/plugins/data/public/ui/types.ts | 1 + 11 files changed, 64 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 4a67ad60240..a7cc2c83123 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,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: [], @@ -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 && ( + +
+ + )} @@ -302,6 +311,7 @@ export default class QueryEditorUI extends Component { scrollBeyondLastLine: false, wordWrap: 'on', wrappingIndent: 'indent', + selectionHighlight: false, }} /> 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; From ff45bbcc5dde10aa5e0a850ab760d328f1256941 Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 08:24:23 +0000 Subject: [PATCH 2/4] Changeset file for PR #7059 created/updated --- changelogs/fragments/7059.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/7059.yml 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 From 830ba39e66bc0762a6a1c926b5eba5e8b0fca9a0 Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Wed, 19 Jun 2024 08:55:42 +0000 Subject: [PATCH 3/4] fix ui setting retrieval Signed-off-by: Kawika Avilla --- src/plugins/data/public/ui/query_editor/query_editor.tsx | 3 +-- .../search/opensearch_search/get_default_search_params.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/data/public/ui/query_editor/query_editor.tsx b/src/plugins/data/public/ui/query_editor/query_editor.tsx index 5267066a1be..2433794645b 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor.tsx @@ -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; @@ -311,7 +311,6 @@ export default class QueryEditorUI extends Component { scrollBeyondLastLine: false, wordWrap: 'on', wrappingIndent: 'indent', - selectionHighlight: false, }} /> 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: From 90a96ac60ea0a03a3552073519116c21f572e6fb Mon Sep 17 00:00:00 2001 From: Kawika Avilla Date: Thu, 20 Jun 2024 09:54:12 +0000 Subject: [PATCH 4/4] add get default search params test Signed-off-by: Kawika Avilla --- .../get_default_search_params.test.ts | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/plugins/data/server/search/opensearch_search/get_default_search_params.test.ts 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', + }); + }); + }); +});