From de589b98c7f5e4d8cb5235a090e82aa8a726662c Mon Sep 17 00:00:00 2001 From: Alexa V <239999+axelavargas@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:21:01 +0200 Subject: [PATCH] Dashboard: Migration [Panel Edit] Missing Query Editor when datasource is not found (#86789) * Return default datasource if datasource is not found * Set query runner datasource state to default, else refreshing will not work --- .../panel-edit/VizPanelManager.test.tsx | 40 ++++++++- .../panel-edit/VizPanelManager.tsx | 18 ++++ .../panel-edit/testfiles/testDashboard.ts | 89 +++++++++++++++++++ 3 files changed, 144 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx index 38390a8d4cc..db2f71c3a6f 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx @@ -1,7 +1,7 @@ import { map, of } from 'rxjs'; import { DataQueryRequest, DataSourceApi, DataSourceInstanceSettings, LoadingState, PanelData } from '@grafana/data'; -import { locationService } from '@grafana/runtime'; +import { config, locationService } from '@grafana/runtime'; import { SceneQueryRunner, VizPanel } from '@grafana/scenes'; import { DataQuery, DataSourceJsonData, DataSourceRef } from '@grafana/schema'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; @@ -75,6 +75,18 @@ const ds3Mock: DataSourceApi = { }, } as DataSourceApi; +const defaultDsMock: DataSourceApi = { + meta: { + id: 'grafana-testdata-datasource', + }, + name: 'grafana-testdata-datasource', + type: 'grafana-testdata-datasource', + uid: 'gdev-testdata', + getRef: () => { + return { type: 'grafana-testdata-datasource', uid: 'gdev-testdata' }; + }, +} as DataSourceApi; + const instance1SettingsMock = { id: 1, uid: 'gdev-testdata', @@ -124,6 +136,7 @@ jest.mock('@grafana/runtime', () => ({ getDataSourceSrv: () => ({ get: async (ref: DataSourceRef) => { // Mocking the build in Grafana data source to avoid annotations data layer errors. + if (ref.uid === '-- Grafana --') { return grafanaDs; } @@ -140,7 +153,8 @@ jest.mock('@grafana/runtime', () => ({ return ds3Mock; } - return null; + // if datasource is not found, return default datasource + return defaultDsMock; }, getInstanceSettings: (ref: DataSourceRef) => { if (ref.uid === 'gdev-testdata') { @@ -151,12 +165,17 @@ jest.mock('@grafana/runtime', () => ({ return instance2SettingsMock; } - return null; + // if datasource is not found, return default instance settings + return instance1SettingsMock; }, }), locationService: { partial: jest.fn(), }, + config: { + ...jest.requireActual('@grafana/runtime').config, + defaultDatasource: 'gdev-testdata', + }, })); describe('VizPanelManager', () => { @@ -350,6 +369,21 @@ describe('VizPanelManager', () => { datasourceUid: 'gdev-testdata', }); }); + + it('should load default datasource if the datasource passed is not found', async () => { + const { vizPanelManager } = setupTest('panel-6'); + vizPanelManager.activate(); + await Promise.resolve(); + + expect(vizPanelManager.queryRunner.state.datasource).toEqual({ + uid: 'abc', + type: 'datasource', + }); + + expect(config.defaultDatasource).toBe('gdev-testdata'); + expect(vizPanelManager.state.datasource).toEqual(defaultDsMock); + expect(vizPanelManager.state.dsSettings).toEqual(instance1SettingsMock); + }); }); describe('data source change', () => { diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx index 6979675ee09..0cfa0f7c5bc 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx @@ -154,6 +154,24 @@ export class VizPanelManager extends SceneObjectBase { ); } } catch (err) { + //set default datasource if we fail to load the datasource + const datasource = await getDataSourceSrv().get(config.defaultDatasource); + const dsSettings = getDataSourceSrv().getInstanceSettings(config.defaultDatasource); + + if (datasource && dsSettings) { + this.setState({ + datasource, + dsSettings, + }); + + this.queryRunner.setState({ + datasource: { + uid: dsSettings.uid, + type: dsSettings.type, + }, + }); + } + console.error(err); } } diff --git a/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts b/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts index f524e20f99c..77fec6d6910 100644 --- a/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts +++ b/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts @@ -410,6 +410,94 @@ export const panelWithNoDataSource = { title: 'Panel with no data source', type: 'timeseries', }; + +export const panelWithDataSourceNotFound = { + datasource: { + type: 'datasource', + uid: 'abc', + }, + fieldConfig: { + defaults: { + color: { + mode: 'palette-classic', + }, + custom: { + axisBorderShow: false, + axisCenteredZero: false, + axisColorMode: 'text', + axisLabel: '', + axisPlacement: 'auto', + barAlignment: 0, + drawStyle: 'line', + fillOpacity: 0, + gradientMode: 'none', + hideFrom: { + legend: false, + tooltip: false, + viz: false, + }, + insertNulls: false, + lineInterpolation: 'linear', + lineWidth: 1, + pointSize: 5, + scaleDistribution: { + type: 'linear', + }, + showPoints: 'auto', + spanNulls: false, + stacking: { + group: 'A', + mode: 'none', + }, + thresholdsStyle: { + mode: 'off', + }, + }, + mappings: [], + thresholds: { + mode: 'absolute', + steps: [ + { + color: 'green', + value: null, + }, + { + color: 'red', + value: 80, + }, + ], + }, + }, + overrides: [], + }, + gridPos: { + h: 8, + w: 12, + x: 0, + y: 0, + }, + id: 6, + options: { + legend: { + calcs: [], + displayMode: 'list', + placement: 'bottom', + showLegend: true, + }, + tooltip: { + mode: 'single', + sort: 'none', + }, + }, + targets: [ + { + refId: 'A', + }, + ], + title: 'Panel with no data source', + type: 'timeseries', +}; + export const testDashboard = { annotations: { list: [ @@ -439,6 +527,7 @@ export const testDashboard = { panelWithDashboardQuery, panelWithDashboardQueryAndTransformations, panelWithNoDataSource, + panelWithDataSourceNotFound, ], refresh: '', schemaVersion: 39,