DashboardScene: AdHoc filters (#76115)

* DashboardScene: AdHoc filters

* Update

* minor update

* update
This commit is contained in:
Torkel Ödegaard
2023-10-10 10:17:21 +02:00
committed by GitHub
parent 7d0c4c5aa7
commit f41565626a
7 changed files with 95 additions and 16 deletions
@@ -204,13 +204,11 @@ exports[`transformSceneToSaveModel Given a scene with rows Should transform back
"B",
],
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "server",
"options": [],
"query": "A,B,C,D,E,F,E,G,H,I,J,K,L",
"skipUrlSync": false,
},
{
"current": {
@@ -223,13 +221,11 @@ exports[`transformSceneToSaveModel Given a scene with rows Should transform back
"2",
],
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "pod",
"options": [],
"query": "Bob : 1, Rob : 2,Sod : 3, Hod : 4, Cod : 5",
"skipUrlSync": false,
},
],
},
@@ -448,7 +444,16 @@ exports[`transformSceneToSaveModel Given a simple scene Should transform back to
"schemaVersion": 36,
"tags": [],
"templating": {
"list": [],
"list": [
{
"datasource": {
"type": "prometheus",
"uid": "wc2AL7L7k",
},
"name": "Filters",
"type": "adhoc",
},
],
},
"time": {
"from": "now-5m",
@@ -114,7 +114,6 @@ describe('sceneVariablesSetToVariables', () => {
"uid": "fake-std",
},
"description": "test-desc",
"hide": 0,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -123,7 +122,6 @@ describe('sceneVariablesSetToVariables', () => {
"query": "query",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
}
`);
@@ -162,7 +160,6 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": 0,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -170,7 +167,6 @@ describe('sceneVariablesSetToVariables', () => {
"options": [],
"query": "fake-std",
"regex": "",
"skipUrlSync": false,
}
`);
});
@@ -213,14 +209,12 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": 0,
"includeAll": true,
"label": "test-label",
"multi": true,
"name": "test",
"options": [],
"query": "test,test1,test2",
"skipUrlSync": false,
}
`);
});
@@ -1,5 +1,5 @@
import { SceneVariableSet, QueryVariable, CustomVariable, DataSourceVariable, ConstantVariable } from '@grafana/scenes';
import { VariableModel, VariableHide } from '@grafana/schema';
import { VariableModel, VariableHide, VariableSort } from '@grafana/schema';
export function sceneVariablesSetToVariables(set: SceneVariableSet) {
const variables: VariableModel[] = [];
@@ -29,7 +29,7 @@ export function sceneVariablesSetToVariables(set: SceneVariableSet) {
allValue: variable.state.allValue,
includeAll: variable.state.includeAll,
multi: variable.state.isMulti,
skipUrlSync: Boolean(variable.state.skipUrlSync),
skipUrlSync: variable.state.skipUrlSync,
hide: variable.state.hide || VariableHide.dontHide,
});
} else if (variable instanceof CustomVariable) {
@@ -81,5 +81,28 @@ export function sceneVariablesSetToVariables(set: SceneVariableSet) {
}
}
// Remove some defaults
for (const variable of variables) {
if (variable.hide === VariableHide.dontHide) {
delete variable.hide;
}
if (!variable.skipUrlSync) {
delete variable.skipUrlSync;
}
if (variable.label === '') {
delete variable.label;
}
if (!variable.multi) {
delete variable.multi;
}
if (variable.sort === VariableSort.disabled) {
delete variable.sort;
}
}
return variables;
}
@@ -191,7 +191,19 @@
"style": "dark",
"tags": ["gdev", "graph-ng", "demo"],
"templating": {
"list": []
"list": [
{
"datasource": {
"type": "prometheus",
"uid": "wc2AL7L7k"
},
"filters": [],
"hide": 0,
"name": "Filters",
"skipUrlSync": false,
"type": "adhoc"
}
]
},
"time": {
"from": "now-5m",
@@ -2,6 +2,7 @@ import { LoadingState } from '@grafana/data';
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
import { config } from '@grafana/runtime';
import {
AdHocFilterSet,
behaviors,
CustomVariable,
DataSourceVariable,
@@ -53,7 +54,6 @@ describe('transformSaveModelToScene', () => {
name: 'constant',
skipUrlSync: false,
type: 'constant' as VariableType,
rootStateKey: 'N4XLmH5Vz',
query: 'test',
id: 'constant',
global: false,
@@ -63,6 +63,19 @@ describe('transformSaveModelToScene', () => {
description: '',
datasource: null,
},
{
hide: 2,
name: 'CoolFilters',
type: 'adhoc' as VariableType,
datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
id: 'adhoc',
global: false,
skipUrlSync: false,
index: 3,
state: LoadingState.Done,
error: null,
description: '',
},
],
},
};
@@ -78,6 +91,8 @@ describe('transformSaveModelToScene', () => {
expect(scene.state?.$timeRange?.state.weekStart).toEqual('saturday');
expect(scene.state?.$variables?.state.variables).toHaveLength(1);
expect(scene.state.controls).toBeDefined();
expect(scene.state.controls![2]).toBeInstanceOf(AdHocFilterSet);
expect((scene.state.controls![2] as AdHocFilterSet).state.name).toBe('CoolFilters');
});
it('should apply cursor sync behavior', () => {
@@ -622,7 +637,7 @@ describe('transformSaveModelToScene', () => {
});
});
it.each(['adhoc', 'interval', 'textbox', 'system'])('should throw for unsupported (yet) variables', (type) => {
it.each(['interval', 'textbox', 'system'])('should throw for unsupported (yet) variables', (type) => {
const variable = {
name: 'query0',
type: type as VariableType,
@@ -1,4 +1,5 @@
import {
AdHocVariableModel,
ConstantVariableModel,
CustomVariableModel,
DataSourceVariableModel,
@@ -29,6 +30,7 @@ import {
SceneDataLayers,
SceneDataLayerProvider,
SceneDataLayerControls,
AdHocFilterSet,
} from '@grafana/scenes';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
@@ -150,11 +152,24 @@ function createRowFromPanelModel(row: PanelModel, content: SceneGridItemLike[]):
export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel) {
let variables: SceneVariableSet | undefined = undefined;
let layers: SceneDataLayerProvider[] = [];
let filtersSets: AdHocFilterSet[] = [];
if (oldModel.templating?.list?.length) {
const variableObjects = oldModel.templating.list
.map((v) => {
try {
if (isAdhocVariable(v)) {
filtersSets.push(
new AdHocFilterSet({
name: v.name,
datasource: v.datasource,
filters: v.filters ?? [],
baseFilters: v.baseFilters ?? [],
})
);
return null;
}
return createSceneVariableFromVariableModel(v);
} catch (err) {
console.error(err);
@@ -185,6 +200,7 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel)
const controls: SceneObject[] = [
new SceneDataLayerControls(),
new VariableValueSelectors({}),
...filtersSets,
new SceneControlsSpacer(),
new SceneTimePicker({}),
new SceneRefreshPicker({
@@ -364,3 +380,4 @@ const isCustomVariable = (v: VariableModel): v is CustomVariableModel => v.type
const isQueryVariable = (v: VariableModel): v is QueryVariableModel => v.type === 'query';
const isDataSourceVariable = (v: VariableModel): v is DataSourceVariableModel => v.type === 'datasource';
const isConstantVariable = (v: VariableModel): v is ConstantVariableModel => v.type === 'constant';
const isAdhocVariable = (v: VariableModel): v is AdHocVariableModel => v.type === 'adhoc';
@@ -10,6 +10,7 @@ import {
SceneQueryRunner,
SceneDataTransformer,
SceneVariableSet,
AdHocFilterSet,
} from '@grafana/scenes';
import {
AnnotationQuery,
@@ -70,6 +71,18 @@ export function transformSceneToSaveModel(scene: DashboardScene): Dashboard {
variables = sceneVariablesSetToVariables(variablesSet);
}
if (state.controls) {
for (const control of state.controls) {
if (control instanceof AdHocFilterSet) {
variables.push({
name: control.state.name!,
type: 'adhoc',
datasource: control.state.datasource,
});
}
}
}
const dashboard: Dashboard = {
...defaultDashboard,
title: state.title,