mirror of https://github.com/grafana/grafana.git
Dashboard Schema V2: Introduce __legacyStringValue and deprecate string type for query prop in QueryVariableSpec (#99716)
* Introduce __legacyStringValue and deprecate string type for query * Fix tests * Fix tests * remove default * kind should default to default ds if variable doesn't have ds field * lint * getDefaultDataSourceRef should not return undefined
This commit is contained in:
parent
f1eac34b54
commit
4c52abb6b4
|
@ -651,7 +651,7 @@ QueryVariableSpec: {
|
||||||
skipUrlSync: bool | *false
|
skipUrlSync: bool | *false
|
||||||
description?: string
|
description?: string
|
||||||
datasource?: DataSourceRef
|
datasource?: DataSourceRef
|
||||||
query: string | DataQueryKind | *""
|
query: DataQueryKind
|
||||||
regex: string | *""
|
regex: string | *""
|
||||||
sort: VariableSort
|
sort: VariableSort
|
||||||
definition?: string
|
definition?: string
|
||||||
|
|
|
@ -344,7 +344,13 @@ export const handyTestingSchema: DashboardV2Spec = {
|
||||||
multi: true,
|
multi: true,
|
||||||
name: 'queryVar',
|
name: 'queryVar',
|
||||||
options: [],
|
options: [],
|
||||||
query: 'query1',
|
query: {
|
||||||
|
kind: 'prometheus',
|
||||||
|
spec: {
|
||||||
|
expr: 'test-query',
|
||||||
|
refId: 'A',
|
||||||
|
},
|
||||||
|
},
|
||||||
refresh: 'onDashboardLoad',
|
refresh: 'onDashboardLoad',
|
||||||
regex: 'regex1',
|
regex: 'regex1',
|
||||||
skipUrlSync: false,
|
skipUrlSync: false,
|
||||||
|
|
|
@ -960,7 +960,7 @@ export interface QueryVariableSpec {
|
||||||
skipUrlSync: boolean;
|
skipUrlSync: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
datasource?: DataSourceRef;
|
datasource?: DataSourceRef;
|
||||||
query: string | DataQueryKind;
|
query: DataQueryKind;
|
||||||
regex: string;
|
regex: string;
|
||||||
sort: VariableSort;
|
sort: VariableSort;
|
||||||
definition?: string;
|
definition?: string;
|
||||||
|
@ -977,7 +977,7 @@ export const defaultQueryVariableSpec = (): QueryVariableSpec => ({
|
||||||
hide: "dontHide",
|
hide: "dontHide",
|
||||||
refresh: "never",
|
refresh: "never",
|
||||||
skipUrlSync: false,
|
skipUrlSync: false,
|
||||||
query: "",
|
query: defaultDataQueryKind(),
|
||||||
regex: "",
|
regex: "",
|
||||||
sort: "disabled",
|
sort: "disabled",
|
||||||
options: [],
|
options: [],
|
||||||
|
|
|
@ -222,7 +222,13 @@ exports[`transformSceneToSaveModelSchemaV2 should transform scene to save model
|
||||||
"multi": true,
|
"multi": true,
|
||||||
"name": "queryVar",
|
"name": "queryVar",
|
||||||
"options": [],
|
"options": [],
|
||||||
"query": "query1",
|
"query": {
|
||||||
|
"kind": "prometheus",
|
||||||
|
"spec": {
|
||||||
|
"expr": "label_values(node_boot_time_seconds)",
|
||||||
|
"refId": "A",
|
||||||
|
},
|
||||||
|
},
|
||||||
"refresh": "onDashboardLoad",
|
"refresh": "onDashboardLoad",
|
||||||
"regex": "regex1",
|
"regex": "regex1",
|
||||||
"skipUrlSync": false,
|
"skipUrlSync": false,
|
||||||
|
|
|
@ -775,7 +775,12 @@ describe('sceneVariablesSetToVariables', () => {
|
||||||
"multi": true,
|
"multi": true,
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"options": [],
|
"options": [],
|
||||||
"query": "query",
|
"query": {
|
||||||
|
"kind": "fake-std",
|
||||||
|
"spec": {
|
||||||
|
"__legacyStringValue": "query",
|
||||||
|
},
|
||||||
|
},
|
||||||
"refresh": "onDashboardLoad",
|
"refresh": "onDashboardLoad",
|
||||||
"regex": "",
|
"regex": "",
|
||||||
"skipUrlSync": false,
|
"skipUrlSync": false,
|
||||||
|
|
|
@ -27,6 +27,7 @@ import {
|
||||||
transformVariableRefreshToEnum,
|
transformVariableRefreshToEnum,
|
||||||
transformVariableHideToEnum,
|
transformVariableHideToEnum,
|
||||||
transformSortVariableToEnum,
|
transformSortVariableToEnum,
|
||||||
|
LEGACY_STRING_VALUE_KEY,
|
||||||
} from './transformToV2TypesUtils';
|
} from './transformToV2TypesUtils';
|
||||||
/**
|
/**
|
||||||
* Converts a SceneVariables object into an array of VariableModel objects.
|
* Converts a SceneVariables object into an array of VariableModel objects.
|
||||||
|
@ -269,16 +270,20 @@ export function sceneVariablesSetToSchemaV2Variables(
|
||||||
if (transformVariableRefreshToEnum(variable.state.refresh) === 'never' || keepQueryOptions) {
|
if (transformVariableRefreshToEnum(variable.state.refresh) === 'never' || keepQueryOptions) {
|
||||||
options = variableValueOptionsToVariableOptions(variable.state);
|
options = variableValueOptionsToVariableOptions(variable.state);
|
||||||
}
|
}
|
||||||
//query: DataQueryKind | string;
|
|
||||||
const query = variable.state.query;
|
const query = variable.state.query;
|
||||||
let dataQuery: DataQueryKind | string;
|
let dataQuery: DataQueryKind | string;
|
||||||
if (typeof query !== 'string') {
|
if (typeof query !== 'string') {
|
||||||
dataQuery = {
|
dataQuery = {
|
||||||
kind: getDataQueryKind(query),
|
kind: variable.state.datasource?.type ?? getDataQueryKind(query),
|
||||||
spec: getDataQuerySpec(query),
|
spec: getDataQuerySpec(query),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
dataQuery = query;
|
dataQuery = {
|
||||||
|
kind: variable.state.datasource?.type ?? getDataQueryKind(query),
|
||||||
|
spec: {
|
||||||
|
[LEGACY_STRING_VALUE_KEY]: query,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const queryVariable: QueryVariableKind = {
|
const queryVariable: QueryVariableKind = {
|
||||||
kind: 'QueryVariable',
|
kind: 'QueryVariable',
|
||||||
|
|
|
@ -100,6 +100,7 @@ import {
|
||||||
transformVariableHideToEnumV1,
|
transformVariableHideToEnumV1,
|
||||||
transformVariableRefreshToEnumV1,
|
transformVariableRefreshToEnumV1,
|
||||||
} from './transformToV1TypesUtils';
|
} from './transformToV1TypesUtils';
|
||||||
|
import { LEGACY_STRING_VALUE_KEY } from './transformToV2TypesUtils';
|
||||||
|
|
||||||
const DEFAULT_DATASOURCE = 'default';
|
const DEFAULT_DATASOURCE = 'default';
|
||||||
|
|
||||||
|
@ -635,12 +636,12 @@ function createSceneVariableFromVariableModel(variable: TypedVariableModelV2): S
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataQueryForVariable(variable: QueryVariableKind) {
|
function getDataQueryForVariable(variable: QueryVariableKind) {
|
||||||
return typeof variable.spec.query !== 'string'
|
return LEGACY_STRING_VALUE_KEY in variable.spec.query.spec
|
||||||
? {
|
? (variable.spec.query.spec[LEGACY_STRING_VALUE_KEY] ?? '')
|
||||||
|
: {
|
||||||
...variable.spec.query.spec,
|
...variable.spec.query.spec,
|
||||||
refId: variable.spec.query.spec.refId ?? 'A',
|
refId: variable.spec.query.spec.refId ?? 'A',
|
||||||
}
|
};
|
||||||
: (variable.spec.query ?? '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentValueForOldIntervalModel(variable: IntervalVariableKind, intervals: string[]): string {
|
export function getCurrentValueForOldIntervalModel(variable: IntervalVariableKind, intervals: string[]): string {
|
||||||
|
|
|
@ -225,7 +225,10 @@ describe('transformSceneToSaveModelSchemaV2', () => {
|
||||||
hide: VariableHideV1.hideLabel,
|
hide: VariableHideV1.hideLabel,
|
||||||
value: 'value1',
|
value: 'value1',
|
||||||
text: 'text1',
|
text: 'text1',
|
||||||
query: 'query1',
|
query: {
|
||||||
|
expr: 'label_values(node_boot_time_seconds)',
|
||||||
|
refId: 'A',
|
||||||
|
},
|
||||||
definition: 'definition1',
|
definition: 'definition1',
|
||||||
datasource: { uid: 'datasource1', type: 'prometheus' },
|
datasource: { uid: 'datasource1', type: 'prometheus' },
|
||||||
sort: VariableSortV1.alphabeticalDesc,
|
sort: VariableSortV1.alphabeticalDesc,
|
||||||
|
|
|
@ -403,8 +403,11 @@ function getVizPanelQueries(vizPanel: VizPanel): PanelQueryKind[] {
|
||||||
return queries;
|
return queries;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDataQueryKind(query: SceneDataQuery): string {
|
export function getDataQueryKind(query: SceneDataQuery | string): string {
|
||||||
// If the query has a datasource, use the datasource type, otherwise return empty kind
|
if (typeof query === 'string') {
|
||||||
|
return getDefaultDataSourceRef()?.type ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
return query.datasource?.type ?? getDefaultDataSourceRef()?.type ?? '';
|
return query.datasource?.type ?? getDefaultDataSourceRef()?.type ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,19 +619,15 @@ export function getAnnotationQueryKind(annotationQuery: AnnotationQuery): string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultDataSourceRef(): DataSourceRef | undefined {
|
export function getDefaultDataSourceRef(): DataSourceRef {
|
||||||
// we need to return the default datasource configured in the BootConfig
|
// we need to return the default datasource configured in the BootConfig
|
||||||
const defaultDatasource = config.bootData.settings.defaultDatasource;
|
const defaultDatasource = config.bootData.settings.defaultDatasource;
|
||||||
|
|
||||||
// get default datasource type
|
// get default datasource type
|
||||||
const dsList = config.bootData.settings.datasources ?? {};
|
const dsList = config.bootData.settings.datasources;
|
||||||
const ds = dsList[defaultDatasource];
|
const ds = dsList[defaultDatasource];
|
||||||
|
|
||||||
if (ds) {
|
return { type: ds.meta.id, uid: ds.name }; // in the datasource list from bootData "id" is the type
|
||||||
return { type: ds.meta.id, uid: ds.name }; // in the datasource list from bootData "id" is the type
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to know if the dashboard transformed is a valid DashboardV2Spec
|
// Function to know if the dashboard transformed is a valid DashboardV2Spec
|
||||||
|
|
|
@ -19,6 +19,9 @@ import {
|
||||||
FieldColorModeId as FieldColorModeIdV2,
|
FieldColorModeId as FieldColorModeIdV2,
|
||||||
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
|
} from '@grafana/schema/dist/esm/schema/dashboard/v2alpha0';
|
||||||
|
|
||||||
|
// used for QueryVariableKind's query prop - in schema V2 we've deprecated string type and support only DataQuery
|
||||||
|
export const LEGACY_STRING_VALUE_KEY = '__legacyStringValue';
|
||||||
|
|
||||||
export function transformCursorSynctoEnum(cursorSync?: DashboardCursorSyncV1): DashboardCursorSync {
|
export function transformCursorSynctoEnum(cursorSync?: DashboardCursorSyncV1): DashboardCursorSync {
|
||||||
switch (cursorSync) {
|
switch (cursorSync) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -53,7 +53,7 @@ export function validateVariable<
|
||||||
}
|
}
|
||||||
if (sceneVariable instanceof QueryVariable && variableKind.kind === 'QueryVariable') {
|
if (sceneVariable instanceof QueryVariable && variableKind.kind === 'QueryVariable') {
|
||||||
expect(sceneVariable?.state.datasource).toBe(variableKind.spec.datasource);
|
expect(sceneVariable?.state.datasource).toBe(variableKind.spec.datasource);
|
||||||
expect(sceneVariable?.state.query).toBe(variableKind.spec.query);
|
expect(sceneVariable?.state.query).toEqual(variableKind.spec.query.spec);
|
||||||
}
|
}
|
||||||
if (sceneVariable instanceof CustomVariable && variableKind.kind === 'CustomVariable') {
|
if (sceneVariable instanceof CustomVariable && variableKind.kind === 'CustomVariable') {
|
||||||
expect(sceneVariable?.state.query).toBe(variableKind.spec.query);
|
expect(sceneVariable?.state.query).toBe(variableKind.spec.query);
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
} from 'app/features/apiserver/types';
|
} from 'app/features/apiserver/types';
|
||||||
import { getDefaultDataSourceRef } from 'app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2';
|
import { getDefaultDataSourceRef } from 'app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2';
|
||||||
import {
|
import {
|
||||||
|
LEGACY_STRING_VALUE_KEY,
|
||||||
transformVariableHideToEnum,
|
transformVariableHideToEnum,
|
||||||
transformVariableRefreshToEnum,
|
transformVariableRefreshToEnum,
|
||||||
} from 'app/features/dashboard-scene/serialization/transformToV2TypesUtils';
|
} from 'app/features/dashboard-scene/serialization/transformToV2TypesUtils';
|
||||||
|
@ -915,7 +916,7 @@ describe('ResponseTransformers', () => {
|
||||||
expect(v2.spec.datasource).toEqual(v1.datasource);
|
expect(v2.spec.datasource).toEqual(v1.datasource);
|
||||||
|
|
||||||
if (typeof v1.query === 'string') {
|
if (typeof v1.query === 'string') {
|
||||||
expect(v2.spec.query).toEqual(v1.query);
|
expect(v2.spec.query.spec[LEGACY_STRING_VALUE_KEY]).toEqual(v1.query);
|
||||||
} else {
|
} else {
|
||||||
expect(v2.spec.query).toEqual({
|
expect(v2.spec.query).toEqual({
|
||||||
kind: v1.datasource?.type,
|
kind: v1.datasource?.type,
|
||||||
|
|
|
@ -62,6 +62,7 @@ import {
|
||||||
transformVariableRefreshToEnumV1,
|
transformVariableRefreshToEnumV1,
|
||||||
} from 'app/features/dashboard-scene/serialization/transformToV1TypesUtils';
|
} from 'app/features/dashboard-scene/serialization/transformToV1TypesUtils';
|
||||||
import {
|
import {
|
||||||
|
LEGACY_STRING_VALUE_KEY,
|
||||||
transformCursorSynctoEnum,
|
transformCursorSynctoEnum,
|
||||||
transformDataTopic,
|
transformDataTopic,
|
||||||
transformSortVariableToEnum,
|
transformSortVariableToEnum,
|
||||||
|
@ -504,8 +505,12 @@ function getVariables(vars: TypedVariableModel[]): DashboardV2Spec['variables']
|
||||||
let query = v.query || {};
|
let query = v.query || {};
|
||||||
|
|
||||||
if (typeof query === 'string') {
|
if (typeof query === 'string') {
|
||||||
console.error('Query variable query is a string. It needs to extend DataQuery.');
|
console.warn(
|
||||||
query = {};
|
'Query variable query is a string which is deprecated in the schema v2. It should extend DataQuery'
|
||||||
|
);
|
||||||
|
query = {
|
||||||
|
[LEGACY_STRING_VALUE_KEY]: query,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const qv: QueryVariableKind = {
|
const qv: QueryVariableKind = {
|
||||||
|
@ -527,7 +532,7 @@ function getVariables(vars: TypedVariableModel[]): DashboardV2Spec['variables']
|
||||||
query: {
|
query: {
|
||||||
kind: v.datasource?.type || getDefaultDatasourceType(),
|
kind: v.datasource?.type || getDefaultDatasourceType(),
|
||||||
spec: {
|
spec: {
|
||||||
...query,
|
...v.query,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -708,7 +713,10 @@ function getVariablesV1(vars: DashboardV2Spec['variables']): VariableModel[] {
|
||||||
...commonProperties,
|
...commonProperties,
|
||||||
current: v.spec.current,
|
current: v.spec.current,
|
||||||
options: v.spec.options,
|
options: v.spec.options,
|
||||||
query: typeof v.spec.query === 'string' ? v.spec.query : v.spec.query.spec,
|
query:
|
||||||
|
LEGACY_STRING_VALUE_KEY in v.spec.query.spec
|
||||||
|
? v.spec.query.spec[LEGACY_STRING_VALUE_KEY]
|
||||||
|
: v.spec.query.spec,
|
||||||
datasource: v.spec.datasource,
|
datasource: v.spec.datasource,
|
||||||
sort: transformSortVariableToEnumV1(v.spec.sort),
|
sort: transformSortVariableToEnumV1(v.spec.sort),
|
||||||
refresh: transformVariableRefreshToEnumV1(v.spec.refresh),
|
refresh: transformVariableRefreshToEnumV1(v.spec.refresh),
|
||||||
|
|
Loading…
Reference in New Issue