diff --git a/src/platform/plugins/shared/discover/public/application/main/components/top_nav/on_save_search.tsx b/src/platform/plugins/shared/discover/public/application/main/components/top_nav/on_save_search.tsx index 130f1f1dbe40a..faeeae34b335d 100644 --- a/src/platform/plugins/shared/discover/public/application/main/components/top_nav/on_save_search.tsx +++ b/src/platform/plugins/shared/discover/public/application/main/components/top_nav/on_save_search.tsx @@ -11,6 +11,7 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiSwitch } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { UnifiedSearchDraft } from '@kbn/unified-search-plugin/public'; import type { OnSaveProps } from '@kbn/saved-objects-plugin/public'; import { SavedObjectSaveModal, showSaveModal } from '@kbn/saved-objects-plugin/public'; import type { SavedSearch, SaveSavedSearchOptions } from '@kbn/saved-search-plugin/public'; @@ -25,12 +26,14 @@ async function saveDataSource({ services, state, navigateOrReloadSavedSearch, + searchDraft, }: { savedSearch: SavedSearch; saveOptions: SaveSavedSearchOptions; services: DiscoverServices; state: DiscoverStateContainer; navigateOrReloadSavedSearch: boolean; + searchDraft: UnifiedSearchDraft | undefined; }) { const prevSavedSearchId = savedSearch.id; function onSuccess(id: string) { @@ -68,7 +71,9 @@ async function saveDataSource({ } try { - const response = await state.savedSearchState.persist(savedSearch, saveOptions); + const response = await state.savedSearchState.persist(savedSearch, saveOptions, { + searchDraft, + }); if (response?.id) { onSuccess(response.id!); } @@ -162,6 +167,7 @@ export async function onSaveSearch({ savedSearch, state, navigateOrReloadSavedSearch, + searchDraft: currentTab.uiState.searchDraft, }); // If the save wasn't successful, put the original values back. diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts index 1a590cec5b689..8277798094f0b 100644 --- a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts +++ b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_saved_search_container.ts @@ -20,6 +20,7 @@ import { canImportVisContext } from '@kbn/unified-histogram'; import type { SavedObjectSaveOpts } from '@kbn/saved-objects-plugin/public'; import { isEqual, isFunction } from 'lodash'; import { i18n } from '@kbn/i18n'; +import type { UnifiedSearchDraft } from '@kbn/unified-search-plugin/public'; import { VIEW_MODE } from '../../../../common/constants'; import { updateSavedSearch } from './utils/update_saved_search'; import { addLog } from '../../../utils/add_log'; @@ -95,7 +96,8 @@ export interface DiscoverSavedSearchContainer { */ persist: ( savedSearch: SavedSearch, - saveOptions?: SavedObjectSaveOpts + saveOptions?: SavedObjectSaveOpts, + options?: { searchDraft?: UnifiedSearchDraft } ) => Promise<{ id: string | undefined } | undefined>; /** * Set the persisted & current state of the saved search @@ -178,7 +180,66 @@ export function getSavedSearchContainer({ }; }; - const persist = async (nextSavedSearch: SavedSearch, saveOptions?: SavedObjectSaveOpts) => { + const applySearchDraftChanges = ( + savedSearch: SavedSearch, + searchDraft: UnifiedSearchDraft | undefined + ): SavedSearch => { + if (!searchDraft?.query && !searchDraft?.dateRangeFrom && !searchDraft?.dateRangeTo) { + addLog('[savedSearch] applySearchDraftChanges: no search draft changes to apply'); + return savedSearch; + } + + // If there are unsubmitted changes to the query or time range, we apply them here + const nextSavedSearchModified = { + ...savedSearch, + }; + + const activeQuery = savedSearch.searchSource.getField('query'); + const draftQuery = searchDraft?.query; + if (draftQuery && !isEqual(activeQuery, draftQuery)) { + if (isOfAggregateQueryType(draftQuery) !== isOfAggregateQueryType(activeQuery)) { + addLog('[savedSearch] applySearchDraftChanges: query type changed', { + activeQuery, + searchDraftQuery: draftQuery, + }); + return savedSearch; // Do not apply changes if the query type has changed + } + + addLog('[savedSearch] applySearchDraftChanges: updating query from search draft', { + activeQuery, + searchDraftQuery: draftQuery, + }); + nextSavedSearchModified.searchSource = nextSavedSearchModified.searchSource.createCopy(); + nextSavedSearchModified.searchSource.setField('query', draftQuery); + } + + if (!searchDraft?.dateRangeFrom && !searchDraft?.dateRangeTo) { + return nextSavedSearchModified; + } + + if (nextSavedSearchModified.timeRestore && nextSavedSearchModified.timeRange) { + addLog('[savedSearch] applySearchDraftChanges: updating time range from search draft', { + activeTimeRange: nextSavedSearchModified.timeRange, + searchDraftTimeRange: { + from: searchDraft?.dateRangeFrom, + to: searchDraft?.dateRangeTo, + }, + }); + nextSavedSearchModified.timeRange = { ...nextSavedSearchModified.timeRange }; + nextSavedSearchModified.timeRange.from = + searchDraft?.dateRangeFrom || nextSavedSearchModified.timeRange.from; + nextSavedSearchModified.timeRange.to = + searchDraft?.dateRangeTo || nextSavedSearchModified.timeRange.to; + } + + return nextSavedSearchModified; + }; + + const persist: DiscoverSavedSearchContainer['persist'] = async ( + nextSavedSearch, + saveOptions, + options + ) => { addLog('[savedSearch] persist', { nextSavedSearch, saveOptions }); const dataView = nextSavedSearch.searchSource.getField('index'); @@ -222,10 +283,12 @@ export function getSavedSearchContainer({ ); } - const id = await services.savedSearch.save(nextSavedSearch, saveOptions || {}); + const nextSavedSearchModified = applySearchDraftChanges(nextSavedSearch, options?.searchDraft); + + const id = await services.savedSearch.save(nextSavedSearchModified, saveOptions || {}); if (id) { - set(nextSavedSearch); + set(nextSavedSearchModified); } return { id }; diff --git a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_state.ts b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_state.ts index c5bca15d21344..5108aff6dde68 100644 --- a/src/platform/plugins/shared/discover/public/application/main/state_management/discover_state.ts +++ b/src/platform/plugins/shared/discover/public/application/main/state_management/discover_state.ts @@ -381,7 +381,13 @@ export function getDiscoverStateContainer({ const transitionFromDataViewToESQL = (dataView: DataView) => { const appState = appStateContainer.get(); const { query } = appState; - const filterQuery = query && isOfQueryType(query) ? query : undefined; + + let filterQuery = query && isOfQueryType(query) ? query : undefined; + const draftQuery = getCurrentTab().uiState.searchDraft?.query; // was not executed yet + if (draftQuery && isOfQueryType(draftQuery)) { + filterQuery = draftQuery; + } + const queryString = getInitialESQLQuery(dataView, filterQuery); appStateContainer.update({