2020-03-23 03:00:36 -05:00
|
|
|
import { cloneDeep } from 'lodash';
|
2020-03-23 07:45:08 -05:00
|
|
|
import { StoreState, ThunkResult } from 'app/types';
|
2020-03-23 03:00:36 -05:00
|
|
|
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
|
|
import { changeVariableEditorExtended } from '../editor/reducer';
|
2020-03-23 07:45:08 -05:00
|
|
|
import { addVariable, changeVariableProp } from '../state/sharedReducer';
|
|
|
|
import { getNewVariabelIndex, getVariable } from '../state/selectors';
|
|
|
|
import { AddVariable, toVariableIdentifier, toVariablePayload, VariableIdentifier } from '../state/types';
|
2020-03-23 03:00:36 -05:00
|
|
|
import {
|
|
|
|
AdHocVariabelFilterUpdate,
|
|
|
|
filterAdded,
|
2020-03-23 07:45:08 -05:00
|
|
|
filterRemoved,
|
2020-03-23 03:00:36 -05:00
|
|
|
filtersRestored,
|
2020-03-23 07:45:08 -05:00
|
|
|
filterUpdated,
|
2020-03-23 03:00:36 -05:00
|
|
|
initialAdHocVariableModelState,
|
|
|
|
} from './reducer';
|
2020-06-04 06:44:48 -05:00
|
|
|
import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types';
|
2020-03-23 03:00:36 -05:00
|
|
|
import { variableUpdated } from '../state/actions';
|
|
|
|
import { isAdHoc } from '../guard';
|
|
|
|
|
|
|
|
export interface AdHocTableOptions {
|
|
|
|
datasource: string;
|
|
|
|
key: string;
|
|
|
|
value: string;
|
|
|
|
operator: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
const filterTableName = 'Filters';
|
|
|
|
|
|
|
|
export const applyFilterFromTable = (options: AdHocTableOptions): ThunkResult<void> => {
|
|
|
|
return async (dispatch, getState) => {
|
|
|
|
let variable = getVariableByOptions(options, getState());
|
|
|
|
|
|
|
|
if (!variable) {
|
|
|
|
dispatch(createAdHocVariable(options));
|
|
|
|
variable = getVariableByOptions(options, getState());
|
|
|
|
}
|
|
|
|
|
2021-01-20 00:59:48 -06:00
|
|
|
const index = variable.filters.findIndex((f) => f.key === options.key && f.value === options.value);
|
2020-03-23 03:00:36 -05:00
|
|
|
|
|
|
|
if (index === -1) {
|
|
|
|
const { value, key, operator } = options;
|
|
|
|
const filter = { value, key, operator, condition: '' };
|
2020-06-04 06:44:48 -05:00
|
|
|
return await dispatch(addFilter(variable.id, filter));
|
2020-03-23 03:00:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const filter = { ...variable.filters[index], operator: options.operator };
|
2020-06-04 06:44:48 -05:00
|
|
|
return await dispatch(changeFilter(variable.id, { index, filter }));
|
2020-03-23 03:00:36 -05:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-03-23 07:45:08 -05:00
|
|
|
export const changeFilter = (id: string, update: AdHocVariabelFilterUpdate): ThunkResult<void> => {
|
2020-03-23 03:00:36 -05:00
|
|
|
return async (dispatch, getState) => {
|
2020-03-23 07:45:08 -05:00
|
|
|
const variable = getVariable(id, getState());
|
2020-03-23 03:00:36 -05:00
|
|
|
dispatch(filterUpdated(toVariablePayload(variable, update)));
|
|
|
|
await dispatch(variableUpdated(toVariableIdentifier(variable), true));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-03-23 07:45:08 -05:00
|
|
|
export const removeFilter = (id: string, index: number): ThunkResult<void> => {
|
2020-03-23 03:00:36 -05:00
|
|
|
return async (dispatch, getState) => {
|
2020-03-23 07:45:08 -05:00
|
|
|
const variable = getVariable(id, getState());
|
2020-03-23 03:00:36 -05:00
|
|
|
dispatch(filterRemoved(toVariablePayload(variable, index)));
|
|
|
|
await dispatch(variableUpdated(toVariableIdentifier(variable), true));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-03-23 07:45:08 -05:00
|
|
|
export const addFilter = (id: string, filter: AdHocVariableFilter): ThunkResult<void> => {
|
2020-03-23 03:00:36 -05:00
|
|
|
return async (dispatch, getState) => {
|
2020-03-23 07:45:08 -05:00
|
|
|
const variable = getVariable(id, getState());
|
2020-03-23 03:00:36 -05:00
|
|
|
dispatch(filterAdded(toVariablePayload(variable, filter)));
|
|
|
|
await dispatch(variableUpdated(toVariableIdentifier(variable), true));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-03-23 07:45:08 -05:00
|
|
|
export const setFiltersFromUrl = (id: string, filters: AdHocVariableFilter[]): ThunkResult<void> => {
|
2020-03-23 03:00:36 -05:00
|
|
|
return async (dispatch, getState) => {
|
2020-03-23 07:45:08 -05:00
|
|
|
const variable = getVariable(id, getState());
|
2020-03-23 03:00:36 -05:00
|
|
|
dispatch(filtersRestored(toVariablePayload(variable, filters)));
|
|
|
|
await dispatch(variableUpdated(toVariableIdentifier(variable), true));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-03-30 04:17:33 -05:00
|
|
|
export const changeVariableDatasource = (datasource?: string): ThunkResult<void> => {
|
2020-03-23 03:00:36 -05:00
|
|
|
return async (dispatch, getState) => {
|
|
|
|
const { editor } = getState().templating;
|
|
|
|
const variable = getVariable(editor.id, getState());
|
|
|
|
|
2021-04-01 11:17:39 -05:00
|
|
|
const loadingText = 'Ad hoc filters are applied automatically to all queries that target this data source';
|
2020-03-23 03:00:36 -05:00
|
|
|
|
|
|
|
dispatch(
|
|
|
|
changeVariableEditorExtended({
|
|
|
|
propName: 'infoText',
|
|
|
|
propValue: loadingText,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
dispatch(changeVariableProp(toVariablePayload(variable, { propName: 'datasource', propValue: datasource })));
|
|
|
|
|
|
|
|
const ds = await getDatasourceSrv().get(datasource);
|
|
|
|
|
|
|
|
if (!ds || !ds.getTagKeys) {
|
|
|
|
dispatch(
|
|
|
|
changeVariableEditorExtended({
|
|
|
|
propName: 'infoText',
|
2021-04-01 11:17:39 -05:00
|
|
|
propValue: 'This data source does not support ad hoc filters yet.',
|
2020-03-23 03:00:36 -05:00
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-01-20 00:59:48 -06:00
|
|
|
export const initAdHocVariableEditor = (): ThunkResult<void> => (dispatch) => {
|
2020-03-23 03:00:36 -05:00
|
|
|
const dataSources = getDatasourceSrv().getMetricSources();
|
|
|
|
const selectable = dataSources.reduce(
|
2021-03-30 04:17:33 -05:00
|
|
|
(all: Array<{ text: string; value: string | null }>, ds) => {
|
|
|
|
if (ds.meta.mixed) {
|
2020-03-23 03:00:36 -05:00
|
|
|
return all;
|
|
|
|
}
|
|
|
|
|
2021-03-30 04:17:33 -05:00
|
|
|
const text = ds.value === null ? `${ds.name} (default)` : ds.name;
|
|
|
|
all.push({ text: text, value: ds.value });
|
2020-03-23 03:00:36 -05:00
|
|
|
|
|
|
|
return all;
|
|
|
|
},
|
|
|
|
[{ text: '', value: '' }]
|
|
|
|
);
|
|
|
|
|
|
|
|
dispatch(
|
|
|
|
changeVariableEditorExtended({
|
|
|
|
propName: 'dataSources',
|
|
|
|
propValue: selectable,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const createAdHocVariable = (options: AdHocTableOptions): ThunkResult<void> => {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
const model = {
|
|
|
|
...cloneDeep(initialAdHocVariableModelState),
|
|
|
|
datasource: options.datasource,
|
|
|
|
name: filterTableName,
|
2020-03-23 07:45:08 -05:00
|
|
|
id: filterTableName,
|
2020-03-23 03:00:36 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
const global = false;
|
|
|
|
const index = getNewVariabelIndex(getState());
|
2020-03-23 07:45:08 -05:00
|
|
|
const identifier: VariableIdentifier = { type: 'adhoc', id: model.id };
|
2020-03-23 03:00:36 -05:00
|
|
|
|
|
|
|
dispatch(
|
|
|
|
addVariable(
|
|
|
|
toVariablePayload<AddVariable>(identifier, { global, model, index })
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const getVariableByOptions = (options: AdHocTableOptions, state: StoreState): AdHocVariableModel => {
|
|
|
|
return Object.values(state.templating.variables).find(
|
2021-01-20 00:59:48 -06:00
|
|
|
(v) => isAdHoc(v) && v.datasource === options.datasource
|
2020-03-23 03:00:36 -05:00
|
|
|
) as AdHocVariableModel;
|
|
|
|
};
|