[Dashboard] Fix Blank Screen when Expanded Embeddable Not Found (#87925) (#88195)

* Fixed blank screen when expanded embeddable id is changed
This commit is contained in:
Devon Thomson 2021-01-13 12:46:06 -05:00 committed by GitHub
parent 0efc67cb3c
commit 5d2f7b3a49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 18 deletions

View file

@ -19,11 +19,11 @@
import { createBrowserHistory } from 'history';
import { getSavedDashboardMock } from './test_helpers';
import { DashboardContainer, DashboardContainerInput } from '.';
import { DashboardContainer, DashboardContainerInput, DashboardPanelState } from '.';
import { DashboardStateManager } from './dashboard_state_manager';
import { DashboardContainerServices } from './embeddable/dashboard_container';
import { ViewMode } from '../services/embeddable';
import { EmbeddableInput, ViewMode } from '../services/embeddable';
import { createKbnUrlStateStorage } from '../services/kibana_utils';
import { InputTimeRange, TimefilterContract, TimeRange } from '../services/data';
@ -134,6 +134,11 @@ describe('DashboardState', function () {
const dashboardContainer = initDashboardContainer({
expandedPanelId: 'theCoolestPanelOnThisDashboard',
panels: {
theCoolestPanelOnThisDashboard: {
explicitInput: { id: 'theCoolestPanelOnThisDashboard' },
} as DashboardPanelState<EmbeddableInput>,
},
});
dashboardState.handleDashboardContainerChanges(dashboardContainer);
@ -149,15 +154,39 @@ describe('DashboardState', function () {
const dashboardContainer = initDashboardContainer({
expandedPanelId: 'theCoolestPanelOnThisDashboard',
panels: {
theCoolestPanelOnThisDashboard: {
explicitInput: { id: 'theCoolestPanelOnThisDashboard' },
} as DashboardPanelState<EmbeddableInput>,
},
});
dashboardState.handleDashboardContainerChanges(dashboardContainer);
dashboardState.handleDashboardContainerChanges(dashboardContainer);
expect(dashboardState.setExpandedPanelId).toHaveBeenCalledTimes(1);
});
test('expandedPanelId is set to undefined if panel does not exist in input', () => {
dashboardState.setExpandedPanelId = jest
.fn()
.mockImplementation(dashboardState.setExpandedPanelId);
const dashboardContainer = initDashboardContainer({
expandedPanelId: 'theCoolestPanelOnThisDashboard',
panels: {
theCoolestPanelOnThisDashboard: {
explicitInput: { id: 'theCoolestPanelOnThisDashboard' },
} as DashboardPanelState<EmbeddableInput>,
},
});
dashboardContainer.updateInput({ expandedPanelId: 'woah it changed' });
dashboardState.handleDashboardContainerChanges(dashboardContainer);
expect(dashboardState.setExpandedPanelId).toHaveBeenCalledTimes(2);
expect(dashboardState.setExpandedPanelId).toHaveBeenCalledWith(
'theCoolestPanelOnThisDashboard'
);
dashboardContainer.updateInput({ expandedPanelId: 'theLeastCoolPanelOnThisDashboard' });
dashboardState.handleDashboardContainerChanges(dashboardContainer);
expect(dashboardState.setExpandedPanelId).toHaveBeenCalledWith(undefined);
});
});

View file

@ -223,6 +223,7 @@ export class DashboardStateManager {
const savedDashboardPanelMap: { [key: string]: SavedDashboardPanel } = {};
const input = dashboardContainer.getInput();
this.getPanels().forEach((savedDashboardPanel) => {
if (input.panels[savedDashboardPanel.panelIndex] !== undefined) {
savedDashboardPanelMap[savedDashboardPanel.panelIndex] = savedDashboardPanel;
@ -234,11 +235,16 @@ export class DashboardStateManager {
const convertedPanelStateMap: { [key: string]: SavedDashboardPanel } = {};
let expandedPanelValid = false;
Object.values(input.panels).forEach((panelState) => {
if (savedDashboardPanelMap[panelState.explicitInput.id] === undefined) {
dirty = true;
}
if (panelState.explicitInput.id === input.expandedPanelId) {
expandedPanelValid = true;
}
convertedPanelStateMap[panelState.explicitInput.id] = convertPanelStateToSavedDashboardPanel(
panelState,
this.kibanaVersion
@ -272,8 +278,10 @@ export class DashboardStateManager {
this.setFullScreenMode(input.isFullScreenMode);
}
if (input.expandedPanelId !== this.getExpandedPanelId()) {
if (expandedPanelValid && input.expandedPanelId !== this.getExpandedPanelId()) {
this.setExpandedPanelId(input.expandedPanelId);
} else if (!expandedPanelValid && this.getExpandedPanelId()) {
this.setExpandedPanelId(undefined);
}
if (!_.isEqual(input.query, this.getQuery())) {

View file

@ -34,7 +34,6 @@ import { ViewMode, EmbeddableChildPanel } from '../../../services/embeddable';
import { DASHBOARD_GRID_COLUMN_COUNT, DASHBOARD_GRID_HEIGHT } from '../dashboard_constants';
import { DashboardPanelState } from '../types';
import { withKibana } from '../../../services/kibana_react';
import { DashboardContainerInput } from '../dashboard_container';
import { DashboardContainer, DashboardReactContextValue } from '../dashboard_container';
let lastValidGridSize = 0;
@ -177,18 +176,17 @@ class DashboardGridUi extends React.Component<DashboardGridProps, State> {
isLayoutInvalid,
});
this.subscription = this.props.container
.getInput$()
.subscribe((input: DashboardContainerInput) => {
if (this.mounted) {
this.setState({
panels: input.panels,
viewMode: input.viewMode,
useMargins: input.useMargins,
expandedPanelId: input.expandedPanelId,
});
}
});
this.subscription = this.props.container.getInput$().subscribe(() => {
const { panels, viewMode, useMargins, expandedPanelId } = this.props.container.getInput();
if (this.mounted) {
this.setState({
panels,
viewMode,
useMargins,
expandedPanelId,
});
}
});
}
public componentWillUnmount() {