Dashboards: Defer loading of plugin exports until panel is visible (#47361) (#47932)

(cherry picked from commit 8ae5dd74e6)
This commit is contained in:
kay delaney
2022-04-20 11:18:27 +01:00
committed by GitHub
parent 78659b6814
commit 45d8bbba3a
2 changed files with 19 additions and 20 deletions
@@ -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<LazyLoaderProps, 'children'>) => {
const LazyLoader = ({ children, onLoad }: Pick<LazyLoaderProps, 'children' | 'onLoad'>) => {
useEffectOnce(() => {
onLoad?.();
});
return <>{typeof children === 'function' ? children({ isInView: true }) : children}</>;
};
return { LazyLoader };
@@ -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<Props> {
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<Props> {
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 ? (
<PanelChromeAngular
plugin={plugin}
panel={panel}
@@ -99,27 +105,16 @@ export class DashboardPanelUnconnected extends PureComponent<Props> {
height={height}
onInstanceStateChange={this.onInstanceStateChange}
/>
);
));
return lazy ? (
<LazyLoader width={width} height={height} onChange={this.onVisibilityChange}>
<LazyLoader width={width} height={height} onChange={this.onVisibilityChange} onLoad={this.onPanelLoad}>
{({ isInView }) => renderPanelChrome(isInView)}
</LazyLoader>
) : (
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);