[Release12.0.1]:Schema V2-Fix built-in annotationsV2 (#104313) (#104815)

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)
pull/104824/head
Alexa V 3 months ago committed by GitHub
parent 5631d9aace
commit 3c62214699
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 18
      public/app/features/dashboard-scene/serialization/DashboardSceneSerializer.test.ts
  2. 25
      public/app/features/dashboard-scene/serialization/transformSaveModelSchemaV2ToScene.test.ts
  3. 29
      public/app/features/dashboard-scene/serialization/transformSaveModelSchemaV2ToScene.ts

@ -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…
Cancel
Save