From bf323b8b4c13b19cad02b619d28984f7c2dec1d1 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 4 Oct 2024 09:21:00 +0200 Subject: [PATCH 1/6] Attempt to fix a flaky test --- .../application/main/state_management/discover_state.ts | 8 ++++++-- test/functional/apps/discover/group3/_lens_vis.ts | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/discover/public/application/main/state_management/discover_state.ts b/src/plugins/discover/public/application/main/state_management/discover_state.ts index 0e1a662567bb8..2acad45bd340a 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_state.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_state.ts @@ -408,14 +408,18 @@ export function getDiscoverStateContainer({ }; const onDataViewEdited = async (editedDataView: DataView) => { + const edited = editedDataView.id; if (editedDataView.isPersisted()) { // Clear the current data view from the cache and create a new instance // of it, ensuring we have a new object reference to trigger a re-render - services.dataViews.clearInstanceCache(editedDataView.id); + services.dataViews.clearInstanceCache(edited); setDataView(await services.dataViews.create(editedDataView.toSpec(), true)); } else { - await updateAdHocDataViewId(); + const nextDataView = await updateAdHocDataViewId(); + // eslint-disable-next-line no-console + console.log('onDataViewEdited', `${edited} -> ${nextDataView?.id}`); } + // maybe it's flaky because of this line loadDataViewList(); addLog('[getDiscoverStateContainer] onDataViewEdited triggers data fetching'); fetchData(); diff --git a/test/functional/apps/discover/group3/_lens_vis.ts b/test/functional/apps/discover/group3/_lens_vis.ts index 1bd6f8099fd22..321486a40238e 100644 --- a/test/functional/apps/discover/group3/_lens_vis.ts +++ b/test/functional/apps/discover/group3/_lens_vis.ts @@ -110,8 +110,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return seriesType; } - // Failing: See https://github.com/elastic/kibana/issues/184600 - describe.skip('discover lens vis', function () { + describe('discover lens vis', function () { before(async () => { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); From 036538a5196a0f7a8d930c0d47268b45dcfabebe Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 4 Oct 2024 09:28:34 +0200 Subject: [PATCH 2/6] Add missing await when building data view list --- .../application/main/state_management/discover_state.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plugins/discover/public/application/main/state_management/discover_state.ts b/src/plugins/discover/public/application/main/state_management/discover_state.ts index 2acad45bd340a..f014f48bdf163 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_state.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_state.ts @@ -415,12 +415,9 @@ export function getDiscoverStateContainer({ services.dataViews.clearInstanceCache(edited); setDataView(await services.dataViews.create(editedDataView.toSpec(), true)); } else { - const nextDataView = await updateAdHocDataViewId(); - // eslint-disable-next-line no-console - console.log('onDataViewEdited', `${edited} -> ${nextDataView?.id}`); + await updateAdHocDataViewId(); } - // maybe it's flaky because of this line - loadDataViewList(); + await loadDataViewList(); addLog('[getDiscoverStateContainer] onDataViewEdited triggers data fetching'); fetchData(); }; From 7d4e3dadc089754b6791415fb237a38f5a819810 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Fri, 4 Oct 2024 18:55:39 +0200 Subject: [PATCH 3/6] Add a new isLoading internal state that is set to true when a ad hoc data view changes --- .../components/top_nav/discover_topnav.tsx | 34 ++--------- .../application/main/discover_main_route.tsx | 57 ++++++++++++------- .../discover_internal_state_container.ts | 7 +++ .../main/state_management/discover_state.ts | 2 + 4 files changed, 48 insertions(+), 52 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 45e8755ca3156..86c3a85d705bb 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 @@ -8,7 +8,7 @@ */ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; -import { type DataView, DataViewType } from '@kbn/data-views-plugin/public'; +import { DataViewType } from '@kbn/data-views-plugin/public'; import { DataViewPickerProps } from '@kbn/unified-search-plugin/public'; import { ENABLE_ESQL } from '@kbn/esql-utils'; import { TextBasedLanguages } from '@kbn/esql-utils'; @@ -20,7 +20,6 @@ import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import type { DiscoverStateContainer } from '../../state_management/discover_state'; import { onSaveSearch } from './on_save_search'; import { useDiscoverCustomization } from '../../../../customizations'; -import { addLog } from '../../../../utils/add_log'; import { useAppStateSelector } from '../../state_management/discover_app_state_container'; import { useDiscoverTopNav } from './use_discover_topnav'; import { useIsEsqlMode } from '../../hooks/use_is_esql_mode'; @@ -46,15 +45,8 @@ export const DiscoverTopNav = ({ onCancelClick, }: DiscoverTopNavProps) => { const services = useDiscoverServices(); - const { - dataViewEditor, - navigation, - dataViewFieldEditor, - data, - uiSettings, - dataViews, - setHeaderActionMenu, - } = services; + const { dataViewEditor, navigation, dataViewFieldEditor, data, uiSettings, setHeaderActionMenu } = + services; const query = useAppStateSelector((state) => state.query); const adHocDataViews = useInternalStateSelector((state) => state.adHocDataViews); const dataView = useInternalStateSelector((state) => state.dataView!); @@ -122,23 +114,6 @@ export const DiscoverTopNav = ({ }); }, [dataViewEditor, stateContainer]); - const onEditDataView = useCallback( - async (editedDataView: DataView) => { - if (editedDataView.isPersisted()) { - // Clear the current data view from the cache and create a new instance - // of it, ensuring we have a new object reference to trigger a re-render - dataViews.clearInstanceCache(editedDataView.id); - stateContainer.actions.setDataView(await dataViews.create(editedDataView.toSpec(), true)); - } else { - await stateContainer.actions.updateAdHocDataViewId(); - } - stateContainer.actions.loadDataViewList(); - addLog('[DiscoverTopNav] onEditDataView triggers data fetching'); - stateContainer.dataState.fetch(); - }, - [dataViews, stateContainer.actions, stateContainer.dataState] - ); - const updateSavedQueryId = (newSavedQueryId: string | undefined) => { const { appState } = stateContainer; if (newSavedQueryId) { @@ -221,14 +196,13 @@ export const DiscoverTopNav = ({ textBasedLanguages: supportedTextBasedLanguages, adHocDataViews, savedDataViews, - onEditDataView, + onEditDataView: stateContainer.actions.onDataViewEdited, }; }, [ adHocDataViews, addField, createNewDataView, dataView, - onEditDataView, savedDataViews, stateContainer, uiSettings, diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index e763a272e45d0..57173717de2a2 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -22,6 +22,7 @@ import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { withSuspense } from '@kbn/shared-ux-utility'; import { getInitialESQLQuery } from '@kbn/esql-utils'; import { ESQL_TYPE } from '@kbn/data-view-utils'; +import { useInternalStateSelector } from './state_management/discover_internal_state_container'; import { useUrl } from './hooks/use_url'; import { useDiscoverStateContainer } from './hooks/use_discover_state_container'; import { MainHistoryLocationState } from '../../../common'; @@ -85,7 +86,6 @@ export function DiscoverMainRoute({ stateContainer, }); const [error, setError] = useState(); - const [loading, setLoading] = useState(true); const [hasESData, setHasESData] = useState(false); const [hasUserDataView, setHasUserDataView] = useState(false); const [showNoDataPage, setShowNoDataPage] = useState(false); @@ -156,9 +156,9 @@ export function DiscoverMainRoute({ initialAppState, }: { nextDataView?: DataView; initialAppState?: LoadParams['initialAppState'] } = {}) => { const loadSavedSearchStartTime = window.performance.now(); - setLoading(true); + stateContainer.internalState.transitions.setIsLoading(true); if (!nextDataView && !(await checkData())) { - setLoading(false); + stateContainer.internalState.transitions.setIsLoading(false); return; } try { @@ -181,7 +181,7 @@ export function DiscoverMainRoute({ setBreadcrumbs({ services, titleBreadcrumbText: currentSavedSearch?.title ?? undefined }); } - setLoading(false); + stateContainer.internalState.transitions.setIsLoading(false); if (services.analytics) { const loadSavedSearchDuration = window.performance.now() - loadSavedSearchStartTime; reportPerformanceMetricEvent(services.analytics, { @@ -215,7 +215,7 @@ export function DiscoverMainRoute({ }, [ checkData, - stateContainer.actions, + stateContainer, savedSearchId, historyLocationState?.dataViewSpec, customizationContext.displayMode, @@ -231,8 +231,7 @@ export function DiscoverMainRoute({ useEffect(() => { if (!isCustomizationServiceInitialized) return; - - setLoading(true); + stateContainer.internalState.transitions.setIsLoading(true); setHasESData(false); setHasUserDataView(false); setShowNoDataPage(false); @@ -258,13 +257,13 @@ export function DiscoverMainRoute({ const onDataViewCreated = useCallback( async (nextDataView: unknown) => { if (nextDataView) { - setLoading(true); + stateContainer.internalState.transitions.setIsLoading(true); setShowNoDataPage(false); setError(undefined); await loadSavedSearch({ nextDataView: nextDataView as DataView }); } }, - [loadSavedSearch] + [loadSavedSearch, stateContainer] ); const onESQLNavigationComplete = useCallback(async () => { @@ -325,14 +324,8 @@ export function DiscoverMainRoute({ ); } - if (loading) { - return loadingIndicator; - } - return ; }, [ - loading, - loadingIndicator, noDataDependencies, onDataViewCreated, onESQLNavigationComplete, @@ -354,13 +347,11 @@ export function DiscoverMainRoute({ return ( - <> - - {mainContent} - + ); @@ -368,6 +359,28 @@ export function DiscoverMainRoute({ // eslint-disable-next-line import/no-default-export export default DiscoverMainRoute; +export function DiscoverMainLoading({ + stateContainer, + showNoDataPage, + mainContent, +}: { + stateContainer: DiscoverStateContainer; + showNoDataPage: boolean; + mainContent: JSX.Element; +}) { + const loading = useInternalStateSelector((state) => state.isLoading); + if (loading && !showNoDataPage) { + return ; + } + + return ( + <> + + {mainContent} + + ); +} + function getLoadParamsForNewSearch(stateContainer: DiscoverStateContainer): { nextDataView: LoadParams['dataView']; initialAppState: LoadParams['initialAppState']; diff --git a/src/plugins/discover/public/application/main/state_management/discover_internal_state_container.ts b/src/plugins/discover/public/application/main/state_management/discover_internal_state_container.ts index d5f7deecf980a..19a9bf1438c96 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_internal_state_container.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_internal_state_container.ts @@ -19,6 +19,7 @@ import type { UnifiedHistogramVisContext } from '@kbn/unified-histogram-plugin/p export interface InternalState { dataView: DataView | undefined; + isLoading: boolean; isDataViewLoading: boolean; savedDataViews: DataViewListItem[]; adHocDataViews: DataView[]; @@ -32,6 +33,7 @@ export interface InternalState { export interface InternalStateTransitions { setDataView: (state: InternalState) => (dataView: DataView) => InternalState; setIsDataViewLoading: (state: InternalState) => (isLoading: boolean) => InternalState; + setIsLoading: (state: InternalState) => (isLoading: boolean) => InternalState; setSavedDataViews: (state: InternalState) => (dataView: DataViewListItem[]) => InternalState; setAdHocDataViews: (state: InternalState) => (dataViews: DataView[]) => InternalState; appendAdHocDataViews: ( @@ -71,6 +73,7 @@ export function getInternalStateContainer() { return createStateContainer( { dataView: undefined, + isLoading: true, isDataViewLoading: false, adHocDataViews: [], savedDataViews: [], @@ -90,6 +93,10 @@ export function getInternalStateContainer() { ...prevState, isDataViewLoading: loading, }), + setIsLoading: (prevState: InternalState) => (isLoading: boolean) => ({ + ...prevState, + isLoading, + }), setIsESQLToDataViewTransitionModalVisible: (prevState: InternalState) => (isVisible: boolean) => ({ ...prevState, diff --git a/src/plugins/discover/public/application/main/state_management/discover_state.ts b/src/plugins/discover/public/application/main/state_management/discover_state.ts index f014f48bdf163..542c861e80e6c 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_state.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_state.ts @@ -408,6 +408,7 @@ export function getDiscoverStateContainer({ }; const onDataViewEdited = async (editedDataView: DataView) => { + internalStateContainer.transitions.setIsLoading(true); const edited = editedDataView.id; if (editedDataView.isPersisted()) { // Clear the current data view from the cache and create a new instance @@ -419,6 +420,7 @@ export function getDiscoverStateContainer({ } await loadDataViewList(); addLog('[getDiscoverStateContainer] onDataViewEdited triggers data fetching'); + internalStateContainer.transitions.setIsLoading(false); fetchData(); }; From d574963ecd844960c1f7e867ac4b2f63b0fcfb2e Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Mon, 7 Oct 2024 11:58:05 +0200 Subject: [PATCH 4/6] Attempt to fix flakiness --- .../layout/use_discover_histogram.ts | 42 +++++++++++++++++-- .../main/data_fetching/fetch_all.test.ts | 3 ++ .../application/main/discover_main_route.tsx | 10 ++--- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts index 1ebeb8d7d1b7f..2994a54a3c645 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts @@ -42,13 +42,19 @@ import type { DiscoverStateContainer } from '../../state_management/discover_sta import { addLog } from '../../../../utils/add_log'; import { useInternalStateSelector } from '../../state_management/discover_internal_state_container'; import type { DiscoverAppState } from '../../state_management/discover_app_state_container'; -import { DataDocumentsMsg } from '../../state_management/discover_data_state_container'; +import type { DataDocumentsMsg } from '../../state_management/discover_data_state_container'; import { useSavedSearch } from '../../state_management/discover_state_provider'; import { useIsEsqlMode } from '../../hooks/use_is_esql_mode'; const EMPTY_ESQL_COLUMNS: DatatableColumn[] = []; const EMPTY_FILTERS: Filter[] = []; +// enabled for debugging +if (window) { + // @ts-ignore + window.ELASTIC_DISCOVER_LOGGER = `debug`; +} + export interface UseDiscoverHistogramProps { stateContainer: DiscoverStateContainer; inspectorAdapters: InspectorAdapters; @@ -180,17 +186,45 @@ export const useDiscoverHistogram = ({ totalHitsResult && typeof result !== 'number' ) { - // ignore the histogram initial loading state if discover state already has a total hits value + addLog( + '[UnifiedHistogram] ignore the histogram initial loading state if discover state already has a total hits value', + { status, result } + ); return; } + const fetchStatus = status.toString() as FetchStatus; + if ( + fetchStatus === FetchStatus.COMPLETE && + savedSearchData$.totalHits$.getValue().fetchStatus === FetchStatus.COMPLETE && + result !== savedSearchData$.totalHits$.getValue().result + ) { + // this is a workaround to make sure the new total hits value is displayed + // a different value without a loading state in between would lead to be ignored by useDataState + addLog( + '[UnifiedHistogram] send loading state to total hits$ to make sure the new value is displayed', + { status, result } + ); + savedSearchData$.totalHits$.next({ + fetchStatus: FetchStatus.LOADING, + }); + } + // Sync the totalHits$ observable with the unified histogram state savedSearchData$.totalHits$.next({ - fetchStatus: status.toString() as FetchStatus, + fetchStatus, result, }); - if (status !== UnifiedHistogramFetchStatus.complete || typeof result !== 'number') { + if ( + (status !== UnifiedHistogramFetchStatus.complete && + status !== UnifiedHistogramFetchStatus.partial) || + typeof result !== 'number' + ) { + addLog( + '[UnifiedHistogram] ignore the histogram complete/partial state if discover state already has a total hits value', + { status, result } + ); return; } diff --git a/src/plugins/discover/public/application/main/data_fetching/fetch_all.test.ts b/src/plugins/discover/public/application/main/data_fetching/fetch_all.test.ts index 169a644e69499..c58417f818b28 100644 --- a/src/plugins/discover/public/application/main/data_fetching/fetch_all.test.ts +++ b/src/plugins/discover/public/application/main/data_fetching/fetch_all.test.ts @@ -69,6 +69,7 @@ describe('test fetchAll', () => { getAppState: () => ({}), getInternalState: () => ({ dataView: undefined, + isLoading: false, isDataViewLoading: false, savedDataViews: [], adHocDataViews: [], @@ -262,6 +263,7 @@ describe('test fetchAll', () => { getInternalState: () => ({ dataView: undefined, isDataViewLoading: false, + isLoading: false, savedDataViews: [], adHocDataViews: [], expandedDoc: undefined, @@ -384,6 +386,7 @@ describe('test fetchAll', () => { getInternalState: () => ({ dataView: undefined, isDataViewLoading: false, + isLoading: false, savedDataViews: [], adHocDataViews: [], expandedDoc: undefined, diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index 57173717de2a2..26848ab20f853 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -369,14 +369,14 @@ export function DiscoverMainLoading({ mainContent: JSX.Element; }) { const loading = useInternalStateSelector((state) => state.isLoading); - if (loading && !showNoDataPage) { - return ; - } return ( <> - - {mainContent} + + {loading && !showNoDataPage ? : mainContent} ); } From 7726c7d14758e439dbb4e5efaeb3a554ea44b409 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Mon, 7 Oct 2024 19:28:56 +0200 Subject: [PATCH 5/6] Add statContainer setIsLoading function - this deserves to be a first level function - we can exchange underlying implementation if needed --- .../layout/use_discover_histogram.ts | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts index 2994a54a3c645..e68d38f3c93df 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts @@ -49,12 +49,6 @@ import { useIsEsqlMode } from '../../hooks/use_is_esql_mode'; const EMPTY_ESQL_COLUMNS: DatatableColumn[] = []; const EMPTY_FILTERS: Filter[] = []; -// enabled for debugging -if (window) { - // @ts-ignore - window.ELASTIC_DISCOVER_LOGGER = `debug`; -} - export interface UseDiscoverHistogramProps { stateContainer: DiscoverStateContainer; inspectorAdapters: InspectorAdapters; @@ -186,10 +180,7 @@ export const useDiscoverHistogram = ({ totalHitsResult && typeof result !== 'number' ) { - addLog( - '[UnifiedHistogram] ignore the histogram initial loading state if discover state already has a total hits value', - { status, result } - ); + addLog(`[UnifiedHistogram] skip ${status}: total hits > 0 in Discover`, result); return; } @@ -202,7 +193,7 @@ export const useDiscoverHistogram = ({ // this is a workaround to make sure the new total hits value is displayed // a different value without a loading state in between would lead to be ignored by useDataState addLog( - '[UnifiedHistogram] send loading state to total hits$ to make sure the new value is displayed', + '[UnifiedHistogram] send loading to totalHits$ to make sure the new value is displayed', { status, result } ); savedSearchData$.totalHits$.next({ @@ -216,11 +207,7 @@ export const useDiscoverHistogram = ({ result, }); - if ( - (status !== UnifiedHistogramFetchStatus.complete && - status !== UnifiedHistogramFetchStatus.partial) || - typeof result !== 'number' - ) { + if (status !== UnifiedHistogramFetchStatus.complete || typeof result !== 'number') { addLog( '[UnifiedHistogram] ignore the histogram complete/partial state if discover state already has a total hits value', { status, result } From 4cfc4f39e41a755a3a8325c85caee6b3c7718042 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Mon, 7 Oct 2024 19:44:36 +0200 Subject: [PATCH 6/6] Add statContainer setIsLoading function - this deserves to be a first level function - we can exchange underlying implementation if needed --- .../public/application/main/discover_main_route.tsx | 10 +++++----- .../main/state_management/discover_state.test.ts | 9 +++++++++ .../main/state_management/discover_state.ts | 12 +++++++++++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index 26848ab20f853..e68227a27b410 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -156,9 +156,9 @@ export function DiscoverMainRoute({ initialAppState, }: { nextDataView?: DataView; initialAppState?: LoadParams['initialAppState'] } = {}) => { const loadSavedSearchStartTime = window.performance.now(); - stateContainer.internalState.transitions.setIsLoading(true); + stateContainer.actions.setIsLoading(true); if (!nextDataView && !(await checkData())) { - stateContainer.internalState.transitions.setIsLoading(false); + stateContainer.actions.setIsLoading(false); return; } try { @@ -181,7 +181,7 @@ export function DiscoverMainRoute({ setBreadcrumbs({ services, titleBreadcrumbText: currentSavedSearch?.title ?? undefined }); } - stateContainer.internalState.transitions.setIsLoading(false); + stateContainer.actions.setIsLoading(false); if (services.analytics) { const loadSavedSearchDuration = window.performance.now() - loadSavedSearchStartTime; reportPerformanceMetricEvent(services.analytics, { @@ -231,7 +231,7 @@ export function DiscoverMainRoute({ useEffect(() => { if (!isCustomizationServiceInitialized) return; - stateContainer.internalState.transitions.setIsLoading(true); + stateContainer.actions.setIsLoading(true); setHasESData(false); setHasUserDataView(false); setShowNoDataPage(false); @@ -257,7 +257,7 @@ export function DiscoverMainRoute({ const onDataViewCreated = useCallback( async (nextDataView: unknown) => { if (nextDataView) { - stateContainer.internalState.transitions.setIsLoading(true); + stateContainer.actions.setIsLoading(true); setShowNoDataPage(false); setError(undefined); await loadSavedSearch({ nextDataView: nextDataView as DataView }); diff --git a/src/plugins/discover/public/application/main/state_management/discover_state.test.ts b/src/plugins/discover/public/application/main/state_management/discover_state.test.ts index a64e36bc39097..cb5ba0dcdbced 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_state.test.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_state.test.ts @@ -956,6 +956,15 @@ describe('Test discover state actions', () => { expect(setTime).toHaveBeenCalledWith({ from: 'now-15d', to: 'now-10d' }); expect(setRefreshInterval).toHaveBeenCalledWith({ pause: false, value: 1000 }); }); + + test('setIsLoading', async () => { + const { state } = await getState('/'); + expect(state.internalState.getState().isLoading).toBe(true); + await state.actions.setIsLoading(false); + expect(state.internalState.getState().isLoading).toBe(false); + await state.actions.setIsLoading(true); + expect(state.internalState.getState().isLoading).toBe(true); + }); }); describe('Test discover state with embedded mode', () => { diff --git a/src/plugins/discover/public/application/main/state_management/discover_state.ts b/src/plugins/discover/public/application/main/state_management/discover_state.ts index 542c861e80e6c..ff8529fe570c1 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_state.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_state.ts @@ -210,6 +210,11 @@ export interface DiscoverStateContainer { * @param dataView */ setDataView: (dataView: DataView) => void; + /** + * Set Discover to loading state on the highest level, this cleans up all internal UI state + * @param value + */ + setIsLoading: (value: boolean) => void; /** * Undo changes made to the saved search, e.g. when the user triggers the "Reset search" button */ @@ -407,8 +412,12 @@ export function getDiscoverStateContainer({ } }; + const setIsLoading = (value: boolean) => { + internalStateContainer.transitions.setIsLoading(value); + }; + const onDataViewEdited = async (editedDataView: DataView) => { - internalStateContainer.transitions.setIsLoading(true); + setIsLoading(true); const edited = editedDataView.id; if (editedDataView.isPersisted()) { // Clear the current data view from the cache and create a new instance @@ -594,6 +603,7 @@ export function getDiscoverStateContainer({ onDataViewCreated, onDataViewEdited, onOpenSavedSearch, + setIsLoading, transitionFromESQLToDataView, transitionFromDataViewToESQL, onUpdateQuery,