mirror of https://github.com/grafana/grafana.git
DashboardScene: Re-perform repeat when returning to dashboard from panel edit (#92754)
* Reset prev values on panel deactivation/reactivation * add comments * fix * add test
This commit is contained in:
parent
cb9c7de0ff
commit
2bbce8a7f7
|
@ -1,11 +1,18 @@
|
||||||
import { VariableRefresh } from '@grafana/data';
|
import { VariableRefresh } from '@grafana/data';
|
||||||
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
|
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
|
||||||
import { setPluginImportUtils } from '@grafana/runtime';
|
import { setPluginImportUtils } from '@grafana/runtime';
|
||||||
import { SceneGridLayout, VizPanel } from '@grafana/scenes';
|
import { SceneGridLayout, SceneVariableSet, TestVariable, VizPanel } from '@grafana/scenes';
|
||||||
|
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from 'app/features/variables/constants';
|
||||||
|
|
||||||
import { activateFullSceneTree, buildPanelRepeaterScene } from '../utils/test-utils';
|
import { activateFullSceneTree, buildPanelRepeaterScene } from '../utils/test-utils';
|
||||||
|
|
||||||
import { DashboardGridItem, DashboardGridItemState } from './DashboardGridItem';
|
import { DashboardGridItem, DashboardGridItemState } from './DashboardGridItem';
|
||||||
|
import { DashboardScene } from './DashboardScene';
|
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => ({
|
||||||
|
...jest.requireActual('@grafana/runtime'),
|
||||||
|
getPluginLinkExtensions: jest.fn().mockReturnValue({ extensions: [] }),
|
||||||
|
}));
|
||||||
|
|
||||||
setPluginImportUtils({
|
setPluginImportUtils({
|
||||||
importPanelPlugin: (id: string) => Promise.resolve(getPanelPlugin({})),
|
importPanelPlugin: (id: string) => Promise.resolve(getPanelPlugin({})),
|
||||||
|
@ -85,6 +92,142 @@ describe('PanelRepeaterGridItem', () => {
|
||||||
expect(repeater.state.repeatedPanels?.length).toBe(1);
|
expect(repeater.state.repeatedPanels?.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should redo the repeat when editing panel and then returning to dashboard', async () => {
|
||||||
|
const panel = new DashboardGridItem({
|
||||||
|
variableName: 'server',
|
||||||
|
repeatedPanels: [],
|
||||||
|
body: new VizPanel({
|
||||||
|
title: 'Panel $server',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const variable = new TestVariable({
|
||||||
|
name: 'server',
|
||||||
|
query: 'A.*',
|
||||||
|
value: ALL_VARIABLE_VALUE,
|
||||||
|
text: ALL_VARIABLE_TEXT,
|
||||||
|
isMulti: true,
|
||||||
|
includeAll: true,
|
||||||
|
delayMs: 0,
|
||||||
|
optionsToReturn: [
|
||||||
|
{ label: 'A', value: '1' },
|
||||||
|
{ label: 'B', value: '2' },
|
||||||
|
{ label: 'C', value: '3' },
|
||||||
|
{ label: 'D', value: '4' },
|
||||||
|
{ label: 'E', value: '5' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const scene = new DashboardScene({
|
||||||
|
$variables: new SceneVariableSet({
|
||||||
|
variables: [variable],
|
||||||
|
}),
|
||||||
|
body: new SceneGridLayout({
|
||||||
|
children: [panel],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const deactivate = activateFullSceneTree(scene);
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
expect(panel.state.repeatedPanels?.length).toBe(5);
|
||||||
|
|
||||||
|
const vizPanel = panel.state.body as VizPanel;
|
||||||
|
|
||||||
|
expect(vizPanel.state.title).toBe('Panel $server');
|
||||||
|
|
||||||
|
// mimic going to panel edit
|
||||||
|
deactivate();
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
vizPanel.setState({ title: 'Changed' });
|
||||||
|
//mimic returning to dashboard from panel edit cloning panel
|
||||||
|
panel.setState({ body: vizPanel.clone() });
|
||||||
|
|
||||||
|
// mimic returning to dashboard
|
||||||
|
activateFullSceneTree(scene);
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
expect(panel.state.repeatedPanels?.length).toBe(5);
|
||||||
|
expect((panel.state.repeatedPanels![0] as VizPanel).state.title).toBe('Changed');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should only redo the repeat of an edited panel, not all panels in dashboard', async () => {
|
||||||
|
const panel = new DashboardGridItem({
|
||||||
|
variableName: 'server',
|
||||||
|
repeatedPanels: [],
|
||||||
|
body: new VizPanel({
|
||||||
|
title: 'Panel $server',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const panel2 = new DashboardGridItem({
|
||||||
|
variableName: 'server',
|
||||||
|
repeatedPanels: [],
|
||||||
|
body: new VizPanel({
|
||||||
|
title: 'Panel $server 2',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const variable = new TestVariable({
|
||||||
|
name: 'server',
|
||||||
|
query: 'A.*',
|
||||||
|
value: ALL_VARIABLE_VALUE,
|
||||||
|
text: ALL_VARIABLE_TEXT,
|
||||||
|
isMulti: true,
|
||||||
|
includeAll: true,
|
||||||
|
delayMs: 0,
|
||||||
|
optionsToReturn: [
|
||||||
|
{ label: 'A', value: '1' },
|
||||||
|
{ label: 'B', value: '2' },
|
||||||
|
{ label: 'C', value: '3' },
|
||||||
|
{ label: 'D', value: '4' },
|
||||||
|
{ label: 'E', value: '5' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const scene = new DashboardScene({
|
||||||
|
$variables: new SceneVariableSet({
|
||||||
|
variables: [variable],
|
||||||
|
}),
|
||||||
|
body: new SceneGridLayout({
|
||||||
|
children: [panel, panel2],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const deactivate = activateFullSceneTree(scene);
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
expect(panel.state.repeatedPanels?.length).toBe(5);
|
||||||
|
|
||||||
|
const vizPanel = panel.state.body as VizPanel;
|
||||||
|
|
||||||
|
expect(vizPanel.state.title).toBe('Panel $server');
|
||||||
|
|
||||||
|
// mimic going to panel edit
|
||||||
|
deactivate();
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
vizPanel.setState({ title: 'Changed' });
|
||||||
|
//mimic returning to dashboard from panel edit cloning panel
|
||||||
|
panel.setState({ body: vizPanel.clone() });
|
||||||
|
|
||||||
|
const performRepeatMock = jest.spyOn(panel, 'performRepeat');
|
||||||
|
// mimic returning to dashboard
|
||||||
|
activateFullSceneTree(scene);
|
||||||
|
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
|
||||||
|
expect(performRepeatMock).toHaveBeenCalledTimes(1); // only for the edited panel
|
||||||
|
expect(panel.state.repeatedPanels?.length).toBe(5);
|
||||||
|
expect((panel.state.repeatedPanels![0] as VizPanel).state.title).toBe('Changed');
|
||||||
|
});
|
||||||
|
|
||||||
it('Should display a panel when there are variable errors', () => {
|
it('Should display a panel when there are variable errors', () => {
|
||||||
const { scene, repeater } = buildPanelRepeaterScene({
|
const { scene, repeater } = buildPanelRepeaterScene({
|
||||||
variableQueryTime: 0,
|
variableQueryTime: 0,
|
||||||
|
|
|
@ -45,6 +45,7 @@ export type RepeatDirection = 'v' | 'h';
|
||||||
export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> implements SceneGridItemLike {
|
export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> implements SceneGridItemLike {
|
||||||
private _libPanelSubscription: Unsubscribable | undefined;
|
private _libPanelSubscription: Unsubscribable | undefined;
|
||||||
private _prevRepeatValues?: VariableValueSingle[];
|
private _prevRepeatValues?: VariableValueSingle[];
|
||||||
|
private _oldBody?: VizPanel | LibraryVizPanel | AddLibraryPanelDrawer;
|
||||||
|
|
||||||
protected _variableDependency = new DashboardGridItemVariableDependencyHandler(this);
|
protected _variableDependency = new DashboardGridItemVariableDependencyHandler(this);
|
||||||
|
|
||||||
|
@ -57,6 +58,11 @@ export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> i
|
||||||
private _activationHandler() {
|
private _activationHandler() {
|
||||||
if (this.state.variableName) {
|
if (this.state.variableName) {
|
||||||
this._subs.add(this.subscribeToState((newState, prevState) => this._handleGridResize(newState, prevState)));
|
this._subs.add(this.subscribeToState((newState, prevState) => this._handleGridResize(newState, prevState)));
|
||||||
|
if (this._oldBody !== this.state.body) {
|
||||||
|
this._prevRepeatValues = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._oldBody = this.state.body;
|
||||||
this.performRepeat();
|
this.performRepeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue