Chore: fixes DataSourceRef for adhoc variables (#41232)

* Chore: fixes DataSourceRef for adhoc variables

* Chore: fix path to packages
This commit is contained in:
Hugo Häggmark 2021-11-03 08:02:51 +01:00 committed by GitHub
parent bac6168e62
commit f5ab8c147a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 25 deletions

View File

@ -40,8 +40,8 @@ export class AdHocVariableEditorUnConnected extends PureComponent<Props> {
const { variable, editor } = this.props; const { variable, editor } = this.props;
const dataSources = editor.extended?.dataSources ?? []; const dataSources = editor.extended?.dataSources ?? [];
const infoText = editor.extended?.infoText ?? null; const infoText = editor.extended?.infoText ?? null;
const options = dataSources.map((ds) => ({ label: ds.text, value: { uid: ds.value } })); const options = dataSources.map((ds) => ({ label: ds.text, value: ds.value }));
const value = options.find((o) => o.value === variable.datasource) ?? options[0]; const value = options.find((o) => o.value?.uid === variable.datasource?.uid) ?? options[0];
return ( return (
<VerticalGroup spacing="xs"> <VerticalGroup spacing="xs">

View File

@ -1,4 +1,4 @@
import { DataSourcePluginMeta, DataSourceSelectItem } from '@grafana/data'; import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data';
import { variableAdapters } from '../adapters'; import { variableAdapters } from '../adapters';
import { createAdHocVariableAdapter } from './adapter'; import { createAdHocVariableAdapter } from './adapter';
@ -22,14 +22,14 @@ import { changeVariableEditorExtended, setIdInEditor } from '../editor/reducer';
import { adHocBuilder } from '../shared/testing/builders'; import { adHocBuilder } from '../shared/testing/builders';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
const getMetricSources = jest.fn().mockReturnValue([]); const getList = jest.fn().mockReturnValue([]);
const getDatasource = jest.fn().mockResolvedValue({}); const getDatasource = jest.fn().mockResolvedValue({});
locationService.partial = jest.fn(); locationService.partial = jest.fn();
jest.mock('app/features/plugins/datasource_srv', () => ({ jest.mock('app/features/plugins/datasource_srv', () => ({
getDatasourceSrv: jest.fn(() => ({ getDatasourceSrv: jest.fn(() => ({
get: getDatasource, get: getDatasource,
getMetricSources, getList,
})), })),
})); }));
@ -351,7 +351,7 @@ describe('adhoc actions', () => {
describe('when initAdHocVariableEditor is dispatched', () => { describe('when initAdHocVariableEditor is dispatched', () => {
it('then correct actions are dispatched', async () => { it('then correct actions are dispatched', async () => {
const datasources = [ const datasources = [
{ ...createDatasource('default', true), value: null }, { ...createDatasource('default', true, true), value: null },
createDatasource('elasticsearch-v1'), createDatasource('elasticsearch-v1'),
createDatasource('loki', false), createDatasource('loki', false),
createDatasource('influx'), createDatasource('influx'),
@ -359,19 +359,19 @@ describe('adhoc actions', () => {
createDatasource('elasticsearch-v7'), createDatasource('elasticsearch-v7'),
]; ];
getMetricSources.mockRestore(); getList.mockRestore();
getMetricSources.mockReturnValue(datasources); getList.mockReturnValue(datasources);
const tester = reduxTester<RootReducerType>() const tester = reduxTester<RootReducerType>()
.givenRootReducer(getRootReducer()) .givenRootReducer(getRootReducer())
.whenActionIsDispatched(initAdHocVariableEditor()); .whenActionIsDispatched(initAdHocVariableEditor());
const expectedDatasources = [ const expectedDatasources = [
{ text: '', value: '' }, { text: '', value: {} },
{ text: 'default (default)', value: null }, { text: 'default (default)', value: { uid: 'default', type: 'default' } },
{ text: 'elasticsearch-v1', value: 'elasticsearch-v1' }, { text: 'elasticsearch-v1', value: { uid: 'elasticsearch-v1', type: 'elasticsearch-v1' } },
{ text: 'influx', value: 'influx' }, { text: 'influx', value: { uid: 'influx', type: 'influx' } },
{ text: 'elasticsearch-v7', value: 'elasticsearch-v7' }, { text: 'elasticsearch-v7', value: { uid: 'elasticsearch-v7', type: 'elasticsearch-v7' } },
]; ];
tester.thenDispatchedActionsShouldEqual( tester.thenDispatchedActionsShouldEqual(
@ -438,12 +438,14 @@ function createAddVariableAction(variable: VariableModel, index = 0) {
return addVariable(toVariablePayload(identifier, data)); return addVariable(toVariablePayload(identifier, data));
} }
function createDatasource(name: string, selectable = true): DataSourceSelectItem { function createDatasource(name: string, selectable = true, isDefault = false): DataSourceInstanceSettings {
return { return {
name, name,
value: name,
meta: { meta: {
mixed: !selectable, mixed: !selectable,
} as DataSourcePluginMeta, } as DataSourcePluginMeta,
}; isDefault,
uid: name,
type: name,
} as DataSourceInstanceSettings;
} }

View File

@ -16,7 +16,7 @@ import {
import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types';
import { variableUpdated } from '../state/actions'; import { variableUpdated } from '../state/actions';
import { isAdHoc } from '../guard'; import { isAdHoc } from '../guard';
import { DataSourceRef } from '@grafana/data'; import { DataSourceRef, getDataSourceRef } from '@grafana/data';
export interface AdHocTableOptions { export interface AdHocTableOptions {
datasource: DataSourceRef; datasource: DataSourceRef;
@ -111,19 +111,20 @@ export const changeVariableDatasource = (datasource?: DataSourceRef): ThunkResul
}; };
export const initAdHocVariableEditor = (): ThunkResult<void> => (dispatch) => { export const initAdHocVariableEditor = (): ThunkResult<void> => (dispatch) => {
const dataSources = getDatasourceSrv().getMetricSources(); const dataSources = getDatasourceSrv().getList({ metrics: true, variables: false });
const selectable = dataSources.reduce( const selectable = dataSources.reduce(
(all: Array<{ text: string; value: string | null }>, ds) => { (all: Array<{ text: string; value: DataSourceRef | null }>, ds) => {
if (ds.meta.mixed) { if (ds.meta.mixed) {
return all; return all;
} }
const text = ds.value === null ? `${ds.name} (default)` : ds.name; const text = ds.isDefault ? `${ds.name} (default)` : ds.name;
all.push({ text: text, value: ds.value }); const value = getDataSourceRef(ds);
all.push({ text, value });
return all; return all;
}, },
[{ text: '', value: '' }] [{ text: '', value: {} }]
); );
dispatch( dispatch(

View File

@ -1,4 +1,6 @@
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { getDataSourceSrv } from '@grafana/runtime';
import { getDataSourceRef } from '@grafana/data';
import { AdHocVariableModel } from '../types'; import { AdHocVariableModel } from '../types';
import { dispatch } from '../../../store/store'; import { dispatch } from '../../../store/store';
@ -8,6 +10,7 @@ import { adHocVariableReducer, initialAdHocVariableModelState } from './reducer'
import { AdHocVariableEditor } from './AdHocVariableEditor'; import { AdHocVariableEditor } from './AdHocVariableEditor';
import { setFiltersFromUrl } from './actions'; import { setFiltersFromUrl } from './actions';
import * as urlParser from './urlParser'; import * as urlParser from './urlParser';
import { isAdHoc, isLegacyAdHocDataSource } from '../guard';
const noop = async () => {}; const noop = async () => {};
@ -35,5 +38,24 @@ export const createAdHocVariableAdapter = (): VariableAdapter<AdHocVariableModel
const filters = variable?.filters ?? []; const filters = variable?.filters ?? [];
return urlParser.toUrl(filters); return urlParser.toUrl(filters);
}, },
beforeAdding: (model) => {
if (!isAdHoc(model)) {
return model;
}
if (!isLegacyAdHocDataSource(model.datasource)) {
return model;
}
const ds = getDataSourceSrv().getInstanceSettings(model.datasource);
if (!ds) {
return model;
}
const clone = cloneDeep(model);
clone.datasource = getDataSourceRef(ds);
return { ...clone };
},
}; };
}; };

View File

@ -1,6 +1,8 @@
import { AdHocVariableFilter, AdHocVariableModel, initialVariableModelState } from 'app/features/variables/types';
import { getInstanceState, VariablePayload, initialVariablesState, VariablesState } from '../state/types';
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { DataSourceRef } from '@grafana/data';
import { AdHocVariableFilter, AdHocVariableModel, initialVariableModelState } from 'app/features/variables/types';
import { getInstanceState, initialVariablesState, VariablePayload, VariablesState } from '../state/types';
export interface AdHocVariabelFilterUpdate { export interface AdHocVariabelFilterUpdate {
index: number; index: number;
@ -8,7 +10,7 @@ export interface AdHocVariabelFilterUpdate {
} }
export interface AdHocVariableEditorState { export interface AdHocVariableEditorState {
infoText: string; infoText: string;
dataSources: Array<{ text: string; value: string }>; dataSources: Array<{ text: string; value: DataSourceRef | null }>;
} }
export const initialAdHocVariableModelState: AdHocVariableModel = { export const initialAdHocVariableModelState: AdHocVariableModel = {

View File

@ -7,6 +7,7 @@ import {
DataQueryResponse, DataQueryResponse,
DataSourceApi, DataSourceApi,
DataSourceJsonData, DataSourceJsonData,
DataSourceRef,
MetricFindValue, MetricFindValue,
StandardVariableQuery, StandardVariableQuery,
StandardVariableSupport, StandardVariableSupport,
@ -59,6 +60,14 @@ function hasObjectProperty(model: VariableModel, property: string): model is Var
return withProperty.hasOwnProperty(property) && typeof withProperty[property] === 'object'; return withProperty.hasOwnProperty(property) && typeof withProperty[property] === 'object';
} }
export function isLegacyAdHocDataSource(datasource: null | DataSourceRef | string): datasource is string {
if (datasource === null) {
return false;
}
return typeof datasource === 'string';
}
interface DataSourceWithLegacyVariableSupport< interface DataSourceWithLegacyVariableSupport<
TQuery extends DataQuery = DataQuery, TQuery extends DataQuery = DataQuery,
TOptions extends DataSourceJsonData = DataSourceJsonData TOptions extends DataSourceJsonData = DataSourceJsonData