LibraryPanel: Use id and title from panel model (#99281)

pull/99442/head
Ivan Ortega Alba 11 months ago committed by GitHub
parent 750027d0a7
commit 83bbdbf8b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue
  2. 12
      packages/grafana-schema/src/schema/dashboard/v2alpha0/examples.ts
  3. 21
      packages/grafana-schema/src/schema/dashboard/v2alpha0/types.gen.ts
  4. 6
      public/app/features/dashboard-scene/serialization/transformSaveModelSchemaV2ToScene.test.ts
  5. 13
      public/app/features/dashboard-scene/serialization/transformSaveModelSchemaV2ToScene.ts
  6. 20
      public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts
  7. 7
      public/app/features/dashboard-scene/v2schema/test-helpers.ts
  8. 18
      public/app/features/dashboard/api/ResponseTransformers.test.ts
  9. 22
      public/app/features/dashboard/api/ResponseTransformers.ts

@ -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 {
// Panel ID for the library panel in the dashboard
id: number;
// Title for the library panel in the dashboard
title: string;
libraryPanel: LibraryPanelRef;
}
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 // Library panel name
name: string; name: string;
// Library panel UID // Library panel uid
uid: string; uid: string;
} }
export const defaultLibraryPanelSpec = (): LibraryPanelSpec => ({ export const defaultLibraryPanelRef = (): LibraryPanelRef => ({
name: "", name: "",
uid: "", uid: "",
}); });

@ -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

@ -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: {},

@ -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 {

Loading…
Cancel
Save