diff --git a/public/app/features/dashboard-scene/serialization/__snapshots__/transformSceneToSaveModel.test.ts.snap b/public/app/features/dashboard-scene/serialization/__snapshots__/transformSceneToSaveModel.test.ts.snap index 079876876c54..f71c10f518e6 100644 --- a/public/app/features/dashboard-scene/serialization/__snapshots__/transformSceneToSaveModel.test.ts.snap +++ b/public/app/features/dashboard-scene/serialization/__snapshots__/transformSceneToSaveModel.test.ts.snap @@ -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", diff --git a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts index 8983043dc6b2..12af487dc7d3 100644 --- a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts +++ b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts @@ -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, } `); }); diff --git a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts index 33636f39849e..e11ad0143013 100644 --- a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts +++ b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts @@ -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; } diff --git a/public/app/features/dashboard-scene/serialization/testfiles/dashboard_to_load1.json b/public/app/features/dashboard-scene/serialization/testfiles/dashboard_to_load1.json index 8ced156f5c96..f5e7476efda4 100644 --- a/public/app/features/dashboard-scene/serialization/testfiles/dashboard_to_load1.json +++ b/public/app/features/dashboard-scene/serialization/testfiles/dashboard_to_load1.json @@ -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", diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts index 13f9f43c1720..d2f3d6f1992c 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts @@ -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, diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index 2f557d35e806..3ee6e03618e8 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -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'; diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts index 839e546b228b..bac01eaaaac8 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts @@ -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,