LibraryPanel: Use id and title from panel model (#99281)
This commit is contained in:
@@ -64,9 +64,21 @@ LibraryPanelKind: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LibraryPanelSpec: {
|
LibraryPanelSpec: {
|
||||||
|
// Panel ID for the library panel in the dashboard
|
||||||
|
id: number
|
||||||
|
// Title for the library panel in the dashboard
|
||||||
|
title: string
|
||||||
|
|
||||||
|
libraryPanel: LibraryPanelRef
|
||||||
|
}
|
||||||
|
|
||||||
|
// A library panel is a reusable panel that you can use in any dashboard.
|
||||||
|
// When you make a change to a library panel, that change propagates to all instances of where the panel is used.
|
||||||
|
// Library panels streamline reuse of panels across multiple dashboards.
|
||||||
|
LibraryPanelRef: {
|
||||||
// Library panel name
|
// Library panel name
|
||||||
name: string
|
name: string
|
||||||
// Library panel UID
|
// Library panel uid
|
||||||
uid: string
|
uid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,11 +181,15 @@ export const handyTestingSchema: DashboardV2Spec = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'library-panel-1': {
|
'panel-2': {
|
||||||
kind: 'LibraryPanel',
|
kind: 'LibraryPanel',
|
||||||
spec: {
|
spec: {
|
||||||
uid: 'library-panel-1',
|
id: 2,
|
||||||
name: 'Library Panel',
|
title: 'Test Library Panel',
|
||||||
|
libraryPanel: {
|
||||||
|
uid: 'uid-for-library-panel',
|
||||||
|
name: 'Library Panel',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -216,7 +220,7 @@ export const handyTestingSchema: DashboardV2Spec = {
|
|||||||
spec: {
|
spec: {
|
||||||
element: {
|
element: {
|
||||||
kind: 'ElementReference',
|
kind: 'ElementReference',
|
||||||
name: 'library-panel-1',
|
name: 'panel-2',
|
||||||
},
|
},
|
||||||
height: 100,
|
height: 100,
|
||||||
width: 200,
|
width: 200,
|
||||||
|
|||||||
@@ -70,13 +70,30 @@ export const defaultLibraryPanelKind = (): LibraryPanelKind => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export interface LibraryPanelSpec {
|
export interface LibraryPanelSpec {
|
||||||
// Library panel name
|
// Panel ID for the library panel in the dashboard
|
||||||
name: string;
|
id: number;
|
||||||
// Library panel UID
|
// Title for the library panel in the dashboard
|
||||||
uid: string;
|
title: string;
|
||||||
|
libraryPanel: LibraryPanelRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultLibraryPanelSpec = (): LibraryPanelSpec => ({
|
export const defaultLibraryPanelSpec = (): LibraryPanelSpec => ({
|
||||||
|
id: 0,
|
||||||
|
title: "",
|
||||||
|
libraryPanel: defaultLibraryPanelRef(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// A library panel is a reusable panel that you can use in any dashboard.
|
||||||
|
// When you make a change to a library panel, that change propagates to all instances of where the panel is used.
|
||||||
|
// Library panels streamline reuse of panels across multiple dashboards.
|
||||||
|
export interface LibraryPanelRef {
|
||||||
|
// Library panel name
|
||||||
|
name: string;
|
||||||
|
// Library panel uid
|
||||||
|
uid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultLibraryPanelRef = (): LibraryPanelRef => ({
|
||||||
name: "",
|
name: "",
|
||||||
uid: "",
|
uid: "",
|
||||||
});
|
});
|
||||||
|
|||||||
+3
-3
@@ -239,14 +239,14 @@ describe('transformSaveModelSchemaV2ToScene', () => {
|
|||||||
validateVizPanel(vizPanel, dash);
|
validateVizPanel(vizPanel, dash);
|
||||||
|
|
||||||
// Library Panel
|
// Library Panel
|
||||||
const libraryPanel = getLibraryPanelElement(dash, 'library-panel-1')!;
|
const libraryPanel = getLibraryPanelElement(dash, 'panel-2')!;
|
||||||
expect(layout.state.grid.state.children[1].state.key).toBe(`grid-item-${libraryPanel.spec.uid}`);
|
expect(layout.state.grid.state.children[1].state.key).toBe(`grid-item-${libraryPanel.spec.id}`);
|
||||||
const libraryGridLayoutItemSpec = dash.layout.spec.items[1].spec;
|
const libraryGridLayoutItemSpec = dash.layout.spec.items[1].spec;
|
||||||
expect(layout.state.grid.state.children[1].state.width).toBe(libraryGridLayoutItemSpec.width);
|
expect(layout.state.grid.state.children[1].state.width).toBe(libraryGridLayoutItemSpec.width);
|
||||||
expect(layout.state.grid.state.children[1].state.height).toBe(libraryGridLayoutItemSpec.height);
|
expect(layout.state.grid.state.children[1].state.height).toBe(libraryGridLayoutItemSpec.height);
|
||||||
expect(layout.state.grid.state.children[1].state.x).toBe(libraryGridLayoutItemSpec.x);
|
expect(layout.state.grid.state.children[1].state.x).toBe(libraryGridLayoutItemSpec.x);
|
||||||
expect(layout.state.grid.state.children[1].state.y).toBe(libraryGridLayoutItemSpec.y);
|
expect(layout.state.grid.state.children[1].state.y).toBe(libraryGridLayoutItemSpec.y);
|
||||||
const vizLibraryPanel = vizPanels.find((p) => p.state.key === 'library-panel-1')!;
|
const vizLibraryPanel = vizPanels.find((p) => p.state.key === 'panel-2')!;
|
||||||
validateVizPanel(vizLibraryPanel, dash);
|
validateVizPanel(vizLibraryPanel, dash);
|
||||||
|
|
||||||
// Transformations
|
// Transformations
|
||||||
|
|||||||
+9
-4
@@ -259,7 +259,7 @@ function createSceneGridLayoutForItems(dashboard: DashboardV2Spec): SceneGridIte
|
|||||||
const libraryPanel = buildLibraryPanel(panel);
|
const libraryPanel = buildLibraryPanel(panel);
|
||||||
|
|
||||||
return new DashboardGridItem({
|
return new DashboardGridItem({
|
||||||
key: `grid-item-${panel.spec.uid}`,
|
key: `grid-item-${panel.spec.id}`,
|
||||||
x: element.spec.x,
|
x: element.spec.x,
|
||||||
y: element.spec.y,
|
y: element.spec.y,
|
||||||
width: element.spec.width,
|
width: element.spec.width,
|
||||||
@@ -293,12 +293,17 @@ function buildLibraryPanel(panel: LibraryPanelKind): VizPanel {
|
|||||||
titleItems.push(new PanelNotices());
|
titleItems.push(new PanelNotices());
|
||||||
|
|
||||||
const vizPanelState: VizPanelState = {
|
const vizPanelState: VizPanelState = {
|
||||||
key: panel.spec.uid,
|
key: getVizPanelKeyForPanelId(panel.spec.id),
|
||||||
titleItems,
|
titleItems,
|
||||||
$behaviors: [new LibraryPanelBehavior({ uid: panel.spec.uid, name: panel.spec.name })],
|
$behaviors: [
|
||||||
|
new LibraryPanelBehavior({
|
||||||
|
uid: panel.spec.libraryPanel.uid,
|
||||||
|
name: panel.spec.libraryPanel.name,
|
||||||
|
}),
|
||||||
|
],
|
||||||
extendPanelContext: setDashboardPanelContext,
|
extendPanelContext: setDashboardPanelContext,
|
||||||
pluginId: LibraryPanelBehavior.LOADING_VIZ_PANEL_PLUGIN_ID,
|
pluginId: LibraryPanelBehavior.LOADING_VIZ_PANEL_PLUGIN_ID,
|
||||||
title: '',
|
title: panel.spec.title,
|
||||||
options: {},
|
options: {},
|
||||||
fieldConfig: {
|
fieldConfig: {
|
||||||
defaults: {},
|
defaults: {},
|
||||||
|
|||||||
+10
-10
@@ -248,8 +248,12 @@ function getElements(state: DashboardSceneState) {
|
|||||||
const elementSpec: LibraryPanelKind = {
|
const elementSpec: LibraryPanelKind = {
|
||||||
kind: 'LibraryPanel',
|
kind: 'LibraryPanel',
|
||||||
spec: {
|
spec: {
|
||||||
name: behavior.state.name,
|
id: getPanelIdForVizPanel(vizPanel),
|
||||||
uid: behavior.state.uid,
|
title: vizPanel.state.title,
|
||||||
|
libraryPanel: {
|
||||||
|
uid: behavior.state.uid,
|
||||||
|
name: behavior.state.name,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return elementSpec;
|
return elementSpec;
|
||||||
@@ -432,14 +436,10 @@ function getVizPanelQueryOptions(vizPanel: VizPanel): QueryOptionsSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createElements(panels: Element[]): Record<string, Element> {
|
function createElements(panels: Element[]): Record<string, Element> {
|
||||||
const elements: Record<string, Element> = {};
|
return panels.reduce<Record<string, Element>>((elements, panel) => {
|
||||||
|
elements[getVizPanelKeyForPanelId(panel.spec.id)] = panel;
|
||||||
for (const panel of panels) {
|
return elements;
|
||||||
const key = panel.kind === 'Panel' ? getVizPanelKeyForPanelId(panel.spec.id) : panel.spec.uid;
|
}, {});
|
||||||
elements[key] = panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elements;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function repeaterToLayoutItems(repeater: DashboardGridItem, isSnapshot = false): GridLayoutItemKind[] {
|
function repeaterToLayoutItems(repeater: DashboardGridItem, isSnapshot = false): GridLayoutItemKind[] {
|
||||||
|
|||||||
@@ -94,9 +94,10 @@ export function validateVizPanel(vizPanel: VizPanel, dash: DashboardV2Spec) {
|
|||||||
expect(vizPanelLinks.state.rawLinks).toEqual(panel.spec.links);
|
expect(vizPanelLinks.state.rawLinks).toEqual(panel.spec.links);
|
||||||
expect(queryRunner.state.dataLayerFilter?.panelId).toBe(panel.spec.id);
|
expect(queryRunner.state.dataLayerFilter?.panelId).toBe(panel.spec.id);
|
||||||
} else if (panel.kind === 'LibraryPanel') {
|
} else if (panel.kind === 'LibraryPanel') {
|
||||||
expect(getLibraryPanelBehavior(vizPanel)?.state.name).toBe(panel.spec.name);
|
expect(getLibraryPanelBehavior(vizPanel)?.state.name).toBe(panel.spec.libraryPanel.name);
|
||||||
expect(getLibraryPanelBehavior(vizPanel)?.state.uid).toBe(panel.spec.uid);
|
expect(getLibraryPanelBehavior(vizPanel)?.state.uid).toBe(panel.spec.libraryPanel.uid);
|
||||||
|
expect(getPanelIdForVizPanel(vizPanel)).toBe(panel.spec.id);
|
||||||
|
expect(vizPanel.state.title).toBe(panel.spec.title);
|
||||||
expect(vizPanel.state.pluginId).toBe(LibraryPanelBehavior.LOADING_VIZ_PANEL_PLUGIN_ID);
|
expect(vizPanel.state.pluginId).toBe(LibraryPanelBehavior.LOADING_VIZ_PANEL_PLUGIN_ID);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('vizPanel is not a valid element kind');
|
throw new Error('vizPanel is not a valid element kind');
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ describe('ResponseTransformers', () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
type: 'table',
|
type: 'table',
|
||||||
|
title: 'Just a shared table',
|
||||||
libraryPanel: {
|
libraryPanel: {
|
||||||
uid: 'library-panel-table',
|
uid: 'library-panel-table',
|
||||||
name: 'Table Panel as Library Panel',
|
name: 'Table Panel as Library Panel',
|
||||||
@@ -458,18 +459,22 @@ describe('ResponseTransformers', () => {
|
|||||||
expect(spec.layout.spec.items[1].spec).toEqual({
|
expect(spec.layout.spec.items[1].spec).toEqual({
|
||||||
element: {
|
element: {
|
||||||
kind: 'ElementReference',
|
kind: 'ElementReference',
|
||||||
name: 'library-panel-table',
|
name: '2',
|
||||||
},
|
},
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 8,
|
y: 8,
|
||||||
width: 12,
|
width: 12,
|
||||||
height: 8,
|
height: 8,
|
||||||
});
|
});
|
||||||
expect(spec.elements['library-panel-table']).toEqual({
|
expect(spec.elements['2']).toEqual({
|
||||||
kind: 'LibraryPanel',
|
kind: 'LibraryPanel',
|
||||||
spec: {
|
spec: {
|
||||||
uid: 'library-panel-table',
|
libraryPanel: {
|
||||||
name: 'Table Panel as Library Panel',
|
uid: 'library-panel-table',
|
||||||
|
name: 'Table Panel as Library Panel',
|
||||||
|
},
|
||||||
|
id: 2,
|
||||||
|
title: 'Just a shared table',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -633,7 +638,10 @@ describe('ResponseTransformers', () => {
|
|||||||
expect(panelV2.kind).toBe('Panel');
|
expect(panelV2.kind).toBe('Panel');
|
||||||
validatePanel(dashboard.panels![0], panelV2, dashboardV2.spec.layout, panelKey);
|
validatePanel(dashboard.panels![0], panelV2, dashboardV2.spec.layout, panelKey);
|
||||||
// library panel
|
// library panel
|
||||||
expect(dashboard.panels![1].libraryPanel).toEqual(dashboardV2.spec.elements['library-panel-1'].spec);
|
expect(dashboard.panels![1].libraryPanel).toEqual({
|
||||||
|
uid: 'uid-for-library-panel',
|
||||||
|
name: 'Library Panel',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPanelQueries', () => {
|
describe('getPanelQueries', () => {
|
||||||
|
|||||||
@@ -278,23 +278,23 @@ function getElementsFromPanels(panels: Panel[]): [DashboardV2Spec['elements'], D
|
|||||||
|
|
||||||
// iterate over panels
|
// iterate over panels
|
||||||
for (const p of panels) {
|
for (const p of panels) {
|
||||||
let elementName;
|
const elementName = p.id!.toString();
|
||||||
|
|
||||||
// LibraryPanelKind
|
// LibraryPanelKind
|
||||||
if (p.libraryPanel) {
|
if (p.libraryPanel) {
|
||||||
elementName = p.libraryPanel.uid;
|
|
||||||
|
|
||||||
elements[elementName] = {
|
elements[elementName] = {
|
||||||
kind: 'LibraryPanel',
|
kind: 'LibraryPanel',
|
||||||
spec: {
|
spec: {
|
||||||
uid: p.libraryPanel.uid,
|
libraryPanel: {
|
||||||
name: p.libraryPanel.name,
|
uid: p.libraryPanel.uid,
|
||||||
|
name: p.libraryPanel.name,
|
||||||
|
},
|
||||||
|
id: p.id!,
|
||||||
|
title: p.title ?? '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// PanelKind
|
// PanelKind
|
||||||
} else {
|
} else {
|
||||||
elementName = p.id!.toString();
|
|
||||||
|
|
||||||
// FIXME: for now we should skip row panels
|
// FIXME: for now we should skip row panels
|
||||||
if (p.type === 'row') {
|
if (p.type === 'row') {
|
||||||
continue;
|
continue;
|
||||||
@@ -826,12 +826,12 @@ function getPanelsV1(
|
|||||||
} else if (p.kind === 'LibraryPanel') {
|
} else if (p.kind === 'LibraryPanel') {
|
||||||
const panel = p.spec;
|
const panel = p.spec;
|
||||||
return {
|
return {
|
||||||
id: 0, //TODO: LibraryPanelSpec.id will be available after https://github.com/grafana/grafana/pull/99281/ is merged
|
id: panel.id,
|
||||||
title: panel.name,
|
title: panel.title,
|
||||||
gridPos,
|
gridPos,
|
||||||
libraryPanel: {
|
libraryPanel: {
|
||||||
uid: panel.uid,
|
uid: panel.libraryPanel.uid,
|
||||||
name: panel.name,
|
name: panel.libraryPanel.name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user