Chore: fixes DataSourceRef for adhoc variables (#41232)

* Chore: fixes DataSourceRef for adhoc variables

* Chore: fix path to packages
pull/39420/head^2
Hugo Häggmark 4 years ago committed by GitHub
parent bac6168e62
commit f5ab8c147a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      public/app/features/variables/adhoc/AdHocVariableEditor.tsx
  2. 30
      public/app/features/variables/adhoc/actions.test.ts
  3. 13
      public/app/features/variables/adhoc/actions.ts
  4. 22
      public/app/features/variables/adhoc/adapter.ts
  5. 8
      public/app/features/variables/adhoc/reducer.ts
  6. 9
      public/app/features/variables/guard.ts

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

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

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

@ -1,4 +1,6 @@
import { cloneDeep } from 'lodash';
import { getDataSourceSrv } from '@grafana/runtime';
import { getDataSourceRef } from '@grafana/data';
import { AdHocVariableModel } from '../types';
import { dispatch } from '../../../store/store';
@ -8,6 +10,7 @@ import { adHocVariableReducer, initialAdHocVariableModelState } from './reducer'
import { AdHocVariableEditor } from './AdHocVariableEditor';
import { setFiltersFromUrl } from './actions';
import * as urlParser from './urlParser';
import { isAdHoc, isLegacyAdHocDataSource } from '../guard';
const noop = async () => {};
@ -35,5 +38,24 @@ export const createAdHocVariableAdapter = (): VariableAdapter<AdHocVariableModel
const filters = variable?.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 };
},
};
};

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

@ -7,6 +7,7 @@ import {
DataQueryResponse,
DataSourceApi,
DataSourceJsonData,
DataSourceRef,
MetricFindValue,
StandardVariableQuery,
StandardVariableSupport,
@ -59,6 +60,14 @@ function hasObjectProperty(model: VariableModel, property: string): model is Var
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<
TQuery extends DataQuery = DataQuery,
TOptions extends DataSourceJsonData = DataSourceJsonData

Loading…
Cancel
Save