From 9b0d9ec039f82414f0856329ff9b109388d0b558 Mon Sep 17 00:00:00 2001 From: Suchit Sahoo Date: Thu, 3 Oct 2024 19:10:53 +0000 Subject: [PATCH 1/4] Fix Saved Search Load for Non Index pattern Datasources Signed-off-by: Suchit Sahoo --- .../index_patterns/index_patterns.ts | 8 ++++++ .../search_source/create_search_source.ts | 11 ++++++++ .../search_source_service.test.ts | 2 ++ .../search_source/search_source_service.ts | 9 ++++-- .../query_string/query_string_manager.ts | 2 +- .../data/public/search/search_service.ts | 8 +++++- .../public/ui/query_editor/query_editor.tsx | 7 ++--- .../public/utils/state_management/store.ts | 6 +++- .../utils/state_management/discover_slice.tsx | 28 ++++++++++++++----- .../view_components/utils/use_search.ts | 5 ++-- .../query_enhancements/public/plugin.tsx | 2 +- 11 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index ccda27870313..26daee2c58bf 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -234,6 +234,14 @@ export class IndexPatternsService { indexPatternCache.set(id, indexPattern); }; + isPresentInCache(id: string) { + const indexPattern = indexPatternCache.get(id); + if (indexPattern) { + return true; + } + return false; + } + /** * Get default index pattern */ diff --git a/src/plugins/data/common/search/search_source/create_search_source.ts b/src/plugins/data/common/search/search_source/create_search_source.ts index 74b164369018..ac9fc5a9cbe6 100644 --- a/src/plugins/data/common/search/search_source/create_search_source.ts +++ b/src/plugins/data/common/search/search_source/create_search_source.ts @@ -28,6 +28,7 @@ * under the License. */ +import { QueryStringContract } from 'src/plugins/data/public/'; import { migrateLegacyQuery } from './migrate_legacy_query'; import { SearchSource, SearchSourceDependencies } from './search_source'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; @@ -52,10 +53,20 @@ import { SearchSourceFields } from './types'; * @public */ export const createSearchSource = ( indexPatterns: IndexPatternsContract, + queryStringService: QueryStringContract, searchSourceDependencies: SearchSourceDependencies ) => async (searchSourceFields: SearchSourceFields = {}) => { const fields = { ...searchSourceFields }; + // When we load a saved search and the saved search contains a non index pattern data source this step creates the temperary index patterns and sets the appriopriate query + if ( + fields.query?.dataset && + fields.query?.dataset?.type !== 'INDEX_PATTERN' && + !indexPatterns.isPresentInCache(fields.query.dataset.id) + ) { + await queryStringService.getDatasetService().cacheDataset(fields.query?.dataset); + } + // hydrating index pattern if (fields.index && typeof fields.index === 'string') { fields.index = await indexPatterns.get(searchSourceFields.index as any); diff --git a/src/plugins/data/common/search/search_source/search_source_service.test.ts b/src/plugins/data/common/search/search_source/search_source_service.test.ts index 8be71dbdacc2..da24c295c563 100644 --- a/src/plugins/data/common/search/search_source/search_source_service.test.ts +++ b/src/plugins/data/common/search/search_source/search_source_service.test.ts @@ -31,6 +31,7 @@ import { BehaviorSubject } from 'rxjs'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; import { SearchSourceService, SearchSourceDependencies } from './'; +import { QueryStringContract } from 'src/plugins/data/public'; describe('SearchSource service', () => { let dependencies: jest.Mocked; @@ -52,6 +53,7 @@ describe('SearchSource service', () => { test('exposes proper contract', () => { const start = new SearchSourceService().start( (jest.fn() as unknown) as jest.Mocked, + (jest.fn() as unknown) as jest.Mocked, dependencies ); diff --git a/src/plugins/data/common/search/search_source/search_source_service.ts b/src/plugins/data/common/search/search_source/search_source_service.ts index b16b755d621d..b20602b3b6c6 100644 --- a/src/plugins/data/common/search/search_source/search_source_service.ts +++ b/src/plugins/data/common/search/search_source/search_source_service.ts @@ -28,18 +28,23 @@ * under the License. */ +import { QueryStringContract } from 'src/plugins/data/public'; import { createSearchSource, SearchSource, SearchSourceDependencies } from './'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; export class SearchSourceService { public setup() {} - public start(indexPatterns: IndexPatternsContract, dependencies: SearchSourceDependencies) { + public start( + indexPatterns: IndexPatternsContract, + queryStringService: QueryStringContract, + dependencies: SearchSourceDependencies + ) { return { /** * creates searchsource based on serialized search source fields */ - create: createSearchSource(indexPatterns, dependencies), + create: createSearchSource(indexPatterns, queryStringService, dependencies), /** * creates an enpty search source */ diff --git a/src/plugins/data/public/query/query_string/query_string_manager.ts b/src/plugins/data/public/query/query_string/query_string_manager.ts index 94d0eb318791..60b230e2c9d0 100644 --- a/src/plugins/data/public/query/query_string/query_string_manager.ts +++ b/src/plugins/data/public/query/query_string/query_string_manager.ts @@ -107,7 +107,7 @@ export class QueryStringManager { } public getUpdates$ = () => { - return this.query$.asObservable().pipe(skip(1)); + return this.query$.asObservable().pipe(); }; public getQuery = (): Query => { diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 0c0dd0cb8043..b9d00b76347e 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -209,13 +209,19 @@ export class SearchService implements Plugin { df: dfService, }; + const queryString = getQueryService().queryString; + return { aggs: this.aggsService.start({ fieldFormats, uiSettings }), search, showError: (e: Error) => { this.searchInterceptor.showError(e); }, - searchSource: this.searchSourceService.start(indexPatterns, searchSourceDependencies), + searchSource: this.searchSourceService.start( + indexPatterns, + queryString, + searchSourceDependencies + ), __enhance: (enhancements: SearchEnhancements) => { this.searchInterceptor = enhancements.searchInterceptor; }, 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 b4299cb6c829..ea624c3034ca 100644 --- a/src/plugins/data/public/ui/query_editor/query_editor.tsx +++ b/src/plugins/data/public/ui/query_editor/query_editor.tsx @@ -240,11 +240,10 @@ export default class QueryEditorUI extends Component { if (!isEqual(this.props.query.dataset, prevQuery.dataset)) { if (this.inputRef) { - const newQuery = this.queryString.getInitialQuery(); - const newQueryString = newQuery.query; - if (this.inputRef.getValue() !== newQueryString) { + const newQueryString = this.props.query.query; + if (this.inputRef.getValue() !== newQueryString && typeof newQueryString === 'string') { this.inputRef.setValue(newQueryString); - this.onSubmit(newQuery); + this.onSubmit(this.props.query); } } } diff --git a/src/plugins/data_explorer/public/utils/state_management/store.ts b/src/plugins/data_explorer/public/utils/state_management/store.ts index daf0b3d7e369..daded4a6f3cc 100644 --- a/src/plugins/data_explorer/public/utils/state_management/store.ts +++ b/src/plugins/data_explorer/public/utils/state_management/store.ts @@ -87,7 +87,11 @@ export const getPreloadedStore = async (services: DataExplorerServices) => { // If the url state is different from the current state, then we need to update the store // the state should have a view property if it was loaded from the url - if (action === 'POP' && urlState.metadata?.view && !isEqual(urlState, currentState)) { + if ( + (action === 'POP' || action === 'REPLACE') && + urlState.metadata?.view && + !isEqual(urlState, currentState) + ) { store.dispatch(hydrate(urlState as RootState)); } }); diff --git a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx index 026599d7fc65..8bd0a8e0ea2f 100644 --- a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx +++ b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx @@ -11,7 +11,11 @@ import { RootState, DefaultViewState } from '../../../../../data_explorer/public import { buildColumns } from '../columns'; import * as utils from './common'; import { SortOrder } from '../../../saved_searches/types'; -import { DEFAULT_COLUMNS_SETTING, PLUGIN_ID } from '../../../../common'; +import { + DEFAULT_COLUMNS_SETTING, + PLUGIN_ID, + QUERY_ENHANCEMENT_ENABLED_SETTING, +} from '../../../../common'; export interface DiscoverState { /** @@ -88,12 +92,22 @@ export const getPreloadedState = async ({ preloadedState.state.sort = savedSearchInstance.sort; preloadedState.state.savedSearch = savedSearchInstance.id; const indexPatternId = savedSearchInstance.searchSource.getField('index')?.id; - preloadedState.root = { - metadata: { - indexPattern: indexPatternId, - view: PLUGIN_ID, - }, - }; + + // If the query enhancement is enabled don't add the indexpattern id to the root since they will be migrated into the _q state + if (config.get(QUERY_ENHANCEMENT_ENABLED_SETTING)) { + preloadedState.root = { + metadata: { + view: PLUGIN_ID, + }, + }; + } else { + preloadedState.root = { + metadata: { + indexPattern: indexPatternId, + view: PLUGIN_ID, + }, + }; + } savedSearchInstance.destroy(); // this instance is no longer needed, will create another one later } diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts index 3796faea1142..01ad93ebb7c4 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_search.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts @@ -352,13 +352,14 @@ export const useSearch = (services: DiscoverViewServices) => { useEffect(() => { (async () => { const savedSearchInstance = await getSavedSearchById(savedSearchId); - setSavedSearch(savedSearchInstance); // if saved search does not exist, do not atempt to sync filters and query from savedObject - if (!savedSearch) { + if (!savedSearchInstance) { return; } + setSavedSearch(savedSearchInstance); + // sync initial app filters from savedObject to filterManager const filters = cloneDeep(savedSearchInstance.searchSource.getOwnField('filter')); const query = diff --git a/src/plugins/query_enhancements/public/plugin.tsx b/src/plugins/query_enhancements/public/plugin.tsx index cbd40cb60b60..ef3512cb797b 100644 --- a/src/plugins/query_enhancements/public/plugin.tsx +++ b/src/plugins/query_enhancements/public/plugin.tsx @@ -96,7 +96,7 @@ export class QueryEnhancementsPlugin title: 'SQL', search: sqlSearchInterceptor, getQueryString: (query: Query) => { - return `SELECT * FROM ${queryString.getQuery().dataset?.title} LIMIT 10`; + return `SELECT * FROM ${query.dataset?.title} LIMIT 10`; }, fields: { filterable: false, From 454a507185b31a379b47fc561a76af65a5ef4c6d Mon Sep 17 00:00:00 2001 From: Suchit Sahoo Date: Thu, 3 Oct 2024 22:28:36 +0000 Subject: [PATCH 2/4] Fixed Test failures Signed-off-by: Suchit Sahoo --- .../search/search_source/create_search_source.ts | 6 ++++-- .../data/common/search/search_source/search_source.ts | 2 ++ .../search_source/search_source_service.test.ts | 2 +- .../search/search_source/search_source_service.ts | 9 ++------- .../public/query/query_string/query_string_manager.ts | 6 +++--- src/plugins/data/public/search/search_service.ts | 11 ++++------- .../data/public/ui/dataset_selector/index.test.tsx | 1 + .../data/public/ui/query_editor/language_selector.tsx | 2 +- .../public/utils/state_management/store.ts | 6 +----- 9 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/plugins/data/common/search/search_source/create_search_source.ts b/src/plugins/data/common/search/search_source/create_search_source.ts index ac9fc5a9cbe6..ff97add20267 100644 --- a/src/plugins/data/common/search/search_source/create_search_source.ts +++ b/src/plugins/data/common/search/search_source/create_search_source.ts @@ -53,18 +53,20 @@ import { SearchSourceFields } from './types'; * @public */ export const createSearchSource = ( indexPatterns: IndexPatternsContract, - queryStringService: QueryStringContract, searchSourceDependencies: SearchSourceDependencies ) => async (searchSourceFields: SearchSourceFields = {}) => { const fields = { ...searchSourceFields }; // When we load a saved search and the saved search contains a non index pattern data source this step creates the temperary index patterns and sets the appriopriate query if ( + searchSourceDependencies.queryStringService && fields.query?.dataset && fields.query?.dataset?.type !== 'INDEX_PATTERN' && !indexPatterns.isPresentInCache(fields.query.dataset.id) ) { - await queryStringService.getDatasetService().cacheDataset(fields.query?.dataset); + await searchSourceDependencies.queryStringService + .getDatasetService() + .cacheDataset(fields.query?.dataset); } // hydrating index pattern 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 df57a8800ed1..f6ca2aec310e 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -83,6 +83,7 @@ import { setWith } from '@elastic/safer-lodash-set'; import { stringify } from '@osd/std'; import { uniqueId, uniq, extend, pick, difference, omit, isObject, keys, isFunction } from 'lodash'; +import { QueryStringContract } from 'src/plugins/data/public'; import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; import { fieldWildcardFilter } from '../../../../opensearch_dashboards_utils/common'; @@ -157,6 +158,7 @@ export interface SearchSourceDependencies extends FetchHandlers { set: (dataFrame: IDataFrame) => void; clear: () => void; }; + queryStringService?: QueryStringContract; } /** @public **/ diff --git a/src/plugins/data/common/search/search_source/search_source_service.test.ts b/src/plugins/data/common/search/search_source/search_source_service.test.ts index da24c295c563..6616342df377 100644 --- a/src/plugins/data/common/search/search_source/search_source_service.test.ts +++ b/src/plugins/data/common/search/search_source/search_source_service.test.ts @@ -46,6 +46,7 @@ describe('SearchSource service', () => { callMsearch: jest.fn(), loadingCount$: new BehaviorSubject(0), }, + queryStringService: (jest.fn() as unknown) as jest.Mocked, }; }); @@ -53,7 +54,6 @@ describe('SearchSource service', () => { test('exposes proper contract', () => { const start = new SearchSourceService().start( (jest.fn() as unknown) as jest.Mocked, - (jest.fn() as unknown) as jest.Mocked, dependencies ); diff --git a/src/plugins/data/common/search/search_source/search_source_service.ts b/src/plugins/data/common/search/search_source/search_source_service.ts index b20602b3b6c6..b16b755d621d 100644 --- a/src/plugins/data/common/search/search_source/search_source_service.ts +++ b/src/plugins/data/common/search/search_source/search_source_service.ts @@ -28,23 +28,18 @@ * under the License. */ -import { QueryStringContract } from 'src/plugins/data/public'; import { createSearchSource, SearchSource, SearchSourceDependencies } from './'; import { IndexPatternsContract } from '../../index_patterns/index_patterns'; export class SearchSourceService { public setup() {} - public start( - indexPatterns: IndexPatternsContract, - queryStringService: QueryStringContract, - dependencies: SearchSourceDependencies - ) { + public start(indexPatterns: IndexPatternsContract, dependencies: SearchSourceDependencies) { return { /** * creates searchsource based on serialized search source fields */ - create: createSearchSource(indexPatterns, queryStringService, dependencies), + create: createSearchSource(indexPatterns, dependencies), /** * creates an enpty search source */ diff --git a/src/plugins/data/public/query/query_string/query_string_manager.ts b/src/plugins/data/public/query/query_string/query_string_manager.ts index 60b230e2c9d0..9cd445f7c25a 100644 --- a/src/plugins/data/public/query/query_string/query_string_manager.ts +++ b/src/plugins/data/public/query/query_string/query_string_manager.ts @@ -31,7 +31,7 @@ import { BehaviorSubject } from 'rxjs'; import { skip } from 'rxjs/operators'; import { CoreStart, NotificationsSetup } from 'opensearch-dashboards/public'; -import { debounce, isEqual } from 'lodash'; +import { isEqual } from 'lodash'; import { i18n } from '@osd/i18n'; import { Dataset, DataStorage, Query, TimeRange, UI_SETTINGS } from '../../../common'; import { createHistory, QueryHistory } from './query_history'; @@ -106,8 +106,8 @@ export class QueryStringManager { } } - public getUpdates$ = () => { - return this.query$.asObservable().pipe(); + public getUpdates$ = (defaultSkip = 1) => { + return this.query$.asObservable().pipe(skip(defaultSkip)); }; public getQuery = (): Query => { diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index b9d00b76347e..818d7a08aecc 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -207,21 +207,18 @@ export class SearchService implements Plugin { loadingCount$, }, df: dfService, + queryStringService: uiSettings.get(UI_SETTINGS.QUERY_ENHANCEMENTS_ENABLED) + ? getQueryService().queryString + : undefined, }; - const queryString = getQueryService().queryString; - return { aggs: this.aggsService.start({ fieldFormats, uiSettings }), search, showError: (e: Error) => { this.searchInterceptor.showError(e); }, - searchSource: this.searchSourceService.start( - indexPatterns, - queryString, - searchSourceDependencies - ), + searchSource: this.searchSourceService.start(indexPatterns, searchSourceDependencies), __enhance: (enhancements: SearchEnhancements) => { this.searchInterceptor = enhancements.searchInterceptor; }, diff --git a/src/plugins/data/public/ui/dataset_selector/index.test.tsx b/src/plugins/data/public/ui/dataset_selector/index.test.tsx index 77528eaea532..ca1e75b62c5e 100644 --- a/src/plugins/data/public/ui/dataset_selector/index.test.tsx +++ b/src/plugins/data/public/ui/dataset_selector/index.test.tsx @@ -9,6 +9,7 @@ import { DatasetSelector as ConnectedDatasetSelector } from './index'; import { DatasetSelector } from './dataset_selector'; import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; import { Dataset } from '../../../common'; +import { of } from 'rxjs'; jest.mock('../../../../opensearch_dashboards_react/public', () => ({ useOpenSearchDashboards: jest.fn(), 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 ed7598fea563..b5d519553b12 100644 --- a/src/plugins/data/public/ui/query_editor/language_selector.tsx +++ b/src/plugins/data/public/ui/query_editor/language_selector.tsx @@ -44,7 +44,7 @@ export const QueryLanguageSelector = (props: QueryLanguageSelectorProps) => { : undefined; useEffect(() => { - const subscription = queryString.getUpdates$().subscribe((query: Query) => { + const subscription = queryString.getUpdates$(0).subscribe((query: Query) => { if (query.language !== currentLanguage) { setCurrentLanguage(query.language); } diff --git a/src/plugins/data_explorer/public/utils/state_management/store.ts b/src/plugins/data_explorer/public/utils/state_management/store.ts index daded4a6f3cc..daf0b3d7e369 100644 --- a/src/plugins/data_explorer/public/utils/state_management/store.ts +++ b/src/plugins/data_explorer/public/utils/state_management/store.ts @@ -87,11 +87,7 @@ export const getPreloadedStore = async (services: DataExplorerServices) => { // If the url state is different from the current state, then we need to update the store // the state should have a view property if it was loaded from the url - if ( - (action === 'POP' || action === 'REPLACE') && - urlState.metadata?.view && - !isEqual(urlState, currentState) - ) { + if (action === 'POP' && urlState.metadata?.view && !isEqual(urlState, currentState)) { store.dispatch(hydrate(urlState as RootState)); } }); From 27f7856b99ba602afb1b6721bae8ccf23ee0feb8 Mon Sep 17 00:00:00 2001 From: Suchit Sahoo Date: Fri, 4 Oct 2024 16:51:35 +0000 Subject: [PATCH 3/4] Fix Filter Manager Bugs in Saved Search Signed-off-by: Suchit Sahoo --- .../components/top_nav/get_top_nav_links.tsx | 2 ++ .../components/top_nav/open_search_panel.tsx | 1 + .../utils/state_management/discover_slice.tsx | 21 ++++++---------- .../view_components/utils/use_search.ts | 25 ++++++++++++------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx b/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx index d87e1e47f702..278612eb76f0 100644 --- a/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx +++ b/src/plugins/discover/public/application/components/top_nav/get_top_nav_links.tsx @@ -54,6 +54,7 @@ const getLegacyTopNavLinks = ( defaultMessage: 'New Search', }), run() { + query.filterManager.setFilters([]); // resetting the filters while we are loading a new search core.application.navigateToApp('discover', { path: '#/', }); @@ -306,6 +307,7 @@ export const getTopNavLinks = ( defaultMessage: 'New', }), run() { + query.filterManager.setFilters([]); // resetting the filters while we are loading a new search core.application.navigateToApp('discover', { path: '#/', }); diff --git a/src/plugins/discover/public/application/components/top_nav/open_search_panel.tsx b/src/plugins/discover/public/application/components/top_nav/open_search_panel.tsx index 6bb3a54e71f7..9acd1dc52a54 100644 --- a/src/plugins/discover/public/application/components/top_nav/open_search_panel.tsx +++ b/src/plugins/discover/public/application/components/top_nav/open_search_panel.tsx @@ -92,6 +92,7 @@ export function OpenSearchPanel({ onClose, makeUrl }: Props) { }, ]} onChoose={(id) => { + data.query.filterManager.setFilters([]); // resetting the filters application.navigateToApp('discover', { path: `#/view/${id}` }); onClose(); }} diff --git a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx index 8bd0a8e0ea2f..442da1d2e25c 100644 --- a/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx +++ b/src/plugins/discover/public/application/utils/state_management/discover_slice.tsx @@ -94,20 +94,13 @@ export const getPreloadedState = async ({ const indexPatternId = savedSearchInstance.searchSource.getField('index')?.id; // If the query enhancement is enabled don't add the indexpattern id to the root since they will be migrated into the _q state - if (config.get(QUERY_ENHANCEMENT_ENABLED_SETTING)) { - preloadedState.root = { - metadata: { - view: PLUGIN_ID, - }, - }; - } else { - preloadedState.root = { - metadata: { - indexPattern: indexPatternId, - view: PLUGIN_ID, - }, - }; - } + preloadedState.root = { + metadata: { + ...(indexPatternId && + !config.get(QUERY_ENHANCEMENT_ENABLED_SETTING) && { indexPattern: indexPatternId }), + view: PLUGIN_ID, + }, + }; savedSearchInstance.destroy(); // this instance is no longer needed, will create another one later } diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts index 01ad93ebb7c4..2886ba811f62 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_search.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts @@ -12,7 +12,7 @@ import { cloneDeep } from 'lodash'; import { useLocation } from 'react-router-dom'; import { RequestAdapter } from '../../../../../inspector/public'; import { DiscoverViewServices } from '../../../build_services'; -import { search } from '../../../../../data/public'; +import { QueryState, search } from '../../../../../data/public'; import { validateTimeRange } from '../../helpers/validate_time_range'; import { updateSearchSource } from './update_search_source'; import { useIndexPattern } from './use_index_pattern'; @@ -352,19 +352,23 @@ export const useSearch = (services: DiscoverViewServices) => { useEffect(() => { (async () => { const savedSearchInstance = await getSavedSearchById(savedSearchId); + setSavedSearch(savedSearchInstance); - // if saved search does not exist, do not atempt to sync filters and query from savedObject - if (!savedSearchInstance) { + // if saved search does not exist, or the URL has filter tyhen don't sync the saved search state with that + if (!savedSearchInstance || !savedSearchId) { return; } - setSavedSearch(savedSearchInstance); - - // sync initial app filters from savedObject to filterManager - const filters = cloneDeep(savedSearchInstance.searchSource.getOwnField('filter')); + // Sync Query from the saved search const query = savedSearchInstance.searchSource.getField('query') || data.query.queryString.getDefaultQuery(); + + data.query.queryString.setQuery(query); + + // Sync Filters from the saved search + const filters = cloneDeep(savedSearchInstance.searchSource.getOwnField('filter')); + const actualFilters = []; if (filters !== undefined) { @@ -374,8 +378,11 @@ export const useSearch = (services: DiscoverViewServices) => { } } - filterManager.setAppFilters(actualFilters); - data.query.queryString.setQuery(query); + // Filters in URL are higher priority than the filters in saved search + const urlFilters = (osdUrlStateStorage.get('_q') as QueryState)?.filters ?? []; + if (!urlFilters || urlFilters.length === 0) { + filterManager.setAppFilters(actualFilters); + } if (savedSearchInstance?.id) { chrome.recentlyAccessed.add( From d69bb15bea10d491b30d2661035e26a832fea157 Mon Sep 17 00:00:00 2001 From: Ashwin P Chandran Date: Sat, 19 Oct 2024 17:24:57 +0000 Subject: [PATCH 4/4] fix validation Signed-off-by: Ashwin P Chandran --- .../public/application/view_components/utils/use_search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/discover/public/application/view_components/utils/use_search.ts b/src/plugins/discover/public/application/view_components/utils/use_search.ts index 2886ba811f62..60d821b1c72b 100644 --- a/src/plugins/discover/public/application/view_components/utils/use_search.ts +++ b/src/plugins/discover/public/application/view_components/utils/use_search.ts @@ -380,7 +380,7 @@ export const useSearch = (services: DiscoverViewServices) => { // Filters in URL are higher priority than the filters in saved search const urlFilters = (osdUrlStateStorage.get('_q') as QueryState)?.filters ?? []; - if (!urlFilters || urlFilters.length === 0) { + if (!Array.isArray(urlFilters) || urlFilters.length === 0) { filterManager.setAppFilters(actualFilters); }