Skip to content

Commit

Permalink
[dashboard][labs] Defer loading panels below the fold (#99880) (#100302)
Browse files Browse the repository at this point in the history
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Clint Andrew Hall <clint.hall@elastic.co>
  • Loading branch information
kibanamachine and clintandrewhall authored May 18, 2021
1 parent 9768ee2 commit 36f0795
Show file tree
Hide file tree
Showing 30 changed files with 405 additions and 111 deletions.
4 changes: 4 additions & 0 deletions src/plugins/dashboard/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ export {
} from './types';

export { migratePanelsTo730 } from './migrate_to_730_panels';

export const UI_SETTINGS = {
ENABLE_LABS_UI: 'labs:dashboard:enable_ui',
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CoreStart } from 'kibana/public';

import { coreMock, uiSettingsServiceMock } from '../../../../../core/public/mocks';
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
import { getStubPluginServices } from '../../../../presentation_util/public';

import {
EmbeddableInput,
Expand Down Expand Up @@ -63,6 +64,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};

container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
CONTACT_CARD_EMBEDDABLE,
} from '../../services/embeddable_test_samples';
import { ErrorEmbeddable, IContainer, isErrorEmbeddable } from '../../services/embeddable';
import { getStubPluginServices } from '../../../../presentation_util/public';

