DashboardScene: Re-perform repeat when returning to dashboard from panel edit (#92754)

* Reset prev values on panel deactivation/reactivation

* add comments

* fix

* add test
pull/92875/head
Victor Marin 10 months ago committed by GitHub
parent cb9c7de0ff
commit 2bbce8a7f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 145
      public/app/features/dashboard-scene/scene/DashboardGridItem.test.tsx
  2. 6
      public/app/features/dashboard-scene/scene/DashboardGridItem.tsx

@ -1,11 +1,18 @@
import { VariableRefresh } from '@grafana/data';
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
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 { DashboardGridItem, DashboardGridItemState } from './DashboardGridItem';
import { DashboardScene } from './DashboardScene';
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getPluginLinkExtensions: jest.fn().mockReturnValue({ extensions: [] }),
}));
setPluginImportUtils({
importPanelPlugin: (id: string) => Promise.resolve(getPanelPlugin({})),
@ -85,6 +92,142 @@ describe('PanelRepeaterGridItem', () => {
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', () => {
const { scene, repeater } = buildPanelRepeaterScene({
variableQueryTime: 0,

@ -45,6 +45,7 @@ export type RepeatDirection = 'v' | 'h';
export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> implements SceneGridItemLike {
private _libPanelSubscription: Unsubscribable | undefined;
private _prevRepeatValues?: VariableValueSingle[];
private _oldBody?: VizPanel | LibraryVizPanel | AddLibraryPanelDrawer;
protected _variableDependency = new DashboardGridItemVariableDependencyHandler(this);
@ -57,6 +58,11 @@ export class DashboardGridItem extends SceneObjectBase<DashboardGridItemState> i
private _activationHandler() {
if (this.state.variableName) {
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();
}

Loading…
Cancel
Save