Dashboard: Fix changes doesn't reflect after changing panel sizes in inspect JSON and click on apply (#35276)

* Trigger DashboardPanelsChangedEvent from InspectJSONTab if the panel.gridPos changed and if the dashboard needs to re-render, if yes we will  that will update the positioning
* Minor cleanup

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Maria Alexandra 2021-06-15 14:12:32 +02:00 committed by GitHub
parent adbb15a3a7
commit b774dd9b1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 11 deletions

View File

@ -1,6 +1,5 @@
// Libraries
import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader';
import ReactGridLayout, { ItemCallback } from 'react-grid-layout';
import classNames from 'classnames';
// @ts-ignore
@ -98,11 +97,22 @@ export interface Props {
isPanelEditorOpen?: boolean;
}
export class DashboardGrid extends PureComponent<Props> {
export interface State {
isLayoutInitialized: boolean;
}
export class DashboardGrid extends PureComponent<Props, State> {
private panelMap: { [id: string]: PanelModel } = {};
private panelRef: { [id: string]: HTMLElement } = {};
private eventSubs = new Subscription();
constructor(props: Props) {
super(props);
this.state = {
isLayoutInitialized: false,
};
}
componentDidMount() {
const { dashboard } = this.props;
this.eventSubs.add(dashboard.events.subscribe(DashboardPanelsChangedEvent, this.triggerForceUpdate));
@ -153,8 +163,10 @@ export class DashboardGrid extends PureComponent<Props> {
this.props.dashboard.sortPanelsByGridPos();
// Call render() after any changes. This is called when the layout loads
this.forceUpdate();
// onLayoutChange is called onMount this marks layout as initialized and we are ready to render panels
if (!this.state.isLayoutInitialized) {
this.setState({ isLayoutInitialized: true });
}
};
triggerForceUpdate = () => {
@ -163,10 +175,6 @@ export class DashboardGrid extends PureComponent<Props> {
updateGridPos = (item: ReactGridLayout.Layout, layout: ReactGridLayout.Layout[]) => {
this.panelMap[item.i!].updateGridPos(item);
// react-grid-layout has a bug (#670), and onLayoutChange() is only called when the component is mounted.
// So it's required to call it explicitly when panel resized or moved to save layout changes.
this.onLayoutChange(layout);
};
onResize: ItemCallback = (layout, oldItem, newItem) => {
@ -259,7 +267,6 @@ export class DashboardGrid extends PureComponent<Props> {
render() {
const { dashboard, viewPanel } = this.props;
return (
<SizedReactLayoutGrid
className={classNames({ layout: true })}
@ -277,5 +284,3 @@ export class DashboardGrid extends PureComponent<Props> {
);
}
}
export default hot(module)(DashboardGrid);

View File

@ -1088,6 +1088,13 @@ export class DashboardModel {
return this.meta.canEdit || this.meta.canMakeEditable;
}
shouldUpdateDashboardPanelFromJSON(updatedPanel: PanelModel, panel: PanelModel) {
const shouldUpdateGridPositionLayout = !isEqual(updatedPanel?.gridPos, panel?.gridPos);
if (shouldUpdateGridPositionLayout) {
this.events.publish(new DashboardPanelsChangedEvent());
}
}
private getPanelRepeatVariable(panel: PanelModel) {
return this.getVariablesFromState().find((variable) => variable.name === panel.repeat);
}

View File

@ -105,6 +105,7 @@ export class InspectJSONTab extends PureComponent<Props, State> {
appEvents.emit(AppEvents.alertError, ['Unable to apply']);
} else {
const updates = JSON.parse(this.state.text);
dashboard!.shouldUpdateDashboardPanelFromJSON(updates, panel!);
panel!.restoreModel(updates);
panel!.refresh();
appEvents.emit(AppEvents.alertSuccess, ['Panel model updated']);