Dashboard Schema v2: Panel links (#97441)

* panel links

* Update transformer scene -> v2; update snapshot

* clean up

* data links test

* Remove type assertion
This commit is contained in:
Haris Rozajac 2024-12-09 08:23:23 -07:00 committed by GitHub
parent fde79020ef
commit c4e19f3570
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 67 additions and 20 deletions

View File

@ -2131,11 +2131,10 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/features/dashboard-scene/settings/DeleteDashboardButton.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
@ -2280,7 +2279,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard-scene/v2schema/test-helpers.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/features/dashboard/api/dashboard_api.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]

View File

@ -145,6 +145,17 @@ export const defaultDataTransformerConfig = (): DataTransformerConfig => ({
options: {},
});
export interface DataLink {
title: string;
url: string;
targetBlank?: boolean;
}
export const defaultDataLink = (): DataLink => ({
title: "",
url: "",
});
// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
// Each column within this structure is called a field. A field can represent a single time series or table column.
// Field options allow you to change how the data is displayed in your visualizations.
@ -686,7 +697,7 @@ export interface PanelSpec {
uid: string;
title: string;
description: string;
links: DashboardLink[];
links: DataLink[];
data: QueryGroupKind;
vizConfig: VizConfigKind;
}

View File

@ -123,6 +123,12 @@ DataTransformerConfig: {
options: _
}
DataLink: {
title: string
url: string
targetBlank?: bool
}
// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
// Each column within this structure is called a field. A field can represent a single time series or table column.
// Field options allow you to change how the data is displayed in your visualizations.
@ -476,7 +482,7 @@ PanelSpec: {
uid: string
title: string
description: string
links: [...DashboardLink]
links: [...DataLink]
data: QueryGroupKind
vizConfig: VizConfigKind
}

View File

@ -163,7 +163,10 @@ export const handyTestingSchema: DashboardV2Spec = {
},
},
description: 'Test Description',
links: [],
links: [
{ title: 'Test Link 1', url: 'http://test1.com', targetBlank: true },
{ title: 'Test Link 2', url: 'http://test2.com' },
],
title: 'Test Panel',
uid: 'test-panel-uid',
vizConfig: {

View File

@ -98,7 +98,17 @@ exports[`transformSceneToSaveModelSchemaV2 should transform scene to save model
},
},
"description": "Test Description",
"links": [],
"links": [
{
"targetBlank": true,
"title": "Test Link 1",
"url": "http://test1.com",
},
{
"title": "Test Link 2",
"url": "http://test2.com",
},
],
"title": "Test Panel",
"uid": "test-panel-uid",
"vizConfig": {

View File

@ -63,7 +63,8 @@ import { registerDashboardMacro } from '../scene/DashboardMacro';
import { DashboardReloadBehavior } from '../scene/DashboardReloadBehavior';
import { DashboardScene } from '../scene/DashboardScene';
import { DashboardScopesFacade } from '../scene/DashboardScopesFacade';
import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
import { panelLinksBehavior, panelMenuBehavior } from '../scene/PanelMenuBehavior';
import { PanelNotices } from '../scene/PanelNotices';
import { PanelTimeRange } from '../scene/PanelTimeRange';
import { AngularDeprecation } from '../scene/angular/AngularDeprecation';
@ -217,13 +218,12 @@ function buildVizPanel(panel: PanelKind): VizPanel {
titleItems.push(new AngularDeprecation());
}
// FIXME: Links in a panel are DashboardLinks not DataLinks
// titleItems.push(
// new VizPanelLinks({
// rawLinks: panel.spec.links,
// menu: new VizPanelLinksMenu({ $behaviors: [panelLinksBehavior] }),
// })
// );
titleItems.push(
new VizPanelLinks({
rawLinks: panel.spec.links,
menu: new VizPanelLinksMenu({ $behaviors: [panelLinksBehavior] }),
})
);
titleItems.push(new PanelNotices());

View File

@ -28,6 +28,7 @@ import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsData
import { DashboardControls } from '../scene/DashboardControls';
import { DashboardDataLayerSet } from '../scene/DashboardDataLayerSet';
import { DashboardScene, DashboardSceneState } from '../scene/DashboardScene';
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem';
import { DefaultGridLayoutManager } from '../scene/layout-default/DefaultGridLayoutManager';
@ -142,6 +143,15 @@ describe('transformSceneToSaveModelSchemaV2', () => {
key: 'test-panel-uid',
pluginId: 'timeseries',
title: 'Test Panel',
titleItems: [
new VizPanelLinks({
rawLinks: [
{ title: 'Test Link 1', url: 'http://test1.com', targetBlank: true },
{ title: 'Test Link 2', url: 'http://test2.com' },
],
menu: new VizPanelLinksMenu({}),
}),
],
description: 'Test Description',
hoverHeader: true,
hoverHeaderOffset: 10,

View File

@ -21,7 +21,6 @@ import {
PanelQueryKind,
TransformationKind,
FieldConfigSource,
DashboardLink,
DataTransformerConfig,
PanelQuerySpec,
DataQueryKind,
@ -38,6 +37,7 @@ import {
AnnotationQueryKind,
defaultAnnotationPanelFilter,
defaultAnnotationQuerySpec,
DataLink,
} from '../../../../../packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen';
import { DashboardDataLayerSet } from '../scene/DashboardDataLayerSet';
import { DashboardScene, DashboardSceneState } from '../scene/DashboardScene';
@ -245,10 +245,10 @@ function getElements(state: DashboardSceneState) {
return elements;
}
function getPanelLinks(panel: VizPanel): DashboardLink[] {
function getPanelLinks(panel: VizPanel): DataLink[] {
const vizLinks = dashboardSceneGraph.getPanelLinks(panel);
if (vizLinks) {
return (vizLinks.state.rawLinks as DashboardLink[]) ?? [];
return vizLinks.state.rawLinks ?? [];
}
return [];
}

View File

@ -4,6 +4,7 @@ import {
GroupByVariable,
QueryVariable,
SceneDataTransformer,
SceneObject,
SceneQueryRunner,
SceneVariable,
SceneVariableState,
@ -12,6 +13,7 @@ import {
import { DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0/dashboard.gen';
import { DashboardScene } from '../scene/DashboardScene';
import { VizPanelLinks } from '../scene/PanelLinks';
import { TypedVariableModelV2 } from '../serialization/transformSaveModelSchemaV2ToScene';
import { getQueryRunnerFor } from '../utils/utils';
@ -82,6 +84,10 @@ export function validateVizPanel(vizPanel: VizPanel, dash: DashboardV2Spec) {
expect(queryRunner.state.cacheTimeout).toBe('1m');
expect(queryRunner.state.queryCachingTTL).toBe(60);
expect(queryRunner.state.minInterval).toBe('1m');
const titleItems = vizPanel.state.titleItems as SceneObject[];
const vizPanelLinks = titleItems[0] as VizPanelLinks;
expect(vizPanelLinks.state.rawLinks).toHaveLength(dash.elements['test-panel-uid'].spec.links.length);
expect(vizPanelLinks.state.rawLinks).toEqual(dash.elements['test-panel-uid'].spec.links);
// FIXME: This is asking for a number as panel ID but here the uid of a panel is string
// will be fixed once scenes package is updated to support string panel ID
// expect(queryRunner.state.dataLayerFilter?.panelId).toBe(0);