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
pull/86812/head
Alexa V 1 year ago committed by GitHub
parent a8424f4831
commit de589b98c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 40
      public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx
  2. 18
      public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx
  3. 89
      public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts

@ -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<DataQuery, DataSourceJsonData, {}>;
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<DataQuery, DataSourceJsonData, {}>;
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', () => {

@ -154,6 +154,24 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
);
}
} 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);
}
}

@ -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,

Loading…
Cancel
Save