From cc9a00d42cacf6ed9a2942a0c3d3ca99e79839e0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 24 May 2023 13:52:04 +0300 Subject: [PATCH 01/14] Always create adhoc dataviews, add @timestamp info --- .../src/editor_footer.tsx | 30 ++++++++++++++++++- .../src/text_based_languages_editor.tsx | 4 +++ .../use_test_based_query_language.test.tsx | 10 ++----- .../hooks/use_text_based_query_language.ts | 30 ++++++++----------- .../query_string_input/query_bar_top_row.tsx | 6 ++++ .../datasources/text_based/utils.test.ts | 12 ++++++-- .../public/datasources/text_based/utils.ts | 15 ++++------ 7 files changed, 69 insertions(+), 38 deletions(-) diff --git a/packages/kbn-text-based-editor/src/editor_footer.tsx b/packages/kbn-text-based-editor/src/editor_footer.tsx index 9516979e9b55f..1075593bbd327 100644 --- a/packages/kbn-text-based-editor/src/editor_footer.tsx +++ b/packages/kbn-text-based-editor/src/editor_footer.tsx @@ -32,6 +32,7 @@ interface EditorFooterProps { lines: number; containerCSS: Interpolation; errors?: MonacoError[]; + filtersByDate: boolean; onErrorClick: (error: MonacoError) => void; refreshErrors: () => void; } @@ -40,6 +41,7 @@ export const EditorFooter = memo(function EditorFooter({ lines, containerCSS, errors, + filtersByDate, onErrorClick, refreshErrors, }: EditorFooterProps) { @@ -54,7 +56,7 @@ export const EditorFooter = memo(function EditorFooter({ > - +

{i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.lineCount', { @@ -64,6 +66,32 @@ export const EditorFooter = memo(function EditorFooter({

+ + + + + + + +

+ {filtersByDate + ? i18n.translate( + 'textBasedEditor.query.textBasedLanguagesEditor.timestampDetected', + { + defaultMessage: '@timestamp detected', + } + ) + : i18n.translate( + 'textBasedEditor.query.textBasedLanguagesEditor.timestampNotDetected', + { + defaultMessage: '@timestamp not detected', + } + )} +

+
+
+
+
{errors && errors.length > 0 && ( diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 9080f634736f5..83f79749070ea 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -55,6 +55,7 @@ export interface TextBasedLanguagesEditorProps { onTextLangQuerySubmit: () => void; expandCodeEditor: (status: boolean) => void; isCodeEditorExpanded: boolean; + filtersByDate?: boolean; errors?: Error[]; isDisabled?: boolean; isDarkMode?: boolean; @@ -87,6 +88,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ onTextLangQuerySubmit, expandCodeEditor, isCodeEditorExpanded, + filtersByDate = false, errors, isDisabled, isDarkMode, @@ -537,6 +539,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} onErrorClick={onErrorClick} refreshErrors={onTextLangQuerySubmit} + filtersByDate={filtersByDate} /> )} @@ -608,6 +611,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} onErrorClick={onErrorClick} refreshErrors={onTextLangQuerySubmit} + filtersByDate={filtersByDate} /> )} {isCodeEditorExpanded && ( diff --git a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx index edf69444ac5e3..525263e404a99 100644 --- a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx +++ b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx @@ -98,7 +98,7 @@ const renderHookWithContext = ( describe('useTextBasedQueryLanguage', () => { test('a text based query should change state when loading and finished', async () => { - const { replaceUrlState, stateContainer } = renderHookWithContext(false); + const { replaceUrlState, stateContainer } = renderHookWithContext(true); await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(1)); expect(replaceUrlState).toHaveBeenCalledWith({ index: 'the-data-view-id' }); @@ -191,11 +191,7 @@ describe('useTextBasedQueryLanguage', () => { query: { sql: 'SELECT field1 from the-data-view-title WHERE field1=1' }, }); - await waitFor(() => { - expect(replaceUrlState).toHaveBeenCalledWith({ - index: 'the-data-view-id', - }); - }); + await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(0)); }); test('if its not a text based query coming along, it should be ignored', async () => { const { replaceUrlState, stateContainer } = renderHookWithContext(false); @@ -270,7 +266,7 @@ describe('useTextBasedQueryLanguage', () => { ], query: { sql: 'SELECT field1 from the-data-view-title' }, }); - await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(1)); + await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(2)); expect(replaceUrlState).toHaveBeenCalledWith({ columns: ['field1'], }); diff --git a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts index b82b749d2acba..4b9806bf44251 100644 --- a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts +++ b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts @@ -37,6 +37,7 @@ export function useTextBasedQueryLanguage({ columns: [], query: undefined, }); + const indexTitle = useRef(''); const savedSearch = useSavedSearchInitial(); const cleanup = useCallback(() => { @@ -80,24 +81,14 @@ export function useTextBasedQueryLanguage({ } } const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); - const internalState = stateContainer.internalState.getState(); - const dataViewList = [...internalState.savedDataViews, ...internalState.adHocDataViews]; - let dataViewObj = dataViewList.find(({ title }) => title === indexPatternFromQuery); - // no dataview found but the index pattern is valid - // create an adhoc instance instead - if (!dataViewObj) { - dataViewObj = await dataViews.create({ - title: indexPatternFromQuery, - }); - stateContainer.internalState.transitions.setAdHocDataViews([dataViewObj]); + const dataViewObj = await dataViews.create({ + title: indexPatternFromQuery, + }); + stateContainer.internalState.transitions.setAdHocDataViews([dataViewObj]); - if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { - dataViewObj.timeFieldName = '@timestamp'; - } else if (dataViewObj.fields.getByType('date')?.length) { - const dateFields = dataViewObj.fields.getByType('date'); - dataViewObj.timeFieldName = dateFields[0].name; - } + if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { + dataViewObj.timeFieldName = '@timestamp'; } // don't set the columns on initial fetch, to prevent overwriting existing state @@ -106,10 +97,15 @@ export function useTextBasedQueryLanguage({ ); // no need to reset index to state if it hasn't changed const addDataViewToState = Boolean(dataViewObj.id !== index); - if (!addColumnsToState && !addDataViewToState) { + const queryChanged = indexPatternFromQuery !== indexTitle.current; + if (!addColumnsToState && !queryChanged) { return; } + if (queryChanged) { + indexTitle.current = indexPatternFromQuery; + } + const nextState = { ...(addDataViewToState && { index: dataViewObj.id }), ...(addColumnsToState && { columns: nextColumns }), diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 94a342d610399..1c7d06749b376 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -577,6 +577,11 @@ export const QueryBarTopRow = React.memo( } function renderTextLangEditor() { + const adHocDataview = props.indexPatterns?.[0]; + let filtersByDate = false; + if (adHocDataview && typeof adHocDataview !== 'string') { + filtersByDate = Boolean(adHocDataview?.timeFieldName); + } return ( isQueryLangSelected && props.query && @@ -587,6 +592,7 @@ export const QueryBarTopRow = React.memo( expandCodeEditor={(status: boolean) => setCodeEditorIsExpanded(status)} isCodeEditorExpanded={codeEditorIsExpanded} errors={props.textBasedLanguageModeErrors} + filtersByDate={filtersByDate} onTextLangQuerySubmit={() => onSubmit({ query: queryRef.current, diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts index 8db05279d593e..c15bf41b6fb8d 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts @@ -191,8 +191,9 @@ describe('Text based languages utils', () => { ), create: jest.fn().mockReturnValue( Promise.resolve({ - id: '1', - title: 'my-fake-index-pattern', + id: '4', + title: 'my-adhoc-index-pattern', + name: 'my-adhoc-index-pattern', timeFieldName: 'timeField', isPersisted: () => false, }) @@ -252,6 +253,11 @@ describe('Text based languages utils', () => { timeField: 'timeField', title: 'my-fake-restricted-pattern', }, + { + id: '4', + timeField: 'timeField', + title: 'my-adhoc-index-pattern', + }, ], layers: { first: { @@ -280,7 +286,7 @@ describe('Text based languages utils', () => { ], columns: [], errors: [], - index: '1', + index: '4', query: { sql: 'SELECT * FROM my-fake-index-pattern', }, diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.ts index a521b9f245a34..fc5de5eba3aa0 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.ts @@ -83,18 +83,13 @@ export async function getStateFromAggregateQuery( let allColumns: TextBasedLayerColumn[] = []; let timeFieldName; try { - const dataView = dataViewId - ? await dataViews.get(dataViewId) - : await dataViews.create({ - title: indexPattern, - }); - if (!dataViewId && !dataView.isPersisted()) { + const dataView = await dataViews.create({ + title: indexPattern, + }); + if (!dataView.isPersisted()) { if (dataView && dataView.id) { - if (dataView.fields.getByName('@timestamp')?.type === 'date') { + if (dataView?.fields?.getByName('@timestamp')?.type === 'date') { dataView.timeFieldName = '@timestamp'; - } else if (dataView.fields.getByType('date')?.length) { - const dateFields = dataView.fields.getByType('date'); - dataView.timeFieldName = dateFields[0].name; } dataViewId = dataView?.id; indexPatternRefs = [ From 03750166ade7cb4e0adc78f949a6d60d9ef0d62f Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 25 May 2023 09:15:02 +0300 Subject: [PATCH 02/14] Fix FT, no popular fields --- test/functional/apps/discover/group3/_sidebar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts index 0e0aa51db2c0a..8c681bf321ad6 100644 --- a/test/functional/apps/discover/group3/_sidebar.ts +++ b/test/functional/apps/discover/group3/_sidebar.ts @@ -404,7 +404,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.waitUntilSidebarHasLoaded(); expect(await PageObjects.discover.getSidebarAriaDescription()).to.be( - '1 popular field. 53 available fields. 0 empty fields. 3 meta fields.' + '53 available fields. 0 empty fields. 3 meta fields.' ); }); From 42e380f7c0b1a7e45c5566771d112e6c3f135f65 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 25 May 2023 14:00:23 +0300 Subject: [PATCH 03/14] Enable the datepicker for text based --- .../components/top_nav/discover_topnav.tsx | 8 +- .../compute_index_timerange.ts | 112 ++++++++++++++++++ .../query_string_input/query_bar_top_row.tsx | 11 +- 3 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx index 43ed023992330..9b1be0e261a73 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx @@ -48,10 +48,10 @@ export const DiscoverTopNav = ({ const dataView = useInternalStateSelector((state) => state.dataView!); const savedDataViews = useInternalStateSelector((state) => state.savedDataViews); const savedSearch = useSavedSearchInitial(); - const showDatePicker = useMemo( - () => dataView.isTimeBased() && dataView.type !== DataViewType.ROLLUP, - [dataView] - ); + const showDatePicker = useMemo(() => { + if (isPlainRecord) return true; + return dataView.isTimeBased() && dataView.type !== DataViewType.ROLLUP; + }, [dataView, isPlainRecord]); const services = useDiscoverServices(); const { dataViewEditor, navigation, dataViewFieldEditor, data, uiSettings, dataViews } = services; diff --git a/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts b/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts new file mode 100644 index 0000000000000..92898973294fa --- /dev/null +++ b/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { lastValueFrom } from 'rxjs'; +import type { DataView } from '@kbn/data-plugin/common'; +import type { AggregateQuery, Query } from '@kbn/es-query'; +import { isOfAggregateQueryType } from '@kbn/es-query'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { AggregationsSingleMetricAggregateBase } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { buildEsQuery } from '@kbn/es-query'; + +export interface Params { + dataView?: DataView | string; + query?: Query | AggregateQuery; + services: { + data: DataPublicPluginStart; + }; + abortSignal: AbortSignal; +} + +export interface OccurrencesRange { + from: string; + to: string; +} + +export interface Result { + range: OccurrencesRange | null | undefined; + refetch: () => Promise; +} + +export const computeTimeRange = async ({ dataView, query, services, abortSignal }: Params) => { + if ( + typeof dataView !== 'string' && + dataView?.isTimeBased() && + query && + isOfAggregateQueryType(query) + ) { + try { + const dslQuery = buildEsQuery(dataView, [], []); + const occurrencesRange = await fetchDocumentsTimeRange({ + data: services.data, + dataView, + dslQuery, + abortSignal, + }); + return occurrencesRange; + } catch (error) { + // + } + } +}; + +async function fetchDocumentsTimeRange({ + data, + dataView, + dslQuery, + abortSignal, +}: { + data: DataPublicPluginStart; + dataView: DataView; + dslQuery?: object; + abortSignal?: AbortSignal; +}): Promise { + if (!dataView?.timeFieldName) { + return null; + } + + const result = await lastValueFrom( + data.search.search( + { + params: { + index: dataView.getIndexPattern(), + size: 0, + body: { + query: dslQuery ?? { match_all: {} }, + aggs: { + earliest_timestamp: { + min: { + field: dataView.timeFieldName, + }, + }, + latest_timestamp: { + max: { + field: dataView.timeFieldName, + }, + }, + }, + }, + }, + }, + { + abortSignal, + } + ) + ); + + const earliestTimestamp = ( + result.rawResponse?.aggregations?.earliest_timestamp as AggregationsSingleMetricAggregateBase + )?.value_as_string; + const latestTimestamp = ( + result.rawResponse?.aggregations?.latest_timestamp as AggregationsSingleMetricAggregateBase + )?.value_as_string; + + return earliestTimestamp && latestTimestamp + ? { from: earliestTimestamp, to: latestTimestamp } + : null; +} diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 1c7d06749b376..4d5579c398434 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -394,13 +394,22 @@ export const QueryBarTopRow = React.memo( if (!shouldRenderDatePicker()) { return null; } + let isDisabled = props.isDisabled; + // On text based mode the datepicker is always on when the user has unsaved changes. + // When the user doesn't have any changes it should be disabled if dataview doesn't have @timestamp field + if (Boolean(isQueryLangSelected) && !props.isDirty) { + const adHocDataview = props.indexPatterns?.[0]; + if (adHocDataview && typeof adHocDataview !== 'string') { + isDisabled = !Boolean(adHocDataview.timeFieldName); + } + } const wrapperClasses = classNames('kbnQueryBar__datePickerWrapper'); return ( Date: Thu, 25 May 2023 14:56:33 +0300 Subject: [PATCH 04/14] Some fixes --- .../unified_histogram/public/chart/chart.tsx | 3 +- .../chart/hooks/use_edit_visualization.ts | 9 +- .../compute_index_timerange.ts | 112 ------------------ .../query_string_input/query_bar_top_row.tsx | 72 +++++++---- .../lens/public/app_plugin/lens_top_nav.tsx | 1 + 5 files changed, 58 insertions(+), 139 deletions(-) delete mode 100644 src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index 1e24de48f55d6..585b5603e1f6c 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -136,7 +136,7 @@ export function Chart({ !chart.hidden && dataView.id && dataView.type !== DataViewType.ROLLUP && - dataView.isTimeBased() + (isPlainRecord || (!isPlainRecord && dataView.isTimeBased())) ); const input$ = useMemo( @@ -219,6 +219,7 @@ export function Chart({ dataView, relativeTimeRange: originalRelativeTimeRange ?? relativeTimeRange, lensAttributes: lensAttributesContext.attributes, + isPlainRecord, }); return ( diff --git a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts index c1b1f899ae756..e681fd34cd91e 100644 --- a/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts +++ b/src/plugins/unified_histogram/public/chart/hooks/use_edit_visualization.ts @@ -21,16 +21,21 @@ export const useEditVisualization = ({ dataView, relativeTimeRange, lensAttributes, + isPlainRecord, }: { services: UnifiedHistogramServices; dataView: DataView; relativeTimeRange?: TimeRange; lensAttributes: TypedLensByValueInput['attributes']; + isPlainRecord?: boolean; }) => { const [canVisualize, setCanVisualize] = useState(false); const checkCanVisualize = useCallback(async () => { - if (!dataView.id || !dataView.isTimeBased() || !dataView.getTimeField().visualizable) { + if (!dataView.id) { + return false; + } + if (!isPlainRecord && (!dataView.isTimeBased() || !dataView.getTimeField().visualizable)) { return false; } @@ -43,7 +48,7 @@ export const useEditVisualization = ({ ); return Boolean(compatibleActions.length); - }, [dataView, services.uiActions]); + }, [dataView, isPlainRecord, services.uiActions]); const onEditVisualization = useMemo(() => { if (!canVisualize) { diff --git a/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts b/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts deleted file mode 100644 index 92898973294fa..0000000000000 --- a/src/plugins/unified_search/public/query_string_input/compute_index_timerange.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { lastValueFrom } from 'rxjs'; -import type { DataView } from '@kbn/data-plugin/common'; -import type { AggregateQuery, Query } from '@kbn/es-query'; -import { isOfAggregateQueryType } from '@kbn/es-query'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { AggregationsSingleMetricAggregateBase } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { buildEsQuery } from '@kbn/es-query'; - -export interface Params { - dataView?: DataView | string; - query?: Query | AggregateQuery; - services: { - data: DataPublicPluginStart; - }; - abortSignal: AbortSignal; -} - -export interface OccurrencesRange { - from: string; - to: string; -} - -export interface Result { - range: OccurrencesRange | null | undefined; - refetch: () => Promise; -} - -export const computeTimeRange = async ({ dataView, query, services, abortSignal }: Params) => { - if ( - typeof dataView !== 'string' && - dataView?.isTimeBased() && - query && - isOfAggregateQueryType(query) - ) { - try { - const dslQuery = buildEsQuery(dataView, [], []); - const occurrencesRange = await fetchDocumentsTimeRange({ - data: services.data, - dataView, - dslQuery, - abortSignal, - }); - return occurrencesRange; - } catch (error) { - // - } - } -}; - -async function fetchDocumentsTimeRange({ - data, - dataView, - dslQuery, - abortSignal, -}: { - data: DataPublicPluginStart; - dataView: DataView; - dslQuery?: object; - abortSignal?: AbortSignal; -}): Promise { - if (!dataView?.timeFieldName) { - return null; - } - - const result = await lastValueFrom( - data.search.search( - { - params: { - index: dataView.getIndexPattern(), - size: 0, - body: { - query: dslQuery ?? { match_all: {} }, - aggs: { - earliest_timestamp: { - min: { - field: dataView.timeFieldName, - }, - }, - latest_timestamp: { - max: { - field: dataView.timeFieldName, - }, - }, - }, - }, - }, - }, - { - abortSignal, - } - ) - ); - - const earliestTimestamp = ( - result.rawResponse?.aggregations?.earliest_timestamp as AggregationsSingleMetricAggregateBase - )?.value_as_string; - const latestTimestamp = ( - result.rawResponse?.aggregations?.latest_timestamp as AggregationsSingleMetricAggregateBase - )?.value_as_string; - - return earliestTimestamp && latestTimestamp - ? { from: earliestTimestamp, to: latestTimestamp } - : null; -} diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 4d5579c398434..16c1cd06fba3b 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -27,6 +27,7 @@ import { OnRefreshProps, useIsWithinBreakpoints, EuiSuperUpdateButton, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { TimeHistoryContract, getQueryLog } from '@kbn/data-plugin/public'; @@ -64,6 +65,25 @@ export const strings = { }), }; +const getWrapperWithTooltip = (children: JSX.Element, enableTooltip: boolean, language: string) => { + if (enableTooltip) { + return ( + + {children} + + ); + } else { + return children; + } +}; + const SuperDatePicker = React.memo( EuiSuperDatePicker as any ) as unknown as typeof EuiSuperDatePicker; @@ -395,41 +415,45 @@ export const QueryBarTopRow = React.memo( return null; } let isDisabled = props.isDisabled; + let enableTooltip = false; // On text based mode the datepicker is always on when the user has unsaved changes. // When the user doesn't have any changes it should be disabled if dataview doesn't have @timestamp field if (Boolean(isQueryLangSelected) && !props.isDirty) { const adHocDataview = props.indexPatterns?.[0]; if (adHocDataview && typeof adHocDataview !== 'string') { isDisabled = !Boolean(adHocDataview.timeFieldName); + enableTooltip = !Boolean(adHocDataview.timeFieldName); } } const wrapperClasses = classNames('kbnQueryBar__datePickerWrapper'); - - return ( - - - + const query = props.query as AggregateQuery; + const textBasedLanguage = getAggregateQueryMode(query); + const datePicker = ( + ); + const component = getWrapperWithTooltip(datePicker, enableTooltip, textBasedLanguage); + + return {component}; } function renderUpdateButton() { diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 9128f64783298..50000201db8fa 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -1080,6 +1080,7 @@ export const LensTopNavMenu = ({ dataViewPickerComponentProps={dataViewPickerProps} showDatePicker={ indexPatterns.some((ip) => ip.isTimeBased()) || + isOnTextBasedMode || Boolean( allLoaded && activeDatasourceId && From 5fdfcd1ef64a7be00c60a5c074ddda8e53cfeeb0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 25 May 2023 16:25:18 +0300 Subject: [PATCH 05/14] Fixes --- .../query_string_input/query_bar_top_row.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 16c1cd06fba3b..d843d7480ac52 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -65,15 +65,20 @@ export const strings = { }), }; -const getWrapperWithTooltip = (children: JSX.Element, enableTooltip: boolean, language: string) => { - if (enableTooltip) { +const getWrapperWithTooltip = ( + children: JSX.Element, + enableTooltip: boolean, + query?: Query | AggregateQuery +) => { + if (enableTooltip && query && isOfAggregateQueryType(query)) { + const textBasedLanguage = getAggregateQueryMode(query); return ( {children} @@ -427,8 +432,7 @@ export const QueryBarTopRow = React.memo( } const wrapperClasses = classNames('kbnQueryBar__datePickerWrapper'); - const query = props.query as AggregateQuery; - const textBasedLanguage = getAggregateQueryMode(query); + const datePicker = ( ); - const component = getWrapperWithTooltip(datePicker, enableTooltip, textBasedLanguage); + const component = getWrapperWithTooltip(datePicker, enableTooltip, props.query); return {component}; } From ee4a3c7614032a680b6875d0194d8f7549d1094e Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 26 May 2023 08:39:18 +0200 Subject: [PATCH 06/14] Initial changes --- .../components/layout/discover_documents.tsx | 1 + .../use_test_based_query_language.test.tsx | 5 ++-- .../hooks/use_text_based_query_language.ts | 11 ++------ .../services/discover_data_state_container.ts | 25 +++++++++++++++++-- .../main/services/discover_state.ts | 16 ++++++------ .../main/services/load_saved_search.ts | 17 +++++++++++++ 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 3070f447712c5..5391bb4d0d9b2 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -123,6 +123,7 @@ function DiscoverDocumentsComponent({ // 5. this is propagated to Discover's URL and causes an unwanted change of state to an unsorted state // This solution switches to the loading state in this component when the URL index doesn't match the dataView.id const isDataViewLoading = index && dataView.id && index !== dataView.id; + console.log({index, id: dataView.id, isDataViewLoading}); const isEmptyDataResult = !documentState.result || documentState.result.length === 0; const isPlainRecord = useMemo(() => getRawRecordType(query) === RecordRawType.PLAIN, [query]); const rows = useMemo(() => documentState.result || [], [documentState.result]); diff --git a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx index 525263e404a99..17b66fe1f29d4 100644 --- a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx +++ b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx @@ -84,6 +84,7 @@ const renderHookWithContext = ( appState?: DiscoverAppState ) => { const props = getHookProps(query, useDataViewsService ? getDataViewsService() : undefined); + props.stateContainer.actions.setDataView(dataViewMock); if (appState) { props.stateContainer.appState.getState = jest.fn(() => { return appState; @@ -284,7 +285,7 @@ describe('useTextBasedQueryLanguage', () => { fetchStatus: FetchStatus.LOADING, query: { sql: 'SELECT * from the-data-view-title WHERE field1=2' }, }); - await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(0)); + await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(1)); documents$.next({ recordRawType: RecordRawType.PLAIN, fetchStatus: FetchStatus.COMPLETE, @@ -297,7 +298,7 @@ describe('useTextBasedQueryLanguage', () => { ], query: { sql: 'SELECT * from the-data-view-title WHERE field1=2' }, }); - await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(1)); + await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(2)); stateContainer.appState.getState = jest.fn(() => { return { columns: ['field1', 'field2'], index: 'the-data-view-id' }; }); diff --git a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts index 4b9806bf44251..ca1c094594759 100644 --- a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts +++ b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts @@ -82,21 +82,14 @@ export function useTextBasedQueryLanguage({ } const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); - const dataViewObj = await dataViews.create({ - title: indexPatternFromQuery, - }); - stateContainer.internalState.transitions.setAdHocDataViews([dataViewObj]); - - if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { - dataViewObj.timeFieldName = '@timestamp'; - } + const dataViewObj = stateContainer.internalState.getState().dataView!; // don't set the columns on initial fetch, to prevent overwriting existing state const addColumnsToState = Boolean( nextColumns.length && (!initialFetch || !stateColumns?.length) ); // no need to reset index to state if it hasn't changed - const addDataViewToState = Boolean(dataViewObj.id !== index); + const addDataViewToState = Boolean(dataViewObj?.id !== index) || initialFetch; const queryChanged = indexPatternFromQuery !== indexTitle.current; if (!addColumnsToState && !queryChanged) { return; diff --git a/src/plugins/discover/public/application/main/services/discover_data_state_container.ts b/src/plugins/discover/public/application/main/services/discover_data_state_container.ts index 07e1f089bcd13..97e675b2e5c78 100644 --- a/src/plugins/discover/public/application/main/services/discover_data_state_container.ts +++ b/src/plugins/discover/public/application/main/services/discover_data_state_container.ts @@ -10,8 +10,10 @@ import { AutoRefreshDoneFn } from '@kbn/data-plugin/public'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { AggregateQuery, Query } from '@kbn/es-query'; +import { AggregateQuery, getIndexPatternFromSQLQuery, Query } from '@kbn/es-query'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { isTextBasedQuery } from '../utils/is_text_based_query'; import { getRawRecordType } from '../utils/get_raw_record_type'; import { DiscoverAppState } from './discover_app_state_container'; import { DiscoverServices } from '../../../build_services'; @@ -129,11 +131,13 @@ export function getDataStateContainer({ searchSessionManager, getAppState, getSavedSearch, + setDataView, }: { services: DiscoverServices; searchSessionManager: DiscoverSearchSessionManager; getAppState: () => DiscoverAppState; getSavedSearch: () => SavedSearch; + setDataView: (dataView: DataView) => void; }): DiscoverDataStateContainer { const { data, uiSettings, toastNotifications } = services; const { timefilter } = data.query.timefilter; @@ -226,7 +230,24 @@ export function getDataStateContainer({ }; } - const fetchQuery = (resetQuery?: boolean) => { + const fetchQuery = async (resetQuery?: boolean) => { + const query = getAppState().query; + const currentDataView = getSavedSearch().searchSource.getField('index'); + + if (query && isTextBasedQuery(query)) { + const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); + if (indexPatternFromQuery !== currentDataView?.getIndexPattern()) { + const dataViewObj = await services.dataViews.create({ + title: indexPatternFromQuery, + }); + + if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { + dataViewObj.timeFieldName = '@timestamp'; + } + setDataView(dataViewObj); + } + } + if (resetQuery) { refetch$.next('reset'); } else { diff --git a/src/plugins/discover/public/application/main/services/discover_state.ts b/src/plugins/discover/public/application/main/services/discover_state.ts index 8be2bb344ae3d..24ca0e38a4d34 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.ts @@ -228,13 +228,6 @@ export function getDiscoverStateContainer({ */ const internalStateContainer = getInternalStateContainer(); - const dataStateContainer = getDataStateContainer({ - services, - searchSessionManager, - getAppState: appStateContainer.getState, - getSavedSearch: savedSearchContainer.getState, - }); - const pauseAutoRefreshInterval = async (dataView: DataView) => { if (dataView && (!dataView.isTimeBased() || dataView.type === DataViewType.ROLLUP)) { const state = stateStorage.get(GLOBAL_STATE_URL_KEY); @@ -247,13 +240,20 @@ export function getDiscoverStateContainer({ } } }; - const setDataView = (dataView: DataView) => { internalStateContainer.transitions.setDataView(dataView); pauseAutoRefreshInterval(dataView); savedSearchContainer.getState().searchSource.setField('index', dataView); }; + const dataStateContainer = getDataStateContainer({ + services, + searchSessionManager, + getAppState: appStateContainer.getState, + getSavedSearch: savedSearchContainer.getState, + setDataView, + }); + const loadDataViewList = async () => { const dataViewList = await services.dataViews.getIdsWithTitle(true); internalStateContainer.transitions.setSavedDataViews(dataViewList); diff --git a/src/plugins/discover/public/application/main/services/load_saved_search.ts b/src/plugins/discover/public/application/main/services/load_saved_search.ts index 5bae488754322..80eb26bf29e1c 100644 --- a/src/plugins/discover/public/application/main/services/load_saved_search.ts +++ b/src/plugins/discover/public/application/main/services/load_saved_search.ts @@ -7,6 +7,7 @@ */ import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import { cloneDeep, isEqual } from 'lodash'; +import { getIndexPatternFromSQLQuery } from '@kbn/es-query'; import { isTextBasedQuery } from '../utils/is_text_based_query'; import { loadAndResolveDataView } from '../utils/resolve_data_view'; import { DiscoverInternalStateContainer } from './discover_internal_state_container'; @@ -151,6 +152,22 @@ const getStateDataView = async ( if (dataView) { return dataView; } + const query = appState?.query; + + if (query && isTextBasedQuery(query)) { + const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); + if (!dataView || indexPatternFromQuery !== dataView.title) { + const dataViewObj = await services.dataViews.create({ + id: 'textBasedIdxPattern', + title: indexPatternFromQuery, + }); + + if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { + dataViewObj.timeFieldName = '@timestamp'; + } + return dataViewObj; + } + } const result = await loadAndResolveDataView( { From ec57a50bafd349133a3e25b85725da157941860f Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 26 May 2023 07:10:50 +0000 Subject: [PATCH 07/14] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../application/main/components/layout/discover_documents.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 5391bb4d0d9b2..bd59ce5150ca0 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -123,7 +123,7 @@ function DiscoverDocumentsComponent({ // 5. this is propagated to Discover's URL and causes an unwanted change of state to an unsorted state // This solution switches to the loading state in this component when the URL index doesn't match the dataView.id const isDataViewLoading = index && dataView.id && index !== dataView.id; - console.log({index, id: dataView.id, isDataViewLoading}); + console.log({ index, id: dataView.id, isDataViewLoading }); const isEmptyDataResult = !documentState.result || documentState.result.length === 0; const isPlainRecord = useMemo(() => getRawRecordType(query) === RecordRawType.PLAIN, [query]); const rows = useMemo(() => documentState.result || [], [documentState.result]); From 548475319678683ca77f4e1235cce0f457d46407 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 26 May 2023 10:19:13 +0200 Subject: [PATCH 08/14] Fix tests --- .../components/layout/discover_documents.tsx | 1 - .../services/discover_data_state_container.ts | 18 ++++------- .../main/services/discover_state.test.ts | 10 ++++++ .../main/services/load_saved_search.ts | 17 ++-------- .../get_data_view_by_text_based_query_lang.ts | 31 +++++++++++++++++++ 5 files changed, 50 insertions(+), 27 deletions(-) create mode 100644 src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 5391bb4d0d9b2..3070f447712c5 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -123,7 +123,6 @@ function DiscoverDocumentsComponent({ // 5. this is propagated to Discover's URL and causes an unwanted change of state to an unsorted state // This solution switches to the loading state in this component when the URL index doesn't match the dataView.id const isDataViewLoading = index && dataView.id && index !== dataView.id; - console.log({index, id: dataView.id, isDataViewLoading}); const isEmptyDataResult = !documentState.result || documentState.result.length === 0; const isPlainRecord = useMemo(() => getRawRecordType(query) === RecordRawType.PLAIN, [query]); const rows = useMemo(() => documentState.result || [], [documentState.result]); diff --git a/src/plugins/discover/public/application/main/services/discover_data_state_container.ts b/src/plugins/discover/public/application/main/services/discover_data_state_container.ts index 97e675b2e5c78..3f3a6427431cc 100644 --- a/src/plugins/discover/public/application/main/services/discover_data_state_container.ts +++ b/src/plugins/discover/public/application/main/services/discover_data_state_container.ts @@ -10,9 +10,10 @@ import { AutoRefreshDoneFn } from '@kbn/data-plugin/public'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { AggregateQuery, getIndexPatternFromSQLQuery, Query } from '@kbn/es-query'; +import { AggregateQuery, Query } from '@kbn/es-query'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import { DataView } from '@kbn/data-views-plugin/common'; +import { getDataViewByTextBasedQueryLang } from '../utils/get_data_view_by_text_based_query_lang'; import { isTextBasedQuery } from '../utils/is_text_based_query'; import { getRawRecordType } from '../utils/get_raw_record_type'; import { DiscoverAppState } from './discover_app_state_container'; @@ -234,17 +235,10 @@ export function getDataStateContainer({ const query = getAppState().query; const currentDataView = getSavedSearch().searchSource.getField('index'); - if (query && isTextBasedQuery(query)) { - const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); - if (indexPatternFromQuery !== currentDataView?.getIndexPattern()) { - const dataViewObj = await services.dataViews.create({ - title: indexPatternFromQuery, - }); - - if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { - dataViewObj.timeFieldName = '@timestamp'; - } - setDataView(dataViewObj); + if (isTextBasedQuery(query)) { + const nextDataView = await getDataViewByTextBasedQueryLang(query, currentDataView, services); + if (nextDataView !== currentDataView) { + setDataView(nextDataView); } } diff --git a/src/plugins/discover/public/application/main/services/discover_state.test.ts b/src/plugins/discover/public/application/main/services/discover_state.test.ts index 684289b4e4799..37c8a358cba80 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.test.ts @@ -37,6 +37,16 @@ const startSync = (appState: DiscoverAppStateContainer) => { async function getState(url: string = '/', savedSearch?: SavedSearch) { const nextHistory = createBrowserHistory(); nextHistory.push(url); + + const dataViewsCreateMock = discoverServiceMock.dataViews.create as jest.Mock; + dataViewsCreateMock.mockImplementation(() => ({ + ...dataViewMock, + })); + discoverServiceMock.dataViews = { + ...discoverServiceMock.dataViews, + create: dataViewsCreateMock, + }; + const nextState = getDiscoverStateContainer({ services: discoverServiceMock, history: nextHistory, diff --git a/src/plugins/discover/public/application/main/services/load_saved_search.ts b/src/plugins/discover/public/application/main/services/load_saved_search.ts index 80eb26bf29e1c..a4503b0a59e00 100644 --- a/src/plugins/discover/public/application/main/services/load_saved_search.ts +++ b/src/plugins/discover/public/application/main/services/load_saved_search.ts @@ -7,7 +7,7 @@ */ import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import { cloneDeep, isEqual } from 'lodash'; -import { getIndexPatternFromSQLQuery } from '@kbn/es-query'; +import { getDataViewByTextBasedQueryLang } from '../utils/get_data_view_by_text_based_query_lang'; import { isTextBasedQuery } from '../utils/is_text_based_query'; import { loadAndResolveDataView } from '../utils/resolve_data_view'; import { DiscoverInternalStateContainer } from './discover_internal_state_container'; @@ -154,19 +154,8 @@ const getStateDataView = async ( } const query = appState?.query; - if (query && isTextBasedQuery(query)) { - const indexPatternFromQuery = getIndexPatternFromSQLQuery(query.sql); - if (!dataView || indexPatternFromQuery !== dataView.title) { - const dataViewObj = await services.dataViews.create({ - id: 'textBasedIdxPattern', - title: indexPatternFromQuery, - }); - - if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { - dataViewObj.timeFieldName = '@timestamp'; - } - return dataViewObj; - } + if (isTextBasedQuery(query)) { + return await getDataViewByTextBasedQueryLang(query, dataView, services); } const result = await loadAndResolveDataView( diff --git a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts new file mode 100644 index 0000000000000..36a0a4accabea --- /dev/null +++ b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { AggregateQuery, getIndexPatternFromSQLQuery } from '@kbn/es-query'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { DiscoverServices } from '../../../build_services'; + +export async function getDataViewByTextBasedQueryLang( + query: AggregateQuery, + currentDataView: DataView | undefined, + services: DiscoverServices +) { + const text = 'sql' in query ? query.sql : undefined; + + const indexPatternFromQuery = getIndexPatternFromSQLQuery(text); + if (indexPatternFromQuery !== currentDataView?.getIndexPattern()) { + const dataViewObj = await services.dataViews.create({ + title: indexPatternFromQuery, + }); + + if (dataViewObj.fields.getByName('@timestamp')?.type === 'date') { + dataViewObj.timeFieldName = '@timestamp'; + } + return dataViewObj; + } + return currentDataView; +} From eb32f8f81a7373ba01e2315cdb508c94a8e88e0d Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 26 May 2023 13:18:39 +0200 Subject: [PATCH 09/14] Fix tests --- .../use_test_based_query_language.test.tsx | 13 ++++--------- .../main/services/discover_state.test.ts | 18 +++++------------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx index 17b66fe1f29d4..05ef44a03f01b 100644 --- a/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx +++ b/src/plugins/discover/public/application/main/hooks/use_test_based_query_language.test.tsx @@ -23,6 +23,7 @@ import { DiscoverMainProvider } from '../services/discover_state_provider'; import { DiscoverAppState } from '../services/discover_app_state_container'; import { DiscoverStateContainer } from '../services/discover_state'; import { VIEW_MODE } from '@kbn/saved-search-plugin/public'; +import { dataViewAdHoc } from '../../../__mocks__/data_view_complex'; function getHookProps( query: AggregateQuery | Query | undefined, @@ -341,17 +342,10 @@ describe('useTextBasedQueryLanguage', () => { }); test('changing a text based query with an index pattern that not corresponds to a dataview should return results', async () => { - const dataViewsCreateMock = discoverServiceMock.dataViews.create as jest.Mock; - dataViewsCreateMock.mockImplementation(() => ({ - ...dataViewMock, - })); - const dataViewsService = { - ...discoverServiceMock.dataViews, - create: dataViewsCreateMock, - }; - const props = getHookProps(query, dataViewsService); + const props = getHookProps(query, discoverServiceMock.dataViews); const { stateContainer, replaceUrlState } = props; const documents$ = stateContainer.dataState.data$.documents$; + props.stateContainer.actions.setDataView(dataViewMock); renderHook(() => useTextBasedQueryLanguage(props), { wrapper: getHookContext(stateContainer) }); @@ -371,6 +365,7 @@ describe('useTextBasedQueryLanguage', () => { ], query: { sql: 'SELECT field1 from the-data-view-*' }, }); + props.stateContainer.actions.setDataView(dataViewAdHoc); await waitFor(() => expect(replaceUrlState).toHaveBeenCalledTimes(1)); await waitFor(() => { diff --git a/src/plugins/discover/public/application/main/services/discover_state.test.ts b/src/plugins/discover/public/application/main/services/discover_state.test.ts index 37c8a358cba80..928e3d431b65e 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.test.ts @@ -38,14 +38,12 @@ async function getState(url: string = '/', savedSearch?: SavedSearch) { const nextHistory = createBrowserHistory(); nextHistory.push(url); - const dataViewsCreateMock = discoverServiceMock.dataViews.create as jest.Mock; - dataViewsCreateMock.mockImplementation(() => ({ + discoverServiceMock.dataViews.create = jest.fn().mockReturnValue({ ...dataViewMock, - })); - discoverServiceMock.dataViews = { - ...discoverServiceMock.dataViews, - create: dataViewsCreateMock, - }; + isPersisted: () => false, + id: 'ad-hoc-id', + title: 'test', + }); const nextState = getDiscoverStateContainer({ services: discoverServiceMock, @@ -645,12 +643,6 @@ describe('Test discover state actions', () => { }); test('onCreateDefaultAdHocDataView', async () => { - discoverServiceMock.dataViews.create = jest.fn().mockReturnValue({ - ...dataViewMock, - isPersisted: () => false, - id: 'ad-hoc-id', - title: 'test', - }); const { state } = await getState('/', savedSearchMock); await state.actions.loadSavedSearch({ savedSearchId: savedSearchMock.id }); const unsubscribe = state.actions.initializeAndSync(); From 0d2a9bd72f3d4def632d790d375883ee6eec7ddc Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 29 May 2023 09:16:52 +0300 Subject: [PATCH 10/14] Fix FT test --- test/functional/apps/discover/group3/_sidebar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts index 8c681bf321ad6..0e0aa51db2c0a 100644 --- a/test/functional/apps/discover/group3/_sidebar.ts +++ b/test/functional/apps/discover/group3/_sidebar.ts @@ -404,7 +404,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.waitUntilSidebarHasLoaded(); expect(await PageObjects.discover.getSidebarAriaDescription()).to.be( - '53 available fields. 0 empty fields. 3 meta fields.' + '1 popular field. 53 available fields. 0 empty fields. 3 meta fields.' ); }); From c384ecc110b9efd4258fda30ecab6c45bb428053 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 29 May 2023 09:34:43 +0300 Subject: [PATCH 11/14] Fix transition --- .../main/components/top_nav/discover_topnav.tsx | 7 +++++-- .../main/utils/get_data_view_by_text_based_query_lang.ts | 5 ++++- test/functional/apps/discover/group3/_sidebar.ts | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx index 9b1be0e261a73..286b8a6113b27 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/discover_topnav.tsx @@ -49,8 +49,11 @@ export const DiscoverTopNav = ({ const savedDataViews = useInternalStateSelector((state) => state.savedDataViews); const savedSearch = useSavedSearchInitial(); const showDatePicker = useMemo(() => { - if (isPlainRecord) return true; - return dataView.isTimeBased() && dataView.type !== DataViewType.ROLLUP; + // always show the timepicker for text based languages + return ( + isPlainRecord || + (!isPlainRecord && dataView.isTimeBased() && dataView.type !== DataViewType.ROLLUP) + ); }, [dataView, isPlainRecord]); const services = useDiscoverServices(); const { dataViewEditor, navigation, dataViewFieldEditor, data, uiSettings, dataViews } = services; diff --git a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts index 36a0a4accabea..3b38b95dfceb1 100644 --- a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts +++ b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.ts @@ -17,7 +17,10 @@ export async function getDataViewByTextBasedQueryLang( const text = 'sql' in query ? query.sql : undefined; const indexPatternFromQuery = getIndexPatternFromSQLQuery(text); - if (indexPatternFromQuery !== currentDataView?.getIndexPattern()) { + if ( + currentDataView?.isPersisted() || + indexPatternFromQuery !== currentDataView?.getIndexPattern() + ) { const dataViewObj = await services.dataViews.create({ title: indexPatternFromQuery, }); diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts index 0e0aa51db2c0a..8c681bf321ad6 100644 --- a/test/functional/apps/discover/group3/_sidebar.ts +++ b/test/functional/apps/discover/group3/_sidebar.ts @@ -404,7 +404,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.waitUntilSidebarHasLoaded(); expect(await PageObjects.discover.getSidebarAriaDescription()).to.be( - '1 popular field. 53 available fields. 0 empty fields. 3 meta fields.' + '53 available fields. 0 empty fields. 3 meta fields.' ); }); From fd4759b93e031f6d7b66f6129199a8b591c480ae Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 29 May 2023 10:29:28 +0300 Subject: [PATCH 12/14] Add some unit tests --- .../src/text_based_languages_editor.test.tsx | 27 +++++++++++++ ...data_view_by_text_based_query_lang.test.ts | 39 +++++++++++++++++++ .../public/chart/chart.test.tsx | 11 ++++++ .../query_bar_top_row.test.tsx | 5 ++- .../lens/public/app_plugin/lens_top_nav.tsx | 1 + 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx index 6243150e56b07..a2b4866f39941 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx @@ -63,6 +63,33 @@ describe('TextBasedLanguagesEditor', () => { }); }); + it('should render the date info with no @timestamp detected', async () => { + const newProps = { + ...props, + isCodeEditorExpanded: true, + }; + await act(async () => { + const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); + expect( + component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text() + ).toStrictEqual('@timestamp not detected'); + }); + }); + + it('should render the date info with @timestamp detected if filtersByDate is true', async () => { + const newProps = { + ...props, + isCodeEditorExpanded: true, + filtersByDate: true, + }; + await act(async () => { + const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); + expect( + component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text() + ).toStrictEqual('@timestamp detected'); + }); + }); + it('should render the errors badge for the inline mode by default if errors are provides', async () => { const newProps = { ...props, diff --git a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts new file mode 100644 index 0000000000000..b77fee2cd07fd --- /dev/null +++ b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getDataViewByTextBasedQueryLang } from './get_data_view_by_text_based_query_lang'; +import { dataViewAdHoc } from '../../../__mocks__/data_view_complex'; +import { dataViewMock } from '../../../__mocks__/data_view'; +import { discoverServiceMock } from '../../../__mocks__/services'; + +describe('getDataViewByTextBasedQueryLang', () => { + discoverServiceMock.dataViews.create = jest.fn().mockReturnValue({ + ...dataViewMock, + isPersisted: () => false, + id: 'ad-hoc-id', + title: 'test', + }); + const services = discoverServiceMock; + it('returns the current dataview if is adhoc and query has not changed', async () => { + const query = { sql: 'Select * from data-view-ad-hoc-title' }; + const dataView = await getDataViewByTextBasedQueryLang(query, dataViewAdHoc, services); + expect(dataView).toStrictEqual(dataViewAdHoc); + }); + + it('creates an adhoc dataview if the current dataview is persistent and query has not changed', async () => { + const query = { sql: 'Select * from the-data-view-title' }; + const dataView = await getDataViewByTextBasedQueryLang(query, dataViewMock, services); + expect(dataView.isPersisted()).toEqual(false); + }); + + it('creates an adhoc dataview if the current dataview is ad hoc and query has changed', async () => { + const query = { sql: 'Select * from the-data-view-title' }; + const dataView = await getDataViewByTextBasedQueryLang(query, dataViewAdHoc, services); + expect(dataView.isPersisted()).toEqual(false); + }); +}); diff --git a/src/plugins/unified_histogram/public/chart/chart.test.tsx b/src/plugins/unified_histogram/public/chart/chart.test.tsx index 428db01cc3773..39c7fa934a125 100644 --- a/src/plugins/unified_histogram/public/chart/chart.test.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.test.tsx @@ -40,6 +40,7 @@ async function mountComponent({ dataView = dataViewWithTimefieldMock, currentSuggestion, allSuggestions, + isPlainRecord, }: { noChart?: boolean; noHits?: boolean; @@ -49,6 +50,7 @@ async function mountComponent({ dataView?: DataView; currentSuggestion?: Suggestion; allSuggestions?: Suggestion[]; + isPlainRecord?: boolean; } = {}) { (searchSourceInstanceMock.fetch$ as jest.Mock).mockImplementation( jest.fn().mockReturnValue(of({ rawResponse: { hits: { total: noHits ? 0 : 2 } } })) @@ -84,6 +86,7 @@ async function mountComponent({ breakdown: noBreakdown ? undefined : { field: undefined }, currentSuggestion, allSuggestions, + isPlainRecord, appendHistogram, onResetChartHeight: jest.fn(), onChartHiddenChange: jest.fn(), @@ -149,6 +152,14 @@ describe('Chart', () => { expect(component.find('[data-test-subj="unifiedHistogramChart"]').exists()).toBeTruthy(); }); + test('render when is text based and not timebased', async () => { + const component = await mountComponent({ isPlainRecord: true, dataView: dataViewMock }); + expect( + component.find('[data-test-subj="unifiedHistogramChartOptionsToggle"]').exists() + ).toBeTruthy(); + expect(component.find('[data-test-subj="unifiedHistogramChart"]').exists()).toBeTruthy(); + }); + test('triggers onEditVisualization on click', async () => { expect(mockUseEditVisualization).not.toHaveBeenCalled(); const component = await mountComponent(); diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx index afe2022529914..4d822e5b9b321 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx @@ -115,6 +115,7 @@ describe('QueryBarTopRowTopRow', () => { const TIMEPICKER_SELECTOR = 'Memo(EuiSuperDatePicker)'; const REFRESH_BUTTON_SELECTOR = 'EuiSuperUpdateButton'; const TIMEPICKER_DURATION = '[data-shared-timefilter-duration]'; + const TEXT_BASED_EDITOR = '[data-test-subj="unifiedTextLangEditor"]'; beforeEach(() => { jest.clearAllMocks(); @@ -293,7 +294,7 @@ describe('QueryBarTopRowTopRow', () => { }); it('Should NOT render query input bar if on text based languages mode', () => { - const component = shallow( + const component = mount( wrapQueryBarTopRowInContext({ query: sqlQuery, isDirty: false, @@ -307,6 +308,8 @@ describe('QueryBarTopRowTopRow', () => { ); expect(component.find(QUERY_INPUT_SELECTOR).length).toBe(0); + expect(component.find(TEXT_BASED_EDITOR).length).toBe(1); + expect(component.find(TEXT_BASED_EDITOR).prop('filtersByDate')).toBe(true); }); }); diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 50000201db8fa..41b0fa567d567 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -1080,6 +1080,7 @@ export const LensTopNavMenu = ({ dataViewPickerComponentProps={dataViewPickerProps} showDatePicker={ indexPatterns.some((ip) => ip.isTimeBased()) || + // always show the timepicker for text based languages isOnTextBasedMode || Boolean( allLoaded && From 79c3fd1969fe7e164363fe3c99746e28828ab7ab Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 30 May 2023 09:26:34 +0300 Subject: [PATCH 13/14] Address PR comments --- .../src/editor_footer.tsx | 6 ++--- .../src/text_based_languages_editor.test.tsx | 4 +-- .../src/text_based_languages_editor.tsx | 8 +++--- ...data_view_by_text_based_query_lang.test.ts | 9 +++++++ .../query_bar_top_row.test.tsx | 2 +- .../query_string_input/query_bar_top_row.tsx | 6 ++--- .../public/datasources/text_based/utils.ts | 26 +++++++++---------- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/packages/kbn-text-based-editor/src/editor_footer.tsx b/packages/kbn-text-based-editor/src/editor_footer.tsx index 1075593bbd327..b2acc7fdb4a6f 100644 --- a/packages/kbn-text-based-editor/src/editor_footer.tsx +++ b/packages/kbn-text-based-editor/src/editor_footer.tsx @@ -32,7 +32,7 @@ interface EditorFooterProps { lines: number; containerCSS: Interpolation; errors?: MonacoError[]; - filtersByDate: boolean; + detectTimestamp: boolean; onErrorClick: (error: MonacoError) => void; refreshErrors: () => void; } @@ -41,7 +41,7 @@ export const EditorFooter = memo(function EditorFooter({ lines, containerCSS, errors, - filtersByDate, + detectTimestamp, onErrorClick, refreshErrors, }: EditorFooterProps) { @@ -74,7 +74,7 @@ export const EditorFooter = memo(function EditorFooter({

- {filtersByDate + {detectTimestamp ? i18n.translate( 'textBasedEditor.query.textBasedLanguagesEditor.timestampDetected', { diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx index a2b4866f39941..69121cf42eb5a 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx @@ -76,11 +76,11 @@ describe('TextBasedLanguagesEditor', () => { }); }); - it('should render the date info with @timestamp detected if filtersByDate is true', async () => { + it('should render the date info with @timestamp detected if detectTimestamp is true', async () => { const newProps = { ...props, isCodeEditorExpanded: true, - filtersByDate: true, + detectTimestamp: true, }; await act(async () => { const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 83f79749070ea..5f432c090eb8c 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -55,7 +55,7 @@ export interface TextBasedLanguagesEditorProps { onTextLangQuerySubmit: () => void; expandCodeEditor: (status: boolean) => void; isCodeEditorExpanded: boolean; - filtersByDate?: boolean; + detectTimestamp?: boolean; errors?: Error[]; isDisabled?: boolean; isDarkMode?: boolean; @@ -88,7 +88,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ onTextLangQuerySubmit, expandCodeEditor, isCodeEditorExpanded, - filtersByDate = false, + detectTimestamp = false, errors, isDisabled, isDarkMode, @@ -539,7 +539,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} onErrorClick={onErrorClick} refreshErrors={onTextLangQuerySubmit} - filtersByDate={filtersByDate} + detectTimestamp={detectTimestamp} /> )} @@ -611,7 +611,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} onErrorClick={onErrorClick} refreshErrors={onTextLangQuerySubmit} - filtersByDate={filtersByDate} + detectTimestamp={detectTimestamp} /> )} {isCodeEditorExpanded && ( diff --git a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts index b77fee2cd07fd..3d12a3421e6c4 100644 --- a/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_data_view_by_text_based_query_lang.test.ts @@ -29,11 +29,20 @@ describe('getDataViewByTextBasedQueryLang', () => { const query = { sql: 'Select * from the-data-view-title' }; const dataView = await getDataViewByTextBasedQueryLang(query, dataViewMock, services); expect(dataView.isPersisted()).toEqual(false); + expect(dataView.timeFieldName).toBe('@timestamp'); }); it('creates an adhoc dataview if the current dataview is ad hoc and query has changed', async () => { + discoverServiceMock.dataViews.create = jest.fn().mockReturnValue({ + ...dataViewAdHoc, + isPersisted: () => false, + id: 'ad-hoc-id-1', + title: 'test-1', + timeFieldName: undefined, + }); const query = { sql: 'Select * from the-data-view-title' }; const dataView = await getDataViewByTextBasedQueryLang(query, dataViewAdHoc, services); expect(dataView.isPersisted()).toEqual(false); + expect(dataView.timeFieldName).toBeUndefined(); }); }); diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx index 4d822e5b9b321..4fd7c3a1a195d 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx @@ -309,7 +309,7 @@ describe('QueryBarTopRowTopRow', () => { expect(component.find(QUERY_INPUT_SELECTOR).length).toBe(0); expect(component.find(TEXT_BASED_EDITOR).length).toBe(1); - expect(component.find(TEXT_BASED_EDITOR).prop('filtersByDate')).toBe(true); + expect(component.find(TEXT_BASED_EDITOR).prop('detectTimestamp')).toBe(true); }); }); diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index d843d7480ac52..3037a725f089d 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -615,9 +615,9 @@ export const QueryBarTopRow = React.memo( function renderTextLangEditor() { const adHocDataview = props.indexPatterns?.[0]; - let filtersByDate = false; + let detectTimestamp = false; if (adHocDataview && typeof adHocDataview !== 'string') { - filtersByDate = Boolean(adHocDataview?.timeFieldName); + detectTimestamp = Boolean(adHocDataview?.timeFieldName); } return ( isQueryLangSelected && @@ -629,7 +629,7 @@ export const QueryBarTopRow = React.memo( expandCodeEditor={(status: boolean) => setCodeEditorIsExpanded(status)} isCodeEditorExpanded={codeEditorIsExpanded} errors={props.textBasedLanguageModeErrors} - filtersByDate={filtersByDate} + detectTimestamp={detectTimestamp} onTextLangQuerySubmit={() => onSubmit({ query: queryRef.current, diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.ts index fc5de5eba3aa0..cd8bb2b8c84fa 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.ts @@ -86,21 +86,19 @@ export async function getStateFromAggregateQuery( const dataView = await dataViews.create({ title: indexPattern, }); - if (!dataView.isPersisted()) { - if (dataView && dataView.id) { - if (dataView?.fields?.getByName('@timestamp')?.type === 'date') { - dataView.timeFieldName = '@timestamp'; - } - dataViewId = dataView?.id; - indexPatternRefs = [ - ...indexPatternRefs, - { - id: dataView.id, - title: dataView.name, - timeField: dataView.timeFieldName, - }, - ]; + if (dataView && dataView.id) { + if (dataView?.fields?.getByName('@timestamp')?.type === 'date') { + dataView.timeFieldName = '@timestamp'; } + dataViewId = dataView?.id; + indexPatternRefs = [ + ...indexPatternRefs, + { + id: dataView.id, + title: dataView.name, + timeField: dataView.timeFieldName, + }, + ]; } timeFieldName = dataView.timeFieldName; const table = await fetchDataFromAggregateQuery(query, dataView, data, expressions); From d9dcaeb661438f0e2f2dca3e8cc709db77d28859 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 30 May 2023 09:44:00 +0300 Subject: [PATCH 14/14] hide the dataview warnings for the text based mode --- .../main/hooks/utils/build_state_subscribe.ts | 3 +- .../main/utils/resolve_data_view.ts | 29 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/plugins/discover/public/application/main/hooks/utils/build_state_subscribe.ts b/src/plugins/discover/public/application/main/hooks/utils/build_state_subscribe.ts index 1799e5146c803..dac3f4cfc6c62 100644 --- a/src/plugins/discover/public/application/main/hooks/utils/build_state_subscribe.ts +++ b/src/plugins/discover/public/application/main/hooks/utils/build_state_subscribe.ts @@ -17,6 +17,7 @@ import { isEqualState, } from '../../services/discover_app_state_container'; import { addLog } from '../../../../utils/add_log'; +import { isTextBasedQuery } from '../../utils/is_text_based_query'; import { FetchStatus } from '../../../types'; import { loadAndResolveDataView } from '../../utils/resolve_data_view'; @@ -61,7 +62,7 @@ export const buildStateSubscribe = // NOTE: this is also called when navigating from discover app to context app if (nextState.index && dataViewChanged) { const { dataView: nextDataView, fallback } = await loadAndResolveDataView( - { id: nextState.index, savedSearch }, + { id: nextState.index, savedSearch, isTextBasedQuery: isTextBasedQuery(nextState?.query) }, { internalStateContainer: internalState, services } ); diff --git a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts index 7a7884e6295ad..d846f7b949513 100644 --- a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts +++ b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts @@ -123,7 +123,8 @@ export function resolveDataView( return ownDataView; } - if (stateVal && !stateValFound) { + // no warnings for text based mode + if (stateVal && !stateValFound && !Boolean(isTextBasedQuery)) { const warningTitle = i18n.translate('discover.valueIsNotConfiguredDataViewIDWarningTitle', { defaultMessage: '{stateVal} is not a configured data view ID', values: { @@ -146,20 +147,18 @@ export function resolveDataView( }); return ownDataView; } - if (!Boolean(isTextBasedQuery)) { - toastNotifications.addWarning({ - title: warningTitle, - text: i18n.translate('discover.showingDefaultDataViewWarningDescription', { - defaultMessage: - 'Showing the default data view: "{loadedDataViewTitle}" ({loadedDataViewId})', - values: { - loadedDataViewTitle: loadedDataView.getIndexPattern(), - loadedDataViewId: loadedDataView.id, - }, - }), - 'data-test-subj': 'dscDataViewNotFoundShowDefaultWarning', - }); - } + toastNotifications.addWarning({ + title: warningTitle, + text: i18n.translate('discover.showingDefaultDataViewWarningDescription', { + defaultMessage: + 'Showing the default data view: "{loadedDataViewTitle}" ({loadedDataViewId})', + values: { + loadedDataViewTitle: loadedDataView.getIndexPattern(), + loadedDataViewId: loadedDataView.id, + }, + }), + 'data-test-subj': 'dscDataViewNotFoundShowDefaultWarning', + }); } return loadedDataView;