DashboardScene: Update view panel scene variables properly after row repeat is performed (#92698)
* update view panel scene variables properly after row repeat is performed * refactor * Fix case where view mode from panel menu would not work Co-authored-by: ivanortegaalba <ivan.ortega@grafana.com> * add context --------- Co-authored-by: ivanortegaalba <ivan.ortega@grafana.com>
This commit is contained in:
co-authored by
ivanortegaalba
parent
b788f43cee
commit
a0c1fc20ec
@@ -1,10 +1,11 @@
|
||||
import { AppEvents } from '@grafana/data';
|
||||
import { SceneGridLayout, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
import { SceneGridLayout, SceneGridRow, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { KioskMode } from 'app/types';
|
||||
|
||||
import { DashboardGridItem } from './DashboardGridItem';
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
import { RowRepeaterBehavior } from './RowRepeaterBehavior';
|
||||
import { DashboardRepeatsProcessedEvent } from './types';
|
||||
|
||||
describe('DashboardSceneUrlSync', () => {
|
||||
@@ -108,6 +109,35 @@ describe('DashboardSceneUrlSync', () => {
|
||||
scene.publishEvent(new DashboardRepeatsProcessedEvent({ source: scene }));
|
||||
expect(scene.state.viewPanelScene?.getUrlKey()).toBe('panel-1-clone-1');
|
||||
});
|
||||
|
||||
it('should subscribe and update view panel if panel is in a repeated row', () => {
|
||||
const scene = buildTestScene();
|
||||
|
||||
// fake adding row panel
|
||||
const layout = scene.state.body as SceneGridLayout;
|
||||
layout.setState({
|
||||
children: [
|
||||
new SceneGridRow({
|
||||
$behaviors: [new RowRepeaterBehavior({ variableName: 'test' })],
|
||||
children: [
|
||||
new VizPanel({
|
||||
title: 'Panel A',
|
||||
key: 'panel-1',
|
||||
pluginId: 'table',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
scene.urlSync?.updateFromUrl({ viewPanel: 'panel-1' });
|
||||
|
||||
expect(scene.state.viewPanelScene?.getUrlKey()).toBeUndefined();
|
||||
|
||||
// Verify it subscribes to DashboardRepeatsProcessedEvent
|
||||
scene.publishEvent(new DashboardRepeatsProcessedEvent({ source: scene }));
|
||||
expect(scene.state.viewPanelScene?.getUrlKey()).toBe('panel-1');
|
||||
});
|
||||
});
|
||||
|
||||
function buildTestScene() {
|
||||
|
||||
@@ -18,7 +18,13 @@ import { buildPanelEditScene } from '../panel-edit/PanelEditor';
|
||||
import { createDashboardEditViewFor } from '../settings/utils';
|
||||
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
|
||||
import { ShareModal } from '../sharing/ShareModal';
|
||||
import { findVizPanelByKey, getDashboardSceneFor, getLibraryPanel, isPanelClone } from '../utils/utils';
|
||||
import {
|
||||
findVizPanelByKey,
|
||||
getDashboardSceneFor,
|
||||
getLibraryPanel,
|
||||
isPanelClone,
|
||||
isWithinUnactivatedRepeatRow,
|
||||
} from '../utils/utils';
|
||||
|
||||
import { DashboardScene, DashboardSceneState } from './DashboardScene';
|
||||
import { LibraryVizPanel } from './LibraryVizPanel';
|
||||
@@ -121,6 +127,11 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWithinUnactivatedRepeatRow(panel)) {
|
||||
this._handleViewRepeatClone(values.viewPanel);
|
||||
return;
|
||||
}
|
||||
|
||||
update.viewPanelScene = new ViewPanelScene({ panelRef: panel.getRef() });
|
||||
} else if (viewPanelScene && values.viewPanel === null) {
|
||||
update.viewPanelScene = undefined;
|
||||
|
||||
@@ -18,6 +18,7 @@ import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { LibraryVizPanel } from '../scene/LibraryVizPanel';
|
||||
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
|
||||
import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
|
||||
import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior';
|
||||
import { RowActions } from '../scene/row-actions/RowActions';
|
||||
|
||||
import { dashboardSceneGraph } from './dashboardSceneGraph';
|
||||
@@ -261,3 +262,22 @@ export function getLibraryPanel(vizPanel: VizPanel): LibraryVizPanel | undefined
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the panel is within a repeated row, it must wait until the row resolves the variables.
|
||||
* This ensures that the scoped variable for the row is assigned and the panel is initialized with them.
|
||||
*/
|
||||
export function isWithinUnactivatedRepeatRow(panel: VizPanel): boolean {
|
||||
let row;
|
||||
|
||||
try {
|
||||
row = sceneGraph.getAncestor(panel, SceneGridRow);
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasBehavior = !!(row.state.$behaviors && row.state.$behaviors.find((b) => b instanceof RowRepeaterBehavior));
|
||||
const hasVariables = !!(row.state.$variables && row.state.$variables.state.variables.length > 0);
|
||||
|
||||
return hasBehavior && !hasVariables;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user