mirror of https://github.com/grafana/grafana.git
298 lines
9.8 KiB
TypeScript
298 lines
9.8 KiB
TypeScript
import { AdHocVariableFilter, TypedVariableModel } from '@grafana/data';
|
|
import { config, getDataSourceSrv } from '@grafana/runtime';
|
|
import {
|
|
AdHocFiltersVariable,
|
|
ConstantVariable,
|
|
CustomVariable,
|
|
DataSourceVariable,
|
|
GroupByVariable,
|
|
IntervalVariable,
|
|
QueryVariable,
|
|
SceneVariable,
|
|
SceneVariableSet,
|
|
ScopesVariable,
|
|
SwitchVariable,
|
|
TextBoxVariable,
|
|
} from '@grafana/scenes';
|
|
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
|
|
|
import { SnapshotVariable } from '../serialization/custom-variables/SnapshotVariable';
|
|
|
|
import { getCurrentValueForOldIntervalModel, getIntervalsFromQueryString } from './utils';
|
|
|
|
const DEFAULT_DATASOURCE = 'default';
|
|
|
|
export function createVariablesForDashboard(oldModel: DashboardModel) {
|
|
const variableObjects = oldModel.templating.list
|
|
.map((v) => {
|
|
try {
|
|
return createSceneVariableFromVariableModel(v);
|
|
} catch (err) {
|
|
console.error(err);
|
|
return null;
|
|
}
|
|
})
|
|
// TODO: Remove filter
|
|
// Added temporarily to allow skipping non-compatible variables
|
|
.filter((v): v is SceneVariable => Boolean(v));
|
|
|
|
if (config.featureToggles.scopeFilters) {
|
|
variableObjects.push(new ScopesVariable({ enable: true }));
|
|
}
|
|
|
|
return new SceneVariableSet({
|
|
variables: variableObjects,
|
|
});
|
|
}
|
|
|
|
export function createVariablesForSnapshot(oldModel: DashboardModel) {
|
|
const variableObjects = oldModel.templating.list
|
|
.map((v) => {
|
|
try {
|
|
// for adhoc we are using the AdHocFiltersVariable from scenes becuase of its complexity
|
|
if (v.type === 'adhoc') {
|
|
return new AdHocFiltersVariable({
|
|
name: v.name,
|
|
label: v.label,
|
|
readOnly: true,
|
|
description: v.description,
|
|
skipUrlSync: v.skipUrlSync,
|
|
hide: v.hide,
|
|
datasource: v.datasource,
|
|
applyMode: 'auto',
|
|
filters: v.filters ?? [],
|
|
baseFilters: v.baseFilters ?? [],
|
|
defaultKeys: v.defaultKeys,
|
|
useQueriesAsFilterForOptions: true,
|
|
layout: config.featureToggles.newFiltersUI ? 'combobox' : undefined,
|
|
supportsMultiValueOperators: Boolean(
|
|
getDataSourceSrv().getInstanceSettings({ type: v.datasource?.type })?.meta.multiValueFilterOperators
|
|
),
|
|
});
|
|
}
|
|
// for other variable types we are using the SnapshotVariable
|
|
return createSnapshotVariable(v);
|
|
} catch (err) {
|
|
console.error(err);
|
|
return null;
|
|
}
|
|
})
|
|
// TODO: Remove filter
|
|
// Added temporarily to allow skipping non-compatible variables
|
|
.filter((v): v is SceneVariable => Boolean(v));
|
|
|
|
return new SceneVariableSet({
|
|
variables: variableObjects,
|
|
});
|
|
}
|
|
|
|
/** Snapshots variables are read-only and should not be updated */
|
|
export function createSnapshotVariable(variable: TypedVariableModel): SceneVariable {
|
|
let snapshotVariable: SnapshotVariable;
|
|
let current: { value: string | string[]; text: string | string[] };
|
|
if (variable.type === 'interval') {
|
|
const intervals = getIntervalsFromQueryString(variable.query);
|
|
const currentInterval = getCurrentValueForOldIntervalModel(variable, intervals);
|
|
snapshotVariable = new SnapshotVariable({
|
|
name: variable.name,
|
|
label: variable.label,
|
|
description: variable.description,
|
|
value: currentInterval,
|
|
text: currentInterval,
|
|
hide: variable.hide,
|
|
});
|
|
return snapshotVariable;
|
|
}
|
|
|
|
if (variable.type === 'system' || variable.type === 'constant' || variable.type === 'adhoc') {
|
|
current = {
|
|
value: '',
|
|
text: '',
|
|
};
|
|
} else {
|
|
current = {
|
|
value: variable.current?.value ?? '',
|
|
text: variable.current?.text ?? '',
|
|
};
|
|
}
|
|
|
|
snapshotVariable = new SnapshotVariable({
|
|
name: variable.name,
|
|
label: variable.label,
|
|
description: variable.description,
|
|
value: current?.value ?? '',
|
|
text: current?.text ?? '',
|
|
hide: variable.hide,
|
|
});
|
|
return snapshotVariable;
|
|
}
|
|
|
|
export function createSceneVariableFromVariableModel(variable: TypedVariableModel): SceneVariable {
|
|
const commonProperties = {
|
|
name: variable.name,
|
|
label: variable.label,
|
|
description: variable.description,
|
|
};
|
|
if (variable.type === 'adhoc') {
|
|
const originFilters: AdHocVariableFilter[] = [];
|
|
const filters: AdHocVariableFilter[] = [];
|
|
variable.filters?.forEach((filter) => (filter.origin ? originFilters.push(filter) : filters.push(filter)));
|
|
|
|
return new AdHocFiltersVariable({
|
|
...commonProperties,
|
|
description: variable.description,
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
datasource: variable.datasource,
|
|
applyMode: 'auto',
|
|
originFilters,
|
|
filters,
|
|
baseFilters: variable.baseFilters ?? [],
|
|
defaultKeys: variable.defaultKeys,
|
|
allowCustomValue: variable.allowCustomValue,
|
|
useQueriesAsFilterForOptions: true,
|
|
layout: config.featureToggles.newFiltersUI ? 'combobox' : undefined,
|
|
supportsMultiValueOperators: Boolean(
|
|
getDataSourceSrv().getInstanceSettings({ type: variable.datasource?.type })?.meta.multiValueFilterOperators
|
|
),
|
|
});
|
|
}
|
|
// Custom variable
|
|
if (variable.type === 'custom') {
|
|
return new CustomVariable({
|
|
...commonProperties,
|
|
value: variable.current?.value ?? '',
|
|
text: variable.current?.text ?? '',
|
|
|
|
query: variable.query,
|
|
isMulti: variable.multi,
|
|
allValue: variable.allValue || undefined,
|
|
includeAll: variable.includeAll,
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
allowCustomValue: variable.allowCustomValue,
|
|
});
|
|
// Query variable
|
|
} else if (variable.type === 'query') {
|
|
return new QueryVariable({
|
|
...commonProperties,
|
|
value: variable.current?.value ?? '',
|
|
text: variable.current?.text ?? '',
|
|
|
|
query: variable.query,
|
|
datasource: variable.datasource,
|
|
sort: variable.sort,
|
|
refresh: variable.refresh,
|
|
regex: variable.regex,
|
|
allValue: variable.allValue || undefined,
|
|
includeAll: variable.includeAll,
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
isMulti: variable.multi,
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
definition: variable.definition,
|
|
allowCustomValue: variable.allowCustomValue,
|
|
staticOptions: variable.staticOptions?.map((option) => ({
|
|
label: String(option.text),
|
|
value: String(option.value),
|
|
})),
|
|
staticOptionsOrder: variable.staticOptionsOrder,
|
|
});
|
|
// Datasource variable
|
|
} else if (variable.type === 'datasource') {
|
|
return new DataSourceVariable({
|
|
...commonProperties,
|
|
value: variable.current?.value ?? '',
|
|
text: variable.current?.text ?? '',
|
|
regex: variable.regex,
|
|
pluginId: variable.query,
|
|
allValue: variable.allValue || undefined,
|
|
includeAll: variable.includeAll,
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
skipUrlSync: variable.skipUrlSync,
|
|
isMulti: variable.multi,
|
|
hide: variable.hide,
|
|
defaultOptionEnabled: variable.current?.value === DEFAULT_DATASOURCE && variable.current?.text === 'default',
|
|
allowCustomValue: variable.allowCustomValue,
|
|
});
|
|
// Interval variable
|
|
} else if (variable.type === 'interval') {
|
|
const intervals = getIntervalsFromQueryString(variable.query);
|
|
const currentInterval = getCurrentValueForOldIntervalModel(variable, intervals);
|
|
return new IntervalVariable({
|
|
...commonProperties,
|
|
value: currentInterval,
|
|
intervals: intervals,
|
|
autoEnabled: variable.auto,
|
|
autoStepCount: variable.auto_count,
|
|
autoMinInterval: variable.auto_min,
|
|
refresh: variable.refresh,
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
});
|
|
// Constant variable
|
|
} else if (variable.type === 'constant') {
|
|
return new ConstantVariable({
|
|
...commonProperties,
|
|
value: variable.query,
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
});
|
|
// Textbox variable
|
|
} else if (variable.type === 'textbox') {
|
|
let val;
|
|
if (!variable?.current?.value) {
|
|
val = variable.query;
|
|
} else {
|
|
if (typeof variable.current.value === 'string') {
|
|
val = variable.current.value;
|
|
} else {
|
|
val = variable.current.value[0];
|
|
}
|
|
}
|
|
|
|
return new TextBoxVariable({
|
|
...commonProperties,
|
|
value: val,
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
});
|
|
// Groupby variable
|
|
} else if (config.featureToggles.groupByVariable && variable.type === 'groupby') {
|
|
return new GroupByVariable({
|
|
...commonProperties,
|
|
datasource: variable.datasource,
|
|
value: variable.current?.value || [],
|
|
text: variable.current?.text || [],
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
// @ts-expect-error
|
|
defaultOptions: variable.options,
|
|
defaultValue: variable.defaultValue,
|
|
allowCustomValue: variable.allowCustomValue,
|
|
});
|
|
// Switch variable
|
|
// In the old variable model we are storing the enabled and disabled values in the options:
|
|
// the first option is the enabled value and the second is the disabled value
|
|
} else if (variable.type === 'switch') {
|
|
const pickFirstValue = (value: string | string[]) => {
|
|
if (Array.isArray(value)) {
|
|
return value[0];
|
|
}
|
|
return value;
|
|
};
|
|
|
|
return new SwitchVariable({
|
|
...commonProperties,
|
|
value: pickFirstValue(variable.current?.value),
|
|
enabledValue: pickFirstValue(variable.options?.[0]?.value),
|
|
disabledValue: pickFirstValue(variable.options?.[1]?.value),
|
|
skipUrlSync: variable.skipUrlSync,
|
|
hide: variable.hide,
|
|
});
|
|
} else {
|
|
throw new Error(`Scenes: Unsupported variable type ${variable.type}`);
|
|
}
|
|
}
|