mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
Scenes/LibraryPanels: Fix transformSceneToSaveModel for library panel repeats (#83843)
This commit is contained in:
+1
-2
@@ -2573,8 +2573,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "5"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "6"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "7"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "6"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/variables/components/VariableSelectField.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
|
||||
+85
-17
@@ -1,3 +1,4 @@
|
||||
import 'whatwg-fetch';
|
||||
import { advanceTo } from 'jest-date-mock';
|
||||
import { map, of } from 'rxjs';
|
||||
|
||||
@@ -18,6 +19,7 @@ import { getPluginLinkExtensions, setPluginImportUtils } from '@grafana/runtime'
|
||||
import {
|
||||
MultiValueVariable,
|
||||
SceneDataLayers,
|
||||
SceneGridItem,
|
||||
SceneGridItemLike,
|
||||
SceneGridLayout,
|
||||
SceneGridRow,
|
||||
@@ -29,6 +31,7 @@ import { getTimeRange } from 'app/features/dashboard/utils/timeRange';
|
||||
import { reduceTransformRegistryItem } from 'app/features/transformers/editors/ReduceTransformerEditor';
|
||||
import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard';
|
||||
|
||||
import { LibraryVizPanel } from '../scene/LibraryVizPanel';
|
||||
import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior';
|
||||
import { NEW_LINK } from '../settings/links/utils';
|
||||
import { activateFullSceneTree, buildPanelRepeaterScene } from '../utils/test-utils';
|
||||
@@ -315,24 +318,41 @@ describe('transformSceneToSaveModel', () => {
|
||||
|
||||
describe('Library panels', () => {
|
||||
it('given a library panel', () => {
|
||||
const panel = buildGridItemFromPanelSchema({
|
||||
id: 4,
|
||||
gridPos: {
|
||||
h: 8,
|
||||
w: 12,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
libraryPanel: {
|
||||
name: 'Some lib panel panel',
|
||||
uid: 'lib-panel-uid',
|
||||
},
|
||||
// Not using buildGridItemFromPanelSchema since it strips options/fieldConfig
|
||||
const libVizPanel = new LibraryVizPanel({
|
||||
name: 'Some lib panel panel',
|
||||
title: 'A panel',
|
||||
transformations: [],
|
||||
fieldConfig: {
|
||||
defaults: {},
|
||||
overrides: [],
|
||||
},
|
||||
uid: 'lib-panel-uid',
|
||||
panelKey: 'lib-panel',
|
||||
panel: new VizPanel({
|
||||
key: 'panel-4',
|
||||
title: 'Panel blahh blah',
|
||||
fieldConfig: {
|
||||
defaults: {},
|
||||
overrides: [],
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
calcs: [],
|
||||
displayMode: 'list',
|
||||
placement: 'bottom',
|
||||
showLegend: true,
|
||||
},
|
||||
tooltip: {
|
||||
maxHeight: 600,
|
||||
mode: 'single',
|
||||
sort: 'none',
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const panel = new SceneGridItem({
|
||||
body: libVizPanel,
|
||||
y: 0,
|
||||
x: 0,
|
||||
width: 12,
|
||||
height: 8,
|
||||
});
|
||||
|
||||
const result = gridItemToPanel(panel);
|
||||
@@ -351,6 +371,7 @@ describe('transformSceneToSaveModel', () => {
|
||||
expect(result.title).toBe('A panel');
|
||||
expect(result.transformations).toBeUndefined();
|
||||
expect(result.fieldConfig).toBeUndefined();
|
||||
expect(result.options).toBeUndefined();
|
||||
});
|
||||
|
||||
it('given a library panel widget', () => {
|
||||
@@ -769,6 +790,53 @@ describe('transformSceneToSaveModel', () => {
|
||||
expect(result[1].title).toEqual('Panel $server');
|
||||
});
|
||||
|
||||
it('handles repeated library panels', () => {
|
||||
const { scene, repeater } = buildPanelRepeaterScene(
|
||||
{ variableQueryTime: 0, numberOfOptions: 2 },
|
||||
new LibraryVizPanel({
|
||||
name: 'Some lib panel panel',
|
||||
title: 'A panel',
|
||||
uid: 'lib-panel-uid',
|
||||
panelKey: 'lib-panel',
|
||||
panel: new VizPanel({
|
||||
key: 'panel-4',
|
||||
title: 'Panel blahh blah',
|
||||
fieldConfig: {
|
||||
defaults: {},
|
||||
overrides: [],
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
calcs: [],
|
||||
displayMode: 'list',
|
||||
placement: 'bottom',
|
||||
showLegend: true,
|
||||
},
|
||||
tooltip: {
|
||||
maxHeight: 600,
|
||||
mode: 'single',
|
||||
sort: 'none',
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
activateFullSceneTree(scene);
|
||||
const result = panelRepeaterToPanels(repeater, true);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
|
||||
expect(result[0]).toMatchObject({
|
||||
id: 4,
|
||||
title: 'A panel',
|
||||
libraryPanel: {
|
||||
name: 'Some lib panel panel',
|
||||
uid: 'lib-panel-uid',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('handles row repeats ', () => {
|
||||
const { scene, row } = buildPanelRepeaterScene({
|
||||
variableQueryTime: 0,
|
||||
|
||||
@@ -139,6 +139,22 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa
|
||||
return sortedDeepCloneWithoutNulls(dashboard);
|
||||
}
|
||||
|
||||
export function libraryVizPanelToPanel(libPanel: LibraryVizPanel, gridPos: GridPos): Panel {
|
||||
if (!libPanel.state.panel) {
|
||||
throw new Error('Library panel has no panel');
|
||||
}
|
||||
|
||||
return {
|
||||
id: getPanelIdForVizPanel(libPanel.state.panel),
|
||||
title: libPanel.state.title,
|
||||
gridPos: gridPos,
|
||||
libraryPanel: {
|
||||
name: libPanel.state.name,
|
||||
uid: libPanel.state.uid,
|
||||
},
|
||||
} as Panel;
|
||||
}
|
||||
|
||||
export function gridItemToPanel(gridItem: SceneGridItemLike, isSnapshot = false): Panel {
|
||||
let vizPanel: VizPanel | undefined;
|
||||
let x = 0,
|
||||
@@ -154,18 +170,7 @@ export function gridItemToPanel(gridItem: SceneGridItemLike, isSnapshot = false)
|
||||
w = gridItem.state.width ?? 0;
|
||||
h = gridItem.state.height ?? 0;
|
||||
|
||||
if (!gridItem.state.body.state.panel) {
|
||||
throw new Error('Library panel has no panel');
|
||||
}
|
||||
return {
|
||||
id: getPanelIdForVizPanel(gridItem.state.body.state.panel),
|
||||
title: gridItem.state.body.state.title,
|
||||
gridPos: { x, y, w, h },
|
||||
libraryPanel: {
|
||||
name: gridItem.state.body.state.name,
|
||||
uid: gridItem.state.body.state.uid,
|
||||
},
|
||||
} as Panel;
|
||||
return libraryVizPanelToPanel(gridItem.state.body, { x, y, w, h });
|
||||
}
|
||||
|
||||
// Handle library panel widget as well and exit early
|
||||
@@ -194,16 +199,16 @@ export function gridItemToPanel(gridItem: SceneGridItemLike, isSnapshot = false)
|
||||
}
|
||||
|
||||
if (gridItem instanceof PanelRepeaterGridItem) {
|
||||
if (gridItem.state.source instanceof LibraryVizPanel) {
|
||||
vizPanel = gridItem.state.source.state.panel;
|
||||
} else {
|
||||
vizPanel = gridItem.state.source;
|
||||
}
|
||||
|
||||
x = gridItem.state.x ?? 0;
|
||||
y = gridItem.state.y ?? 0;
|
||||
w = gridItem.state.width ?? 0;
|
||||
h = gridItem.state.height ?? 0;
|
||||
|
||||
if (gridItem.state.source instanceof LibraryVizPanel) {
|
||||
return libraryVizPanelToPanel(gridItem.state.source, { x, y, w, h });
|
||||
} else {
|
||||
vizPanel = gridItem.state.source;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vizPanel) {
|
||||
@@ -323,18 +328,7 @@ export function panelRepeaterToPanels(repeater: PanelRepeaterGridItem, isSnapsho
|
||||
} else {
|
||||
if (repeater.state.source instanceof LibraryVizPanel) {
|
||||
const { x = 0, y = 0, width: w = 0, height: h = 0 } = repeater.state;
|
||||
|
||||
return [
|
||||
{
|
||||
id: getPanelIdForVizPanel(repeater.state.source),
|
||||
title: repeater.state.source.state.title,
|
||||
gridPos: { x, y, w, h },
|
||||
libraryPanel: {
|
||||
name: repeater.state.source.state.name,
|
||||
uid: repeater.state.source.state.uid,
|
||||
},
|
||||
} as Panel,
|
||||
];
|
||||
return [libraryVizPanelToPanel(repeater.state.source, { x, y, w, h })];
|
||||
}
|
||||
|
||||
if (repeater.state.repeatedPanels) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { DashboardLoaderSrv, setDashboardLoaderSrv } from 'app/features/dashboar
|
||||
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from 'app/features/variables/constants';
|
||||
import { DashboardDTO } from 'app/types';
|
||||
|
||||
import { LibraryVizPanel } from '../scene/LibraryVizPanel';
|
||||
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
|
||||
import { PanelRepeaterGridItem, RepeatDirection } from '../scene/PanelRepeaterGridItem';
|
||||
import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior';
|
||||
@@ -99,7 +100,7 @@ interface SceneOptions {
|
||||
useRowRepeater?: boolean;
|
||||
}
|
||||
|
||||
export function buildPanelRepeaterScene(options: SceneOptions) {
|
||||
export function buildPanelRepeaterScene(options: SceneOptions, source?: VizPanel | LibraryVizPanel) {
|
||||
const defaults = { usePanelRepeater: true, ...options };
|
||||
|
||||
const repeater = new PanelRepeaterGridItem({
|
||||
@@ -108,10 +109,12 @@ export function buildPanelRepeaterScene(options: SceneOptions) {
|
||||
repeatDirection: options.repeatDirection,
|
||||
maxPerRow: options.maxPerRow,
|
||||
itemHeight: options.itemHeight,
|
||||
source: new VizPanel({
|
||||
title: 'Panel $server',
|
||||
pluginId: 'timeseries',
|
||||
}),
|
||||
source:
|
||||
source ??
|
||||
new VizPanel({
|
||||
title: 'Panel $server',
|
||||
pluginId: 'timeseries',
|
||||
}),
|
||||
x: options.x || 0,
|
||||
y: options.y || 0,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user