diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
index 57c5a9041dac2..db500566d3143 100644
--- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
+++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
@@ -7,7 +7,14 @@
*/
import './discover_layout.scss';
import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { EuiPage, EuiPageBody, EuiPanel, useEuiBackgroundColor } from '@elastic/eui';
+import {
+ EuiPage,
+ EuiPageBody,
+ EuiPanel,
+ EuiProgress,
+ useEuiBackgroundColor,
+ EuiDelayRender,
+} from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { METRIC_TYPE } from '@kbn/analytics';
@@ -81,7 +88,10 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {
if (uiSettings.get(SHOW_FIELD_STATISTICS) !== true) return VIEW_MODE.DOCUMENT_LEVEL;
return state.viewMode ?? VIEW_MODE.DOCUMENT_LEVEL;
});
- const dataView = useInternalStateSelector((state) => state.dataView!);
+ const [dataView, dataViewLoading] = useInternalStateSelector((state) => [
+ state.dataView!,
+ state.isDataViewLoading,
+ ]);
const dataState: DataMainMsg = useDataState(main$);
const savedSearch = useSavedSearchInitial();
@@ -293,6 +303,11 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {
height: 100%;
`}
>
+ {dataViewLoading && (
+
+
+
+ )}
{
const savedSearch = savedSearchMock;
@@ -26,7 +28,14 @@ const setupTestParams = (dataView: DataView | undefined) => {
discoverState.internalState.transitions.setDataView(savedSearch.searchSource.getField('index')!);
services.dataViews.get = jest.fn(() => Promise.resolve(dataView as DataView));
discoverState.appState.update = jest.fn();
- return { services, appState: discoverState.appState, internalState: discoverState.internalState };
+ discoverState.internalState.transitions = {
+ setIsDataViewLoading: jest.fn(),
+ } as unknown as Readonly>;
+ return {
+ services,
+ appState: discoverState.appState,
+ internalState: discoverState.internalState,
+ };
};
describe('changeDataView', () => {
@@ -38,6 +47,8 @@ describe('changeDataView', () => {
index: 'data-view-with-user-default-column-id',
sort: [['@timestamp', 'desc']],
});
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(1, true);
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(2, false);
});
it('should set the right app state when a valid data view to switch to is given', async () => {
@@ -48,11 +59,15 @@ describe('changeDataView', () => {
index: 'data-view-with-various-field-types-id',
sort: [['data', 'desc']],
});
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(1, true);
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(2, false);
});
it('should not set the app state when an invalid data view to switch to is given', async () => {
const params = setupTestParams(undefined);
await changeDataView('data-view-with-various-field-types', params);
expect(params.appState.update).not.toHaveBeenCalled();
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(1, true);
+ expect(params.internalState.transitions.setIsDataViewLoading).toHaveBeenNthCalledWith(2, false);
});
});
diff --git a/src/plugins/discover/public/application/main/hooks/utils/change_data_view.ts b/src/plugins/discover/public/application/main/hooks/utils/change_data_view.ts
index 7218ea76b2ac6..41a911295cacd 100644
--- a/src/plugins/discover/public/application/main/hooks/utils/change_data_view.ts
+++ b/src/plugins/discover/public/application/main/hooks/utils/change_data_view.ts
@@ -39,6 +39,7 @@ export async function changeDataView(
const dataView = internalState.getState().dataView;
const state = appState.getState();
let nextDataView: DataView | null = null;
+ internalState.transitions.setIsDataViewLoading(true);
try {
nextDataView = typeof id === 'string' ? await dataViews.get(id, false) : id;
@@ -63,4 +64,5 @@ export async function changeDataView(
internalState.transitions.setExpandedDoc(undefined);
}
}
+ internalState.transitions.setIsDataViewLoading(false);
}
diff --git a/src/plugins/discover/public/application/main/services/discover_internal_state_container.ts b/src/plugins/discover/public/application/main/services/discover_internal_state_container.ts
index ec8d7ec6c57f2..5825e4d2cef6c 100644
--- a/src/plugins/discover/public/application/main/services/discover_internal_state_container.ts
+++ b/src/plugins/discover/public/application/main/services/discover_internal_state_container.ts
@@ -17,14 +17,16 @@ import type { DataTableRecord } from '@kbn/discover-utils/types';
export interface InternalState {
dataView: DataView | undefined;
+ isDataViewLoading: boolean;
savedDataViews: DataViewListItem[];
adHocDataViews: DataView[];
expandedDoc: DataTableRecord | undefined;
customFilters: Filter[];
}
-interface InternalStateTransitions {
+export interface InternalStateTransitions {
setDataView: (state: InternalState) => (dataView: DataView) => InternalState;
+ setIsDataViewLoading: (state: InternalState) => (isLoading: boolean) => InternalState;
setSavedDataViews: (state: InternalState) => (dataView: DataViewListItem[]) => InternalState;
setAdHocDataViews: (state: InternalState) => (dataViews: DataView[]) => InternalState;
appendAdHocDataViews: (
@@ -52,6 +54,7 @@ export function getInternalStateContainer() {
return createStateContainer(
{
dataView: undefined,
+ isDataViewLoading: false,
adHocDataViews: [],
savedDataViews: [],
expandedDoc: undefined,
@@ -62,6 +65,10 @@ export function getInternalStateContainer() {
...prevState,
dataView: nextDataView,
}),
+ setIsDataViewLoading: (prevState: InternalState) => (loading: boolean) => ({
+ ...prevState,
+ isDataViewLoading: loading,
+ }),
setSavedDataViews: (prevState: InternalState) => (nextDataViewList: DataViewListItem[]) => ({
...prevState,
savedDataViews: nextDataViewList,
diff --git a/src/plugins/discover/public/application/main/utils/fetch_all.test.ts b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts
index 744ca9039d8c0..08fae23110972 100644
--- a/src/plugins/discover/public/application/main/utils/fetch_all.test.ts
+++ b/src/plugins/discover/public/application/main/utils/fetch_all.test.ts
@@ -72,6 +72,7 @@ describe('test fetchAll', () => {
getAppState: () => ({}),
getInternalState: () => ({
dataView: undefined,
+ isDataViewLoading: false,
savedDataViews: [],
adHocDataViews: [],
expandedDoc: undefined,
@@ -269,6 +270,7 @@ describe('test fetchAll', () => {
getAppState: () => ({ query }),
getInternalState: () => ({
dataView: undefined,
+ isDataViewLoading: false,
savedDataViews: [],
adHocDataViews: [],
expandedDoc: undefined,
@@ -394,6 +396,7 @@ describe('test fetchAll', () => {
getAppState: () => ({ query }),
getInternalState: () => ({
dataView: undefined,
+ isDataViewLoading: false,
savedDataViews: [],
adHocDataViews: [],
expandedDoc: undefined,