mirror of https://github.com/grafana/grafana.git
Dashboard: Schema V2 - Fix built-in annotations not present (#104313)
* Add grafana Built-in annonation to the serialization
* Add unit tests
(cherry picked from commit ab7e18feda
)
This commit is contained in:
parent
5631d9aace
commit
3c62214699
|
@ -15,6 +15,7 @@ import {
|
||||||
GridLayoutKind,
|
GridLayoutKind,
|
||||||
PanelSpec,
|
PanelSpec,
|
||||||
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
|
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
|
||||||
|
import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui';
|
||||||
import { AnnoKeyDashboardSnapshotOriginalUrl } from 'app/features/apiserver/types';
|
import { AnnoKeyDashboardSnapshotOriginalUrl } from 'app/features/apiserver/types';
|
||||||
import { SaveDashboardAsOptions } from 'app/features/dashboard/components/SaveDashboard/types';
|
import { SaveDashboardAsOptions } from 'app/features/dashboard/components/SaveDashboard/types';
|
||||||
import { DASHBOARD_SCHEMA_VERSION } from 'app/features/dashboard/state/DashboardMigrator';
|
import { DASHBOARD_SCHEMA_VERSION } from 'app/features/dashboard/state/DashboardMigrator';
|
||||||
|
@ -715,7 +716,22 @@ describe('DashboardSceneSerializer', () => {
|
||||||
title: baseOptions.title,
|
title: baseOptions.title,
|
||||||
description: baseOptions.description,
|
description: baseOptions.description,
|
||||||
editable: true,
|
editable: true,
|
||||||
annotations: [],
|
annotations: [
|
||||||
|
{
|
||||||
|
kind: 'AnnotationQuery',
|
||||||
|
spec: {
|
||||||
|
builtIn: true,
|
||||||
|
name: 'Annotations & Alerts',
|
||||||
|
datasource: {
|
||||||
|
uid: '-- Grafana --',
|
||||||
|
type: 'grafana',
|
||||||
|
},
|
||||||
|
enable: true,
|
||||||
|
hide: true,
|
||||||
|
iconColor: DEFAULT_ANNOTATION_COLOR,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
cursorSync: 'Off',
|
cursorSync: 'Off',
|
||||||
liveNow: false,
|
liveNow: false,
|
||||||
preload: false,
|
preload: false,
|
||||||
|
|
|
@ -206,26 +206,36 @@ describe('transformSaveModelSchemaV2ToScene', () => {
|
||||||
// Annotations
|
// Annotations
|
||||||
expect(scene.state.$data).toBeInstanceOf(DashboardDataLayerSet);
|
expect(scene.state.$data).toBeInstanceOf(DashboardDataLayerSet);
|
||||||
const dataLayers = scene.state.$data as DashboardDataLayerSet;
|
const dataLayers = scene.state.$data as DashboardDataLayerSet;
|
||||||
|
// we should get two annotations, Grafana built-in and the custom ones
|
||||||
expect(dataLayers.state.annotationLayers).toHaveLength(dash.annotations.length);
|
expect(dataLayers.state.annotationLayers).toHaveLength(dash.annotations.length);
|
||||||
expect(dataLayers.state.annotationLayers[0].state.name).toBe(dash.annotations[0].spec.name);
|
expect(dataLayers.state.annotationLayers).toHaveLength(5);
|
||||||
expect(dataLayers.state.annotationLayers[0].state.isEnabled).toBe(dash.annotations[0].spec.enable);
|
|
||||||
expect(dataLayers.state.annotationLayers[0].state.isHidden).toBe(dash.annotations[0].spec.hide);
|
// Built-in
|
||||||
|
const builtInAnnotation = dataLayers.state.annotationLayers[0] as unknown as DashboardAnnotationsDataLayer;
|
||||||
|
expect(builtInAnnotation.state.name).toBe('Annotations & Alerts');
|
||||||
|
expect(builtInAnnotation.state.isEnabled).toBe(true);
|
||||||
|
expect(builtInAnnotation.state.isHidden).toBe(true);
|
||||||
|
expect(builtInAnnotation.state?.query.builtIn).toBe(1);
|
||||||
|
|
||||||
// Enabled
|
// Enabled
|
||||||
expect(dataLayers.state.annotationLayers[1].state.name).toBe(dash.annotations[1].spec.name);
|
expect(dataLayers.state.annotationLayers[1].state.name).toBe(dash.annotations[1].spec.name);
|
||||||
expect(dataLayers.state.annotationLayers[1].state.isEnabled).toBe(dash.annotations[1].spec.enable);
|
expect(dataLayers.state.annotationLayers[1].state.isEnabled).toBe(dash.annotations[1].spec.enable);
|
||||||
expect(dataLayers.state.annotationLayers[1].state.isHidden).toBe(dash.annotations[1].spec.hide);
|
expect(dataLayers.state.annotationLayers[1].state.isHidden).toBe(dash.annotations[1].spec.hide);
|
||||||
|
|
||||||
// Disabled
|
|
||||||
expect(dataLayers.state.annotationLayers[2].state.name).toBe(dash.annotations[2].spec.name);
|
expect(dataLayers.state.annotationLayers[2].state.name).toBe(dash.annotations[2].spec.name);
|
||||||
expect(dataLayers.state.annotationLayers[2].state.isEnabled).toBe(dash.annotations[2].spec.enable);
|
expect(dataLayers.state.annotationLayers[2].state.isEnabled).toBe(dash.annotations[2].spec.enable);
|
||||||
expect(dataLayers.state.annotationLayers[2].state.isHidden).toBe(dash.annotations[2].spec.hide);
|
expect(dataLayers.state.annotationLayers[2].state.isHidden).toBe(dash.annotations[2].spec.hide);
|
||||||
|
|
||||||
// Hidden
|
// Disabled
|
||||||
expect(dataLayers.state.annotationLayers[3].state.name).toBe(dash.annotations[3].spec.name);
|
expect(dataLayers.state.annotationLayers[3].state.name).toBe(dash.annotations[3].spec.name);
|
||||||
expect(dataLayers.state.annotationLayers[3].state.isEnabled).toBe(dash.annotations[3].spec.enable);
|
expect(dataLayers.state.annotationLayers[3].state.isEnabled).toBe(dash.annotations[3].spec.enable);
|
||||||
expect(dataLayers.state.annotationLayers[3].state.isHidden).toBe(dash.annotations[3].spec.hide);
|
expect(dataLayers.state.annotationLayers[3].state.isHidden).toBe(dash.annotations[3].spec.hide);
|
||||||
|
|
||||||
|
// Hidden
|
||||||
|
expect(dataLayers.state.annotationLayers[4].state.name).toBe(dash.annotations[4].spec.name);
|
||||||
|
expect(dataLayers.state.annotationLayers[4].state.isEnabled).toBe(dash.annotations[4].spec.enable);
|
||||||
|
expect(dataLayers.state.annotationLayers[4].state.isHidden).toBe(dash.annotations[4].spec.hide);
|
||||||
|
|
||||||
// VizPanel
|
// VizPanel
|
||||||
const vizPanels = (scene.state.body as DashboardLayoutManager).getVizPanels();
|
const vizPanels = (scene.state.body as DashboardLayoutManager).getVizPanels();
|
||||||
expect(vizPanels).toHaveLength(3);
|
expect(vizPanels).toHaveLength(3);
|
||||||
|
@ -757,9 +767,10 @@ describe('transformSaveModelSchemaV2ToScene', () => {
|
||||||
// Get the annotation layers
|
// Get the annotation layers
|
||||||
const dataLayerSet = scene.state.$data as DashboardDataLayerSet;
|
const dataLayerSet = scene.state.$data as DashboardDataLayerSet;
|
||||||
expect(dataLayerSet).toBeDefined();
|
expect(dataLayerSet).toBeDefined();
|
||||||
expect(dataLayerSet.state.annotationLayers.length).toBe(1);
|
// it should have two annotation layers, built-in and custom
|
||||||
|
expect(dataLayerSet.state.annotationLayers.length).toBe(2);
|
||||||
|
|
||||||
const annotationLayer = dataLayerSet.state.annotationLayers[0] as DashboardAnnotationsDataLayer;
|
const annotationLayer = dataLayerSet.state.annotationLayers[1] as DashboardAnnotationsDataLayer;
|
||||||
|
|
||||||
// Verify that the options have been merged into the query object
|
// Verify that the options have been merged into the query object
|
||||||
expect(annotationLayer.state.query).toMatchObject({
|
expect(annotationLayer.state.query).toMatchObject({
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import {
|
import {
|
||||||
AdhocVariableKind,
|
AdhocVariableKind,
|
||||||
|
AnnotationQueryKind,
|
||||||
ConstantVariableKind,
|
ConstantVariableKind,
|
||||||
CustomVariableKind,
|
CustomVariableKind,
|
||||||
Spec as DashboardV2Spec,
|
Spec as DashboardV2Spec,
|
||||||
|
@ -38,6 +39,7 @@ import {
|
||||||
QueryVariableKind,
|
QueryVariableKind,
|
||||||
TextVariableKind,
|
TextVariableKind,
|
||||||
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
|
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
|
||||||
|
import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui';
|
||||||
import {
|
import {
|
||||||
AnnoKeyCreatedBy,
|
AnnoKeyCreatedBy,
|
||||||
AnnoKeyFolder,
|
AnnoKeyFolder,
|
||||||
|
@ -87,6 +89,13 @@ export type TypedVariableModelV2 =
|
||||||
export function transformSaveModelSchemaV2ToScene(dto: DashboardWithAccessInfo<DashboardV2Spec>): DashboardScene {
|
export function transformSaveModelSchemaV2ToScene(dto: DashboardWithAccessInfo<DashboardV2Spec>): DashboardScene {
|
||||||
const { spec: dashboard, metadata } = dto;
|
const { spec: dashboard, metadata } = dto;
|
||||||
|
|
||||||
|
// annotations might not come with the builtIn Grafana annotation, we need to add it
|
||||||
|
|
||||||
|
const grafanaBuiltAnnotation = getGrafanaBuiltInAnnotationDataLayer(dashboard);
|
||||||
|
if (grafanaBuiltAnnotation) {
|
||||||
|
dashboard.annotations.unshift(grafanaBuiltAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
const annotationLayers = dashboard.annotations.map((annotation) => {
|
const annotationLayers = dashboard.annotations.map((annotation) => {
|
||||||
let annoQuerySpec = annotation.spec;
|
let annoQuerySpec = annotation.spec;
|
||||||
// some annotations will contain in the options properties that need to be
|
// some annotations will contain in the options properties that need to be
|
||||||
|
@ -500,3 +509,23 @@ export function getPanelElement(dashboard: DashboardV2Spec, elementName: string)
|
||||||
export function getLibraryPanelElement(dashboard: DashboardV2Spec, elementName: string): LibraryPanelKind | undefined {
|
export function getLibraryPanelElement(dashboard: DashboardV2Spec, elementName: string): LibraryPanelKind | undefined {
|
||||||
return dashboard.elements[elementName].kind === 'LibraryPanel' ? dashboard.elements[elementName] : undefined;
|
return dashboard.elements[elementName].kind === 'LibraryPanel' ? dashboard.elements[elementName] : undefined;
|
||||||
}
|
}
|
||||||
|
function getGrafanaBuiltInAnnotationDataLayer(dashboard: DashboardV2Spec) {
|
||||||
|
const found = dashboard.annotations.some((item) => item.spec.builtIn);
|
||||||
|
if (found) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const grafanaBuiltAnnotation: AnnotationQueryKind = {
|
||||||
|
kind: 'AnnotationQuery',
|
||||||
|
spec: {
|
||||||
|
datasource: { uid: '-- Grafana --', type: 'grafana' },
|
||||||
|
name: 'Annotations & Alerts',
|
||||||
|
iconColor: DEFAULT_ANNOTATION_COLOR,
|
||||||
|
enable: true,
|
||||||
|
hide: true,
|
||||||
|
builtIn: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return grafanaBuiltAnnotation;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue