From 401ec3c4b09ca9a2cf689922a8b744980df45017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 18 Sep 2023 09:00:59 +0200 Subject: [PATCH] DashboardScene: Meta data tab (#74810) * DashboardScene: Inspect meta tab * DashboardScene: Inspect meta tab * fix casing * Added meta data inspector to testdata data source --- pkg/tsdb/testdatasource/scenarios.go | 10 ++++- .../inspect/InspectMetaDataTab.tsx | 40 +++++++++++++++++++ .../inspect/PanelInspectDrawer.tsx | 14 ++++++- .../dashboard/components/Inspector/hooks.ts | 32 ++++++++------- .../datasource/testdata/MetaDataInspector.tsx | 27 +++++++++++++ .../plugins/datasource/testdata/module.tsx | 2 + public/locales/en-US/grafana.json | 2 +- public/locales/pseudo-LOCALE/grafana.json | 2 +- 8 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 public/app/features/dashboard-scene/inspect/InspectMetaDataTab.tsx create mode 100644 public/app/plugins/datasource/testdata/MetaDataInspector.tsx diff --git a/pkg/tsdb/testdatasource/scenarios.go b/pkg/tsdb/testdatasource/scenarios.go index 1757839aad0..93a2de919f3 100644 --- a/pkg/tsdb/testdatasource/scenarios.go +++ b/pkg/tsdb/testdatasource/scenarios.go @@ -757,13 +757,21 @@ func RandomWalk(query backend.DataQuery, model JSONModel, index int) *data.Frame timeWalkerMs += query.Interval.Milliseconds() } - return data.NewFrame("", + frame := data.NewFrame("", data.NewField("time", nil, timeVec). SetConfig(&data.FieldConfig{ Interval: float64(query.Interval.Milliseconds()), }), data.NewField(frameNameForQuery(query, model, index), parseLabels(model, index), floatVec), ) + + frame.SetMeta(&data.FrameMeta{ + Custom: map[string]interface{}{ + "customStat": 10, + }, + }) + + return frame } func randomWalkTable(query backend.DataQuery, model JSONModel) *data.Frame { diff --git a/public/app/features/dashboard-scene/inspect/InspectMetaDataTab.tsx b/public/app/features/dashboard-scene/inspect/InspectMetaDataTab.tsx new file mode 100644 index 00000000000..61ead1e25cc --- /dev/null +++ b/public/app/features/dashboard-scene/inspect/InspectMetaDataTab.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +import { DataSourceApi } from '@grafana/data'; +import { + SceneComponentProps, + sceneGraph, + SceneObjectBase, + SceneObjectState, + SceneObjectRef, + VizPanel, +} from '@grafana/scenes'; +import { t } from 'app/core/internationalization'; +import { InspectTab } from 'app/features/inspector/types'; + +export interface InspectMetaDataTabState extends SceneObjectState { + panelRef: SceneObjectRef; + dataSource: DataSourceApi; +} + +export class InspectMetaDataTab extends SceneObjectBase { + public getTabLabel() { + return t('dashboard.inspect.meta-tab', 'Meta data'); + } + + public getTabValue() { + return InspectTab.Meta; + } + + static Component = ({ model }: SceneComponentProps) => { + const { panelRef, dataSource } = model.state; + const data = sceneGraph.getData(panelRef.resolve()); + const Inspector = dataSource.components?.MetadataInspector; + + if (!data.state.data || !Inspector) { + return null; + } + + return ; + }; +} diff --git a/public/app/features/dashboard-scene/inspect/PanelInspectDrawer.tsx b/public/app/features/dashboard-scene/inspect/PanelInspectDrawer.tsx index e3e5119254f..76339abe519 100644 --- a/public/app/features/dashboard-scene/inspect/PanelInspectDrawer.tsx +++ b/public/app/features/dashboard-scene/inspect/PanelInspectDrawer.tsx @@ -12,10 +12,12 @@ import { SceneObjectRef, } from '@grafana/scenes'; import { Alert, Drawer, Tab, TabsBar } from '@grafana/ui'; +import { getDataSourceWithInspector } from 'app/features/dashboard/components/Inspector/hooks'; import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils'; import { InspectDataTab } from './InspectDataTab'; import { InspectJsonTab } from './InspectJsonTab'; +import { InspectMetaDataTab } from './InspectMetaDataTab'; import { InspectQueryTab } from './InspectQueryTab'; import { InspectStatsTab } from './InspectStatsTab'; import { SceneInspectTab } from './types'; @@ -32,7 +34,10 @@ export class PanelInspectDrawer extends SceneObjectBase constructor(state: PanelInspectDrawerState) { super(state); + this.addActivationHandler(() => this._activationHandler()); + } + private _activationHandler() { this.buildTabs(0); } @@ -40,7 +45,7 @@ export class PanelInspectDrawer extends SceneObjectBase * We currently have no async await to get the panel plugin from the VizPanel. * That is why there is a retry argument here and a setTimeout, to try again a bit later. */ - buildTabs(retry: number) { + async buildTabs(retry: number) { const panelRef = this.state.panelRef; const panel = panelRef.resolve(); const plugin = panel.getPlugin(); @@ -55,9 +60,16 @@ export class PanelInspectDrawer extends SceneObjectBase } if (supportsDataQuery(plugin)) { + const data = sceneGraph.getData(panel); + tabs.push(new InspectDataTab({ panelRef })); tabs.push(new InspectStatsTab({ panelRef })); tabs.push(new InspectQueryTab({ panelRef })); + + const dsWithInspector = await getDataSourceWithInspector(data.state.data); + if (dsWithInspector) { + tabs.push(new InspectMetaDataTab({ panelRef, dataSource: dsWithInspector })); + } } tabs.push(new InspectJsonTab({ panelRef, onClose: this.onClose })); diff --git a/public/app/features/dashboard/components/Inspector/hooks.ts b/public/app/features/dashboard/components/Inspector/hooks.ts index 48163ea84cc..3e4291f3d65 100644 --- a/public/app/features/dashboard/components/Inspector/hooks.ts +++ b/public/app/features/dashboard/components/Inspector/hooks.ts @@ -13,25 +13,27 @@ import { supportsDataQuery } from '../PanelEditor/utils'; * Given PanelData return first data source supporting metadata inspector */ export const useDatasourceMetadata = (data?: PanelData) => { - const state = useAsync(async () => { - const targets = data?.request?.targets || []; + const state = useAsync(async () => getDataSourceWithInspector(data), [data]); + return state.value; +}; - if (data && data.series && targets.length) { - for (const frame of data.series) { - if (frame.meta && frame.meta.custom) { - // get data source from first query - const dataSource = await getDataSourceSrv().get(targets[0].datasource); - if (dataSource && dataSource.components?.MetadataInspector) { - return dataSource; - } +export async function getDataSourceWithInspector(data?: PanelData): Promise { + const targets = data?.request?.targets || []; + + if (data && data.series && targets.length) { + for (const frame of data.series) { + if (frame.meta && frame.meta.custom) { + // get data source from first query + const dataSource = await getDataSourceSrv().get(targets[0].datasource); + if (dataSource && dataSource.components?.MetadataInspector) { + return dataSource; } } } + } - return undefined; - }, [data]); - return state.value; -}; + return undefined; +} /** * Configures tabs for PanelInspector @@ -51,7 +53,7 @@ export const useInspectTabs = ( } if (metaDs) { - tabs.push({ label: t('dashboard.inspect.meta-tab', 'Meta Data'), value: InspectTab.Meta }); + tabs.push({ label: t('dashboard.inspect.meta-tab', 'Meta data'), value: InspectTab.Meta }); } tabs.push({ label: t('dashboard.inspect.json-tab', 'JSON'), value: InspectTab.JSON }); diff --git a/public/app/plugins/datasource/testdata/MetaDataInspector.tsx b/public/app/plugins/datasource/testdata/MetaDataInspector.tsx new file mode 100644 index 00000000000..94b7599435f --- /dev/null +++ b/public/app/plugins/datasource/testdata/MetaDataInspector.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +import { MetadataInspectorProps } from '@grafana/data'; +import { Stack } from '@grafana/experimental'; + +import { TestData } from './dataquery.gen'; +import { TestDataDataSource } from './datasource'; + +export type Props = MetadataInspectorProps; + +export function MetaDataInspector({ data }: Props) { + return ( + +
Meta data inspector for the TestData data source.
+ + {data.map((frame, index) => ( + <> +
Frame: {index}
+
+ Custom meta:
+ {JSON.stringify(frame.meta?.custom, null, 2)} +
+ + ))} +
+ ); +} diff --git a/public/app/plugins/datasource/testdata/module.tsx b/public/app/plugins/datasource/testdata/module.tsx index ad727cf0f87..c992b60de9d 100644 --- a/public/app/plugins/datasource/testdata/module.tsx +++ b/public/app/plugins/datasource/testdata/module.tsx @@ -1,6 +1,7 @@ import { DataSourcePlugin } from '@grafana/data'; import { ConfigEditor } from './ConfigEditor'; +import { MetaDataInspector } from './MetaDataInspector'; import { QueryEditor } from './QueryEditor'; import { TestInfoTab } from './TestInfoTab'; import { TestDataDataSource } from './datasource'; @@ -8,6 +9,7 @@ import { TestDataDataSource } from './datasource'; export const plugin = new DataSourcePlugin(TestDataDataSource) .setConfigEditor(ConfigEditor) .setQueryEditor(QueryEditor) + .setMetadataInspector(MetaDataInspector) .addConfigPage({ title: 'Setup', icon: 'list-ul', diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 2553762c79e..60801a3f577 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -152,7 +152,7 @@ "data-tab": "Data", "error-tab": "Error", "json-tab": "JSON", - "meta-tab": "Meta Data", + "meta-tab": "Meta data", "query-tab": "Query", "stats-tab": "Stats", "subtitle": "{{queryCount}} queries with total query time of {{formatted}}", diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json index 4004f2c6e79..5f9770bac16 100644 --- a/public/locales/pseudo-LOCALE/grafana.json +++ b/public/locales/pseudo-LOCALE/grafana.json @@ -152,7 +152,7 @@ "data-tab": "Đäŧä", "error-tab": "Ēřřőř", "json-tab": "ĴŜØŃ", - "meta-tab": "Męŧä Đäŧä", + "meta-tab": "Męŧä đäŧä", "query-tab": "Qūęřy", "stats-tab": "Ŝŧäŧş", "subtitle": "{{queryCount}} qūęřįęş ŵįŧĥ ŧőŧäľ qūęřy ŧįmę őƒ {{formatted}}",