Dashboards: Fixing saving and viewing snapshots for repeated panels (#109856)

This commit is contained in:
Torkel Ödegaard 2025-08-19 16:42:15 +02:00 committed by GitHub
parent d07fa65920
commit b0e9307d15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 4 deletions

View File

@ -999,6 +999,9 @@ describe('transformSaveModelToScene', () => {
config: {},
},
],
scopedVars: {
var1: { value: 'value1', text: 'text1' },
},
},
],
}) as Panel;
@ -1021,6 +1024,30 @@ describe('transformSaveModelToScene', () => {
{ config: {}, name: 'Field 2', type: 'number' },
]);
});
it('should translate scopedVars to local variable value', () => {
const panel = createPanelSaveModel({
title: 'test',
gridPos: { x: 1, y: 0, w: 12, h: 8 },
targets: [
{
queryType: 'snapshot',
},
],
// @ts-ignore
scopedVars: {
var1: { value: 'value1', text: 'text1' },
},
}) as Panel;
const oldPanelModel = new PanelModel(panel);
const scenePanel = buildGridItemForPanel(oldPanelModel);
const vizPanel = scenePanel.state.body;
expect(vizPanel.state.$variables?.state.variables[0].state.name).toBe('var1');
expect(vizPanel.state.$variables?.state.variables[0].getValue()).toBe('value1');
expect(vizPanel.state.$variables?.state.variables[0].getValueText?.()).toBe('text1');
});
});
});

View File

@ -18,6 +18,7 @@ import {
SceneDataLayerProvider,
UserActionEvent,
SceneObjectState,
LocalValueVariable,
} from '@grafana/scenes';
import { isWeekStart } from '@grafana/ui';
import { K8S_V1_DASHBOARD_API_CONFIG } from 'app/features/dashboard/api/v1';
@ -443,6 +444,21 @@ export function buildGridItemForPanel(panel: PanelModel): DashboardGridItem {
});
}
if (panel.scopedVars && panel.targets?.[0]?.queryType === 'snapshot') {
vizPanelState.$variables = new SceneVariableSet({
variables: Object.entries(panel.scopedVars).map(
([key, variable]) =>
new LocalValueVariable({
name: key,
value: variable?.value,
text: variable?.text,
isMulti: true,
includeAll: true,
})
),
});
}
const body = new VizPanel(vizPanelState);
return new DashboardGridItem({

View File

@ -38,6 +38,7 @@ import { DefaultGridLayoutManager } from '../scene/layout-default/DefaultGridLay
import { RowRepeaterBehavior } from '../scene/layout-default/RowRepeaterBehavior';
import { isClonedKey } from '../utils/clone';
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
import { djb2Hash } from '../utils/djb2Hash';
import {
calculateGridItemDimensions,
getLibraryPanelBehavior,
@ -337,7 +338,7 @@ export function panelRepeaterToPanels(repeater: DashboardGridItem, isSnapshot =
y = 0;
if (repeater.state.repeatDirection === 'v') {
x = repeater.state.x!;
y = index * h;
y = repeater.state.y! + index * h;
} else {
x = (index % columnCount) * w;
y = repeater.state.y! + Math.floor(index / columnCount) * h;
@ -348,7 +349,7 @@ export function panelRepeaterToPanels(repeater: DashboardGridItem, isSnapshot =
const localVariable = panel.state.$variables!.getByName(repeater.state.variableName!) as LocalValueVariable;
const result: Panel = {
id: getPanelIdForVizPanel(panel),
id: djb2Hash(panel.state.key!),
type: panel.state.pluginId,
title: panel.state.title,
gridPos,

View File

@ -373,8 +373,8 @@ export function getLibraryPanelBehavior(vizPanel: VizPanel): LibraryPanelBehavio
}
export function calculateGridItemDimensions(repeater: DashboardGridItem) {
const rowCount = Math.ceil(repeater.state.repeatedPanels!.length / repeater.getMaxPerRow());
const columnCount = Math.ceil(repeater.state.repeatedPanels!.length / rowCount);
const rowCount = Math.ceil(repeater.getPanelCount() / repeater.getMaxPerRow());
const columnCount = Math.ceil(repeater.getPanelCount() / rowCount);
const w = 24 / columnCount;
const h = repeater.state.itemHeight ?? 10;
return { h, w, columnCount };