From f00f56bbff12a29e2de06525392af7d0c462ba79 Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Mon, 21 Aug 2023 17:43:48 +0200 Subject: [PATCH] DashboardLoaders: Add support for loading library panels (#73406) * DashboardLoaders: Add support for loading library panels * Bump scenes * Scene object for loading library panels * Remove unused function * Remove console.log * Bump scenes * Review --- package.json | 2 +- .../scenes/dashboard/DashboardsLoader.ts | 55 +++++------------ .../scenes/dashboard/LibraryVizPanel.tsx | 60 +++++++++++++++++++ .../utils/createPanelDataProvider.ts | 39 ++++++++++++ yarn.lock | 10 ++-- 5 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 public/app/features/scenes/dashboard/LibraryVizPanel.tsx create mode 100644 public/app/features/scenes/dashboard/utils/createPanelDataProvider.ts diff --git a/package.json b/package.json index b48f647bd3e..d4aee81680f 100644 --- a/package.json +++ b/package.json @@ -244,7 +244,7 @@ "@grafana/lezer-traceql": "0.0.4", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "0.24.0", + "@grafana/scenes": "0.24.2", "@grafana/schema": "workspace:*", "@grafana/ui": "workspace:*", "@kusto/monaco-kusto": "^7.4.0", diff --git a/public/app/features/scenes/dashboard/DashboardsLoader.ts b/public/app/features/scenes/dashboard/DashboardsLoader.ts index 3071e014242..2190b318c3f 100644 --- a/public/app/features/scenes/dashboard/DashboardsLoader.ts +++ b/public/app/features/scenes/dashboard/DashboardsLoader.ts @@ -5,14 +5,12 @@ import { QueryVariableModel, VariableModel, } from '@grafana/data'; -import { config } from '@grafana/runtime'; import { VizPanel, SceneTimePicker, SceneGridLayout, SceneGridRow, SceneTimeRange, - SceneQueryRunner, SceneVariableSet, VariableValueSelectors, SceneVariable, @@ -21,9 +19,7 @@ import { QueryVariable, ConstantVariable, SceneRefreshPicker, - SceneDataTransformer, SceneGridItem, - SceneDataProvider, SceneObject, SceneControlsSpacer, VizPanelMenu, @@ -32,12 +28,12 @@ import { import { StateManagerBase } from 'app/core/services/StateManagerBase'; import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; -import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types'; import { DashboardScene } from './DashboardScene'; +import { LibraryVizPanel } from './LibraryVizPanel'; import { panelMenuBehavior } from './PanelMenuBehavior'; -import { ShareQueryDataProvider } from './ShareQueryDataProvider'; import { getVizPanelKeyForPanelId } from './utils'; +import { createPanelDataProvider } from './utils/createPanelDataProvider'; export interface DashboardLoaderState { dashboard?: DashboardScene; @@ -129,6 +125,18 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): Array { + static Component = LibraryPanelRenderer; + + constructor({ uid, title }: Pick) { + super({ uid, title }); + + this.addActivationHandler(this._onActivate); + } + + private _onActivate = () => { + this.loadLibraryPanelFromPanelModel(); + }; + + private async loadLibraryPanelFromPanelModel() { + const { title } = this.state; + let vizPanel = new VizPanel({ title }); + try { + const libPanel = await getLibraryPanel(this.state.uid, true); + const libPanelModel = new PanelModel(libPanel.model); + vizPanel.setState({ + options: libPanelModel.options ?? {}, + fieldConfig: libPanelModel.fieldConfig, + pluginVersion: libPanelModel.pluginVersion, + displayMode: libPanelModel.transparent ? 'transparent' : undefined, + $data: createPanelDataProvider(libPanelModel), + }); + } catch (err) { + vizPanel.setState({ + pluginLoadError: 'Unable to load library panel: ' + this.state.uid, + }); + } + + this.setState({ panel: vizPanel }); + } +} + +function LibraryPanelRenderer({ model }: SceneComponentProps) { + const { panel } = model.useState(); + + if (!panel) { + return null; + } + + return ; +} diff --git a/public/app/features/scenes/dashboard/utils/createPanelDataProvider.ts b/public/app/features/scenes/dashboard/utils/createPanelDataProvider.ts new file mode 100644 index 00000000000..71ba47b717b --- /dev/null +++ b/public/app/features/scenes/dashboard/utils/createPanelDataProvider.ts @@ -0,0 +1,39 @@ +import { config } from '@grafana/runtime'; +import { SceneDataProvider, SceneDataTransformer, SceneQueryRunner } from '@grafana/scenes'; +import { PanelModel } from 'app/features/dashboard/state'; +import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard'; + +import { ShareQueryDataProvider } from '../ShareQueryDataProvider'; + +export function createPanelDataProvider(panel: PanelModel): SceneDataProvider | undefined { + // Skip setting query runner for panels without queries + if (!panel.targets?.length) { + return undefined; + } + + // Skip setting query runner for panel plugins with skipDataQuery + if (config.panels[panel.type]?.skipDataQuery) { + return undefined; + } + + let dataProvider: SceneDataProvider | undefined = undefined; + + if (panel.datasource?.uid === SHARED_DASHBOARD_QUERY) { + dataProvider = new ShareQueryDataProvider({ query: panel.targets[0] }); + } else { + dataProvider = new SceneQueryRunner({ + queries: panel.targets, + maxDataPoints: panel.maxDataPoints ?? undefined, + }); + } + + // Wrap inner data provider in a data transformer + if (panel.transformations?.length) { + dataProvider = new SceneDataTransformer({ + $data: dataProvider, + transformations: panel.transformations, + }); + } + + return dataProvider; +} diff --git a/yarn.lock b/yarn.lock index 3d5eb4723fe..fb540ca9f64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3929,9 +3929,9 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes@npm:0.24.0": - version: 0.24.0 - resolution: "@grafana/scenes@npm:0.24.0" +"@grafana/scenes@npm:0.24.2": + version: 0.24.2 + resolution: "@grafana/scenes@npm:0.24.2" dependencies: "@grafana/e2e-selectors": 10.0.2 react-grid-layout: 1.3.4 @@ -3943,7 +3943,7 @@ __metadata: "@grafana/runtime": 10.0.3 "@grafana/schema": 10.0.3 "@grafana/ui": 10.0.3 - checksum: b9cfc535228f0426ee4e422d3e8872f56212f9785acfcdb86aefe6e9c2ff5c98ef750eef0d72cd0ebc2feb67719fac86877b2eae6d376bdd45691da9068b5194 + checksum: 26797a4c90ff3b6d2e80f3da1d3be9721a371d9d9569e443dad14c81eba8413ef3fff78ab85602f9bfe3e243d7555a834134ac0c1c8542c23b9cc572bd40ad0a languageName: node linkType: hard @@ -19248,7 +19248,7 @@ __metadata: "@grafana/lezer-traceql": 0.0.4 "@grafana/monaco-logql": ^0.0.7 "@grafana/runtime": "workspace:*" - "@grafana/scenes": 0.24.0 + "@grafana/scenes": 0.24.2 "@grafana/schema": "workspace:*" "@grafana/toolkit": "workspace:*" "@grafana/tsconfig": ^1.3.0-rc1