PanelEdit: Fixed timing and state related issues (#22131)

* PanelEdit: Fixed timing and state related issues

* Added unit test and changed some logic

* Fixed id logic

* Updated snapshots

* Update public/app/features/dashboard/state/PanelModel.ts

Co-Authored-By: Dominik Prokop <dominik.prokop@grafana.com>

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
Torkel Ödegaard
2020-02-13 16:06:45 +01:00
committed by GitHub
parent 9c55500cc0
commit 70b0ec65b3
13 changed files with 139 additions and 37 deletions

View File

@@ -969,16 +969,4 @@ export class DashboardModel {
panel.render();
}
}
updatePanel = (panelModel: PanelModel) => {
let index = 0;
for (const panel of this.panels) {
if (panel.id === panelModel.id) {
this.panels[index].restoreModel(panelModel.getSaveModel());
this.panels[index].getQueryRunner().pipeDataToSubject(panelModel.getQueryRunner().getLastResult());
break;
}
index++;
}
};
}

View File

@@ -88,6 +88,7 @@ const defaults: any = {
targets: [{ refId: 'A' }],
cachedPluginOptions: {},
transparent: false,
options: {},
};
export class PanelModel {
@@ -179,7 +180,6 @@ export class PanelModel {
updateOptions(options: object) {
this.options = options;
this.render();
}
@@ -354,7 +354,12 @@ export class PanelModel {
}
getEditClone() {
const clone = new PanelModel(this.getSaveModel());
const sourceModel = this.getSaveModel();
// Temporary id for the clone, restored later in redux action when changes are saved
sourceModel.id = 23763571993;
const clone = new PanelModel(sourceModel);
const sourceQueryRunner = this.getQueryRunner();
// pipe last result to new clone query runner

View File

@@ -3,7 +3,7 @@ import { getBackendSrv } from '@grafana/runtime';
import { createSuccessNotification } from 'app/core/copy/appNotification';
// Actions
import { loadPluginDashboards } from '../../plugins/state/actions';
import { loadDashboardPermissions, dashboardPanelTypeChanged } from './reducers';
import { loadDashboardPermissions, panelModelAndPluginReady } from './reducers';
import { notifyApp } from 'app/core/actions';
import { loadPanelPlugin } from 'app/features/plugins/state/actions';
// Types
@@ -122,6 +122,8 @@ export function initDashboardPanel(panel: PanelModel): ThunkResult<void> {
if (!panel.plugin) {
panel.pluginLoaded(plugin);
}
dispatch(panelModelAndPluginReady({ panelId: panel.id, plugin }));
};
}
@@ -139,6 +141,7 @@ export function changePanelPlugin(panel: PanelModel, pluginId: string): ThunkRes
}
panel.changePlugin(plugin);
dispatch(dashboardPanelTypeChanged({ panelId: panel.id, pluginId }));
dispatch(panelModelAndPluginReady({ panelId: panel.id, plugin }));
};
}

View File

@@ -4,6 +4,7 @@ import {
DashboardState,
DashboardAclDTO,
DashboardInitError,
PanelState,
QueriesToUpdateOnDashboardLoad,
} from 'app/types';
import { processAclItems } from 'app/core/utils/acl';
@@ -11,6 +12,7 @@ import { panelEditorReducer } from '../panel_editor/state/reducers';
import { panelEditorReducerNew } from '../components/PanelEditor/state/reducers';
import { DashboardModel } from './DashboardModel';
import { PanelModel } from './PanelModel';
import { PanelPlugin } from '@grafana/data';
export const initialState: DashboardState = {
initPhase: DashboardInitPhase.NotStarted,
@@ -72,16 +74,24 @@ const dashbardSlice = createSlice({
clearDashboardQueriesToUpdateOnLoad: (state, action: PayloadAction) => {
state.modifiedQueries = null;
},
dashboardPanelTypeChanged: (state, action: PayloadAction<DashboardPanelTypeChangedPayload>) => {
state.panels[action.payload.panelId] = { pluginId: action.payload.pluginId };
panelModelAndPluginReady: (state: DashboardState, action: PayloadAction<PanelModelAndPluginReadyPayload>) => {
updatePanelState(state, action.payload.panelId, { plugin: action.payload.plugin });
},
addPanelToDashboard: (state, action: PayloadAction<AddPanelPayload>) => {},
},
});
export interface DashboardPanelTypeChangedPayload {
export function updatePanelState(state: DashboardState, panelId: number, ps: Partial<PanelState>) {
if (!state.panels[panelId]) {
state.panels[panelId] = ps as PanelState;
} else {
Object.assign(state.panels[panelId], ps);
}
}
export interface PanelModelAndPluginReadyPayload {
panelId: number;
pluginId: string;
plugin: PanelPlugin;
}
export interface AddPanelPayload {
@@ -98,7 +108,7 @@ export const {
cleanUpDashboard,
setDashboardQueriesToUpdateOnLoad,
clearDashboardQueriesToUpdateOnLoad,
dashboardPanelTypeChanged,
panelModelAndPluginReady,
addPanelToDashboard,
} = dashbardSlice.actions;

View File

@@ -0,0 +1,9 @@
import { DashboardState, PanelState } from 'app/types';
export function getPanelStateById(state: DashboardState, panelId: number): PanelState {
if (!panelId) {
return {} as PanelState;
}
return state.panels[panelId] ?? ({} as PanelState);
}