Files
Victor Marin d5f404d082 Dashboards: Add possibility to lock multi value variables option list (#95949)
* add new option for multi variables to lock value list wip

* WIP - lock option list

* tests

* fix

* fixes + canary scenes

* wip

* wip

* fix snapshot

* bump scenes

* Dashboards: Add possibility to lock adhoc variables options list (#96077)

* Lock list of options flag for ad hoc

* refactor

* fix snapshot
2024-11-21 16:01:54 +02:00

254 lines
8.2 KiB
TypeScript

import { TypedVariableModel } from '@grafana/data';
import { config, getDataSourceSrv } from '@grafana/runtime';
import {
AdHocFiltersVariable,
ConstantVariable,
CustomVariable,
DataSourceVariable,
GroupByVariable,
IntervalVariable,
QueryVariable,
SceneVariable,
SceneVariableSet,
TextBoxVariable,
} from '@grafana/scenes';
import { DashboardModel } from 'app/features/dashboard/state';
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));
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(v.datasource)?.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') {
return new AdHocFiltersVariable({
...commonProperties,
description: variable.description,
skipUrlSync: variable.skipUrlSync,
hide: variable.hide,
datasource: variable.datasource,
applyMode: 'auto',
filters: variable.filters ?? [],
baseFilters: variable.baseFilters ?? [],
defaultKeys: variable.defaultKeys,
allowCustomValue: variable.allowCustomValue ?? true,
useQueriesAsFilterForOptions: true,
layout: config.featureToggles.newFiltersUI ? 'combobox' : undefined,
supportsMultiValueOperators: Boolean(
getDataSourceSrv().getInstanceSettings(variable.datasource)?.meta.multiValueFilterOperators
),
});
}
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 ?? true,
});
} 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 ?? true,
});
} 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 ?? true,
});
} 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,
});
} else if (variable.type === 'constant') {
return new ConstantVariable({
...commonProperties,
value: variable.query,
skipUrlSync: variable.skipUrlSync,
hide: variable.hide,
});
} 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,
});
} 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,
});
} else {
throw new Error(`Scenes: Unsupported variable type ${variable.type}`);
}
}