From 45d8bbba3a402a3e5cae584aeea2b9625ac5c796 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:18:27 +0100 Subject: [PATCH] Dashboards: Defer loading of plugin exports until panel is visible (#47361) (#47932) (cherry picked from commit 8ae5dd74e617fcb8442514a1afa3229a5d938334) --- .../containers/DashboardPage.test.tsx | 6 +++- .../dashboard/dashgrid/DashboardPanel.tsx | 33 ++++++++----------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.test.tsx b/public/app/features/dashboard/containers/DashboardPage.test.tsx index 4c68581de51..c6b90437dc0 100644 --- a/public/app/features/dashboard/containers/DashboardPage.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Provider } from 'react-redux'; +import { useEffectOnce } from 'react-use'; import { render, screen } from '@testing-library/react'; import { Props, UnthemedDashboardPage } from './DashboardPage'; import { Props as LazyLoaderProps } from '../dashgrid/LazyLoader'; @@ -17,7 +18,10 @@ import { AutoSizerProps } from 'react-virtualized-auto-sizer'; import { setDashboardSrv } from '../services/DashboardSrv'; jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => { - const LazyLoader = ({ children }: Pick) => { + const LazyLoader = ({ children, onLoad }: Pick) => { + useEffectOnce(() => { + onLoad?.(); + }); return <>{typeof children === 'function' ? children({ isInView: true }) : children}; }; return { LazyLoader }; diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 668ed6e8d42..ecdfdb231eb 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -4,7 +4,6 @@ import { PanelChrome } from './PanelChrome'; import { PanelChromeAngular } from './PanelChromeAngular'; import { DashboardModel, PanelModel } from '../state'; import { StoreState } from 'app/types'; -import { PanelPlugin } from '@grafana/data'; import { cleanUpPanelState, setPanelInstanceState } from '../../panel/state/reducers'; import { initPanelState } from '../../panel/state/actions'; import { LazyLoader } from './LazyLoader'; @@ -52,8 +51,8 @@ export class DashboardPanelUnconnected extends PureComponent { componentDidMount() { this.props.panel.isInView = !this.props.lazy; - if (!this.props.plugin) { - this.props.initPanelState(this.props.panel); + if (!this.props.lazy) { + this.onPanelLoad(); } } @@ -72,11 +71,18 @@ export class DashboardPanelUnconnected extends PureComponent { this.props.panel.isInView = v; }; - renderPanel(plugin: PanelPlugin) { - const { dashboard, panel, isViewing, isEditing, width, height, lazy } = this.props; + onPanelLoad = () => { + if (!this.props.plugin) { + this.props.initPanelState(this.props.panel); + } + }; + + render() { + const { dashboard, panel, isViewing, isEditing, width, height, lazy, plugin } = this.props; const renderPanelChrome = (isInView: boolean) => - plugin.angularPanelCtrl ? ( + plugin && + (plugin.angularPanelCtrl ? ( { height={height} onInstanceStateChange={this.onInstanceStateChange} /> - ); + )); return lazy ? ( - + {({ isInView }) => renderPanelChrome(isInView)} ) : ( renderPanelChrome(true) ); } - - render() { - const { plugin } = this.props; - - // If we have not loaded plugin exports yet, wait - if (!plugin) { - return null; - } - - return this.renderPanel(plugin); - } } export const DashboardPanel = connector(DashboardPanelUnconnected);