const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
Expand Down Expand Up @@ -53,6 +54,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};
const input = getSampleDashboardInput({
panels: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { getSampleDashboardInput, getSampleDashboardPanel } from '../test_helper

import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
import { isErrorEmbeddable } from '../../services/embeddable';
import { getStubPluginServices } from '../../../../presentation_util/public';

import {
CONTACT_CARD_EMBEDDABLE,
ContactCardEmbeddableFactory,
Expand Down Expand Up @@ -45,6 +47,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
presentationUtil: getStubPluginServices(),
};
const input = getSampleDashboardInput({
panels: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { embeddablePluginMock } from '../../../../embeddable/public/mocks';
import { DataPublicPluginStart } from '../../../../data/public/types';
import { dataPluginMock } from '../../../../data/public/mocks';
import { LINE_FEED_CHARACTER } from 'src/plugins/data/common/exports/export_csv';
import { getStubPluginServices } from '../../../../presentation_util/public';

describe('Export CSV action', () => {
const { setup, doStart } = embeddablePluginMock.createInstance();
Expand Down Expand Up @@ -59,6 +60,7 @@ describe('Export CSV action', () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};
const input = getSampleDashboardInput({
panels: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
ContactCardEmbeddableOutput,
CONTACT_CARD_EMBEDDABLE,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';

const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
Expand Down Expand Up @@ -60,6 +61,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};

container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
ContactCardEmbeddableOutput,
ContactCardEmbeddable,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';

describe('LibraryNotificationPopover', () => {
const { setup, doStart } = embeddablePluginMock.createInstance();
Expand Down Expand Up @@ -55,6 +56,7 @@ describe('LibraryNotificationPopover', () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};

container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ContactCardEmbeddableInput,
ContactCardEmbeddableOutput,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';

const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
Expand All @@ -46,6 +47,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};
const input = getSampleDashboardInput({
panels: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
ContactCardEmbeddableOutput,
CONTACT_CARD_EMBEDDABLE,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';

const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
Expand All @@ -55,6 +56,7 @@ beforeEach(async () => {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
};

container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
Expand Down
36 changes: 20 additions & 16 deletions src/plugins/dashboard/public/application/dashboard_router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {

import { createKbnUrlStateStorage, withNotifyOnErrors } from '../services/kibana_utils';
import { KibanaContextProvider } from '../services/kibana_react';

import {
AppMountParameters,
CoreSetup,
Expand Down Expand Up @@ -81,6 +82,7 @@ export async function mountApp({
kibanaLegacy: { dashboardConfig },
savedObjectsTaggingOss,
visualizations,
presentationUtil,
} = pluginsStart;

const spacesApi = pluginsStart.spacesOss?.isSpacesAvailable ? pluginsStart.spacesOss : undefined;
Expand Down Expand Up @@ -208,22 +210,24 @@ export async function mountApp({
const app = (
<I18nProvider>
<KibanaContextProvider services={dashboardServices}>
<HashRouter>
<Switch>
<Route
path={[
DashboardConstants.CREATE_NEW_DASHBOARD_URL,
`${DashboardConstants.VIEW_DASHBOARD_URL}/:id`,
]}
render={renderDashboard}
/>
<Route exact path={DashboardConstants.LANDING_PAGE_PATH} render={renderListingPage} />
<Route exact path="/">
<Redirect to={DashboardConstants.LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Switch>
</HashRouter>
<presentationUtil.ContextProvider>
<HashRouter>
<Switch>
<Route
path={[
DashboardConstants.CREATE_NEW_DASHBOARD_URL,
`${DashboardConstants.VIEW_DASHBOARD_URL}/:id`,
]}
render={renderDashboard}
/>
<Route exact path={DashboardConstants.LANDING_PAGE_PATH} render={renderListingPage} />
<Route exact path="/">
<Redirect to={DashboardConstants.LANDING_PAGE_PATH} />
</Route>
<Route render={renderNoMatch} />
</Switch>
</HashRouter>
</presentationUtil.ContextProvider>
</KibanaContextProvider>
</I18nProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ import {
} from '../../../../../core/public/mocks';
import { inspectorPluginMock } from '../../../../inspector/public/mocks';
import { uiActionsPluginMock } from '../../../../ui_actions/public/mocks';
import { getStubPluginServices } from '../../../../presentation_util/public';

const presentationUtil = getStubPluginServices();

const options: DashboardContainerServices = {
application: {} as any,
Expand All @@ -50,6 +53,7 @@ const options: DashboardContainerServices = {
uiActions: {} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
presentationUtil,
};

beforeEach(() => {
Expand Down Expand Up @@ -233,17 +237,19 @@ test('DashboardContainer in edit mode shows edit mode actions', async () => {
const component = mount(
<I18nProvider>
<KibanaContextProvider services={options}>
<EmbeddablePanel
embeddable={embeddable}
getActions={() => Promise.resolve([])}
getAllEmbeddableFactories={(() => []) as any}
getEmbeddableFactory={(() => null) as any}
notifications={{} as any}
application={options.application}
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
<presentationUtil.ContextProvider>
<EmbeddablePanel
embeddable={embeddable}
getActions={() => Promise.resolve([])}
getAllEmbeddableFactories={(() => []) as any}
getEmbeddableFactory={(() => null) as any}
notifications={{} as any}
application={options.application}
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
</presentationUtil.ContextProvider>
</KibanaContextProvider>
</I18nProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
import { PanelPlacementMethod, IPanelPlacementArgs } from './panel/dashboard_panel_placement';
import { DashboardCapabilities } from '../types';
import { PresentationUtilPluginStart } from '../../services/presentation_util';

export interface DashboardContainerInput extends ContainerInput {
dashboardCapabilities?: DashboardCapabilities;
Expand Down Expand Up @@ -68,6 +69,7 @@ export interface DashboardContainerServices {
embeddable: EmbeddableStart;
uiActions: UiActionsStart;
http: CoreStart['http'];
presentationUtil: PresentationUtilPluginStart;
}

interface IndexSignature {
Expand Down Expand Up @@ -245,7 +247,9 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
ReactDOM.render(
<I18nProvider>
<KibanaContextProvider services={this.services}>
<DashboardViewport container={this} switchViewMode={this.switchViewMode} />
<this.services.presentationUtil.ContextProvider>
<DashboardViewport container={this} switchViewMode={this.switchViewMode} />
</this.services.presentationUtil.ContextProvider>
</KibanaContextProvider>
</I18nProvider>,
dom
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import {
ContactCardEmbeddableFactory,
} from '../../../services/embeddable_test_samples';
import { coreMock, uiSettingsServiceMock } from '../../../../../../core/public/mocks';
import { getStubPluginServices } from '../../../../../presentation_util/public';

let dashboardContainer: DashboardContainer | undefined;
const presentationUtil = getStubPluginServices();

function prepare(props?: Partial<DashboardGridProps>) {
const { setup, doStart } = embeddablePluginMock.createInstance();
Expand Down Expand Up @@ -68,6 +70,7 @@ function prepare(props?: Partial<DashboardGridProps>) {
} as any,
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
presentationUtil,
};
dashboardContainer = new DashboardContainer(initialInput, options);
const defaultTestProps: DashboardGridProps = {
Expand Down Expand Up @@ -96,7 +99,9 @@ test('renders DashboardGrid', () => {
const { props, options } = prepare();
const component = mountWithIntl(
<KibanaContextProvider services={options}>
<DashboardGrid {...props} />
<presentationUtil.ContextProvider>
<DashboardGrid {...props} />
</presentationUtil.ContextProvider>
</KibanaContextProvider>
);
const panelElements = component.find('EmbeddableChildPanel');
Expand All @@ -107,7 +112,9 @@ test('renders DashboardGrid with no visualizations', () => {
const { props, options } = prepare();
const component = mountWithIntl(
<KibanaContextProvider services={options}>
<DashboardGrid {...props} />
<presentationUtil.ContextProvider>
<DashboardGrid {...props} />
</presentationUtil.ContextProvider>
</KibanaContextProvider>
);

Expand All @@ -120,7 +127,9 @@ test('DashboardGrid removes panel when removed from container', () => {
const { props, options } = prepare();
const component = mountWithIntl(
<KibanaContextProvider services={options}>
<DashboardGrid {...props} />
<presentationUtil.ContextProvider>
<DashboardGrid {...props} />
</presentationUtil.ContextProvider>
</KibanaContextProvider>
);

Expand All @@ -137,7 +146,9 @@ test('DashboardGrid renders expanded panel', () => {
const { props, options } = prepare();
const component = mountWithIntl(
<KibanaContextProvider services={options}>
<DashboardGrid {...props} />
<presentationUtil.ContextProvider>
<DashboardGrid {...props} />
</presentationUtil.ContextProvider>
</KibanaContextProvider>
);

Expand All @@ -163,7 +174,9 @@ test('DashboardGrid unmount unsubscribes', async (done) => {
const { props, options } = prepare();
const component = mountWithIntl(
<KibanaContextProvider services={options}>
<DashboardGrid {...props} />
<presentationUtil.ContextProvider>
<DashboardGrid {...props} />
</presentationUtil.ContextProvider>
</KibanaContextProvider>
);

Expand Down
Loading

0 comments on commit 36f0795

Please sign in to comment.