DashboardScene: Prepare annotations support for public dashboards (#75146)

* WIP Dashboard to Scenes: Annotations

* Bump scenes

* Enable annotations and controls

* Betterer

* Update snapshots

* Test fix

* DashboardScene: Prepare annotations support for public dashboards

* Use latest scenes
This commit is contained in:
Dominik Prokop 2023-09-20 12:47:09 +02:00 committed by GitHub
parent 501e547bea
commit df1c80c7d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 124 additions and 8 deletions

View File

@ -251,7 +251,7 @@
"@grafana/lezer-traceql": "0.0.6", "@grafana/lezer-traceql": "0.0.6",
"@grafana/monaco-logql": "^0.0.7", "@grafana/monaco-logql": "^0.0.7",
"@grafana/runtime": "workspace:*", "@grafana/runtime": "workspace:*",
"@grafana/scenes": "^1.3.3", "@grafana/scenes": "^1.5.1",
"@grafana/schema": "workspace:*", "@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*", "@grafana/ui": "workspace:*",
"@kusto/monaco-kusto": "^7.4.0", "@kusto/monaco-kusto": "^7.4.0",

View File

@ -0,0 +1,71 @@
import { map, of } from 'rxjs';
import { DataSourceApi, DataQueryRequest, PanelData } from '@grafana/data';
import { LoadingState } from '@grafana/schema';
import { PublicAnnotationsDataSource } from 'app/features/query/state/DashboardQueryRunner/PublicAnnotationsDataSource';
import { DashboardAnnotationsDataLayer } from './DashboardAnnotationsDataLayer';
const getDataSourceSrvSpy = jest.fn();
const runRequestMock = jest.fn().mockImplementation((ds: DataSourceApi, request: DataQueryRequest) => {
const result: PanelData = {
state: LoadingState.Loading,
series: [],
timeRange: request.range,
};
return of([]).pipe(
map(() => {
result.state = LoadingState.Done;
result.series = [];
return result;
})
);
});
jest.mock('app/features/query/state/DashboardQueryRunner/PublicAnnotationsDataSource');
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
getDataSourceSrv: () => {
getDataSourceSrvSpy();
},
getRunRequest: () => (ds: DataSourceApi, request: DataQueryRequest) => {
return runRequestMock(ds, request);
},
config: {
publicDashboardAccessToken: 'ac123',
},
}));
describe('DashboardAnnotationsDataLayer', () => {
it('should use PublicAnnotationsDataSource when config.publicDashboardAccessToken is set', () => {
const dataLayer = new DashboardAnnotationsDataLayer({
name: 'Annotations & Alerts',
query: {
builtIn: 1,
datasource: {
type: 'grafana',
uid: '-- Grafana --',
},
enable: true,
hide: true,
iconColor: 'rgba(0, 211, 255, 1)',
name: 'Annotations & Alerts',
target: {
// @ts-expect-error
limit: 100,
matchAny: false,
tags: [],
type: 'dashboard',
},
type: 'dashboard',
},
});
dataLayer.activate();
expect(PublicAnnotationsDataSource).toHaveBeenCalledTimes(1);
expect(getDataSourceSrvSpy).not.toHaveBeenCalled();
});
});

View File

@ -0,0 +1,45 @@
import { AnnotationEvent, arrayToDataFrame, DataTopic, getDefaultTimeRange, PanelData } from '@grafana/data';
import { config } from '@grafana/runtime';
import { dataLayers } from '@grafana/scenes';
import { AnnotationQuery, LoadingState } from '@grafana/schema';
import { PublicAnnotationsDataSource } from 'app/features/query/state/DashboardQueryRunner/PublicAnnotationsDataSource';
/**
* This class is an extension to dataLayers.AnnotationsDataLayer to provide support for public dashboards.
*/
export class DashboardAnnotationsDataLayer extends dataLayers.AnnotationsDataLayer {
protected async resolveDataSource(query: AnnotationQuery) {
if (config.publicDashboardAccessToken) {
return new PublicAnnotationsDataSource();
}
return super.resolveDataSource(query);
}
protected processEvents(
query: AnnotationQuery,
events: {
state: LoadingState;
events: AnnotationEvent[];
}
) {
if (config.publicDashboardAccessToken) {
const stateUpdate: PanelData = {
series: [],
timeRange: getDefaultTimeRange(),
state: events.state,
};
const df = arrayToDataFrame(events.events);
df.meta = {
...df.meta,
dataTopic: DataTopic.Annotations,
};
stateUpdate.annotations = [df];
return stateUpdate;
} else {
return super.processEvents(query, events);
}
}
}

View File

@ -27,7 +27,6 @@ import {
VizPanelState, VizPanelState,
SceneGridItemLike, SceneGridItemLike,
SceneDataLayers, SceneDataLayers,
dataLayers,
SceneDataLayerProvider, SceneDataLayerProvider,
SceneDataLayerControls, SceneDataLayerControls,
} from '@grafana/scenes'; } from '@grafana/scenes';
@ -35,6 +34,7 @@ import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { DashboardDTO } from 'app/types'; import { DashboardDTO } from 'app/types';
import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer';
import { DashboardScene } from '../scene/DashboardScene'; import { DashboardScene } from '../scene/DashboardScene';
import { LibraryVizPanel } from '../scene/LibraryVizPanel'; import { LibraryVizPanel } from '../scene/LibraryVizPanel';
import { panelMenuBehavior } from '../scene/PanelMenuBehavior'; import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
@ -180,7 +180,7 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel)
if (oldModel.annotations?.list?.length) { if (oldModel.annotations?.list?.length) {
layers = oldModel.annotations?.list.map((a) => { layers = oldModel.annotations?.list.map((a) => {
// Each annotation query is an individual data layer // Each annotation query is an individual data layer
return new dataLayers.AnnotationsDataLayer({ return new DashboardAnnotationsDataLayer({
query: a, query: a,
name: a.name, name: a.name,
isEnabled: Boolean(a.enable), isEnabled: Boolean(a.enable),

View File

@ -4010,9 +4010,9 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@grafana/scenes@npm:^1.3.3": "@grafana/scenes@npm:^1.5.1":
version: 1.3.3 version: 1.5.1
resolution: "@grafana/scenes@npm:1.3.3" resolution: "@grafana/scenes@npm:1.5.1"
dependencies: dependencies:
"@grafana/e2e-selectors": 10.0.2 "@grafana/e2e-selectors": 10.0.2
react-grid-layout: 1.3.4 react-grid-layout: 1.3.4
@ -4024,7 +4024,7 @@ __metadata:
"@grafana/runtime": 10.0.3 "@grafana/runtime": 10.0.3
"@grafana/schema": 10.0.3 "@grafana/schema": 10.0.3
"@grafana/ui": 10.0.3 "@grafana/ui": 10.0.3
checksum: 3c630aaeca7bc240b1db1a6cc7856808d940c354a558e6f1c5c0fac7268c5f57e0b6f8f55a1d9d1dbfbb02011f1beecc5fe1aae1209bc4430599e2660fd76f6d checksum: 9f3adbe54078181e8770c79c6958b9cf6ad5d511a799d3f05aab64cbd06fffdcf7a4f7ae4b518db8b3562408a95221f1a8783499119fe96f2100f53a3b9ddb22
languageName: node languageName: node
linkType: hard linkType: hard
@ -19701,7 +19701,7 @@ __metadata:
"@grafana/lezer-traceql": 0.0.6 "@grafana/lezer-traceql": 0.0.6
"@grafana/monaco-logql": ^0.0.7 "@grafana/monaco-logql": ^0.0.7
"@grafana/runtime": "workspace:*" "@grafana/runtime": "workspace:*"
"@grafana/scenes": ^1.3.3 "@grafana/scenes": ^1.5.1
"@grafana/schema": "workspace:*" "@grafana/schema": "workspace:*"
"@grafana/tsconfig": ^1.3.0-rc1 "@grafana/tsconfig": ^1.3.0-rc1
"@grafana/ui": "workspace:*" "@grafana/ui": "workspace:*"