UpdateQueries: Fixes issues setting datasource on queries after changing type (#41702)

This commit is contained in:
Torkel Ödegaard 2021-11-15 18:15:13 +01:00 committed by GitHub
parent 99900cbdd8
commit 51ef770c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 134 additions and 25 deletions

View File

@ -1,5 +1,4 @@
import { DataQuery, DataSourceInstanceSettings, DataSourceRef, getDataSourceRef } from '@grafana/data'; import { DataQuery, DataSourceRef } from '@grafana/data';
import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend';
export const getNextRefIdChar = (queries: DataQuery[]): string => { export const getNextRefIdChar = (queries: DataQuery[]): string => {
for (let num = 0; ; num++) { for (let num = 0; ; num++) {
@ -22,28 +21,6 @@ export function addQuery(queries: DataQuery[], query?: Partial<DataQuery>, datas
return [...queries, q as DataQuery]; return [...queries, q as DataQuery];
} }
export function updateQueries(
newSettings: DataSourceInstanceSettings,
queries: DataQuery[],
dsSettings?: DataSourceInstanceSettings
): DataQuery[] {
const datasource = getDataSourceRef(newSettings);
if (!newSettings.meta.mixed && dsSettings?.meta.mixed) {
return queries.map((q) => {
if (!isExpressionReference(q.datasource)) {
q.datasource = datasource;
}
return q;
});
} else if (!newSettings.meta.mixed && dsSettings?.meta.id !== newSettings.meta.id) {
// we are changing data source type, clear queries
return [{ refId: 'A', datasource }];
}
return queries;
}
export function isDataQuery(url: string): boolean { export function isDataQuery(url: string): boolean {
if ( if (
url.indexOf('api/datasources/proxy') !== -1 || url.indexOf('api/datasources/proxy') !== -1 ||

View File

@ -27,7 +27,7 @@ import {
PanelData, PanelData,
} from '@grafana/data'; } from '@grafana/data';
import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp';
import { addQuery, updateQueries } from 'app/core/utils/query'; import { addQuery } from 'app/core/utils/query';
import { Unsubscribable } from 'rxjs'; import { Unsubscribable } from 'rxjs';
import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -37,6 +37,7 @@ import { DashboardQueryEditor, isSharedDashboardQuery } from 'app/plugins/dataso
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { QueryGroupOptions } from 'app/types'; import { QueryGroupOptions } from 'app/types';
import { GroupActionComponents } from './QueryActionComponent'; import { GroupActionComponents } from './QueryActionComponent';
import { updateQueries } from '../state/updateQueries';
interface Props { interface Props {
queryRunner: PanelQueryRunner; queryRunner: PanelQueryRunner;

View File

@ -0,0 +1,102 @@
import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';
import { updateQueries } from './updateQueries';
describe('updateQueries', () => {
it('Should update all queries except expression query when changing data source with same type', () => {
const updated = updateQueries(
{
uid: 'new-uid',
type: 'same-type',
meta: {},
} as any,
[
{
refId: 'A',
datasource: {
uid: 'old-uid',
type: 'same-type',
},
},
{
refId: 'B',
datasource: ExpressionDatasourceRef,
},
],
{
uid: 'old-uid',
type: 'same-type',
} as any
);
expect(updated[0].datasource).toEqual({ type: 'same-type', uid: 'new-uid' });
expect(updated[1].datasource).toEqual(ExpressionDatasourceRef);
});
it('Should clear queries when changing type', () => {
const updated = updateQueries(
{
uid: 'new-uid',
type: 'new-type',
meta: {},
} as any,
[
{
refId: 'A',
datasource: {
uid: 'old-uid',
type: 'old-type',
},
},
{
refId: 'B',
datasource: {
uid: 'old-uid',
type: 'old-type',
},
},
],
{
uid: 'old-uid',
type: 'old-type',
} as any
);
expect(updated.length).toEqual(1);
expect(updated[0].datasource).toEqual({ type: 'new-type', uid: 'new-uid' });
});
it('Should preserve query data source when changing to mixed', () => {
const updated = updateQueries(
{
uid: 'mixed',
type: 'mixed',
meta: {
mixed: true,
},
} as any,
[
{
refId: 'A',
datasource: {
uid: 'old-uid',
type: 'old-type',
},
},
{
refId: 'B',
datasource: {
uid: 'other-uid',
type: 'other-type',
},
},
],
{
uid: 'old-uid',
type: 'old-type',
} as any
);
expect(updated[0].datasource).toEqual({ type: 'old-type', uid: 'old-uid' });
expect(updated[1].datasource).toEqual({ type: 'other-type', uid: 'other-uid' });
});
});

View File

@ -0,0 +1,29 @@
import { DataQuery, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data';
import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend';
export function updateQueries(
newSettings: DataSourceInstanceSettings,
queries: DataQuery[],
dsSettings?: DataSourceInstanceSettings
): DataQuery[] {
const datasource = getDataSourceRef(newSettings);
// we are changing data source type
if (dsSettings?.type !== newSettings.type) {
// If changing to mixed do nothing
if (newSettings.meta.mixed) {
return queries;
} else {
// Changing to another datasource type clear queries
return [{ refId: 'A', datasource }];
}
}
// Set data source on all queries except expression queries
return queries.map((query) => {
if (!isExpressionReference(query.datasource)) {
query.datasource = datasource;
}
return query;
});
}