Skip to content

Commit 98d1748

Browse files
committed
fix(templating): work on fixing exporting issues when using templating variables, like data source variables, and panel repeats, requires more work grafana#6189
1 parent 9d5928d commit 98d1748

File tree

11 files changed

+51
-27
lines changed

11 files changed

+51
-27
lines changed

public/app/core/directives/ng_model_on_blur.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function (coreModule, kbn, rangeUtil) {
4747
if (ctrl.$isEmpty(modelValue)) {
4848
return true;
4949
}
50-
if (viewValue.indexOf('$') === 0) {
50+
if (viewValue.indexOf('$') === 0 || viewValue.indexOf('+$') === 0) {
5151
return true; // allow template variable
5252
}
5353
var info = rangeUtil.describeTextRange(viewValue);

public/app/features/dashboard/dashboard_ctrl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class DashboardCtrl {
5252
.catch($scope.onInitFailed.bind(this, 'Templating init failed', false))
5353
// continue
5454
.finally(function() {
55-
dynamicDashboardSrv.init(dashboard, variableSrv);
55+
dynamicDashboardSrv.init(dashboard);
5656
dynamicDashboardSrv.process();
5757

5858
unsavedChangesSrv.init(dashboard, $scope);

public/app/features/dashboard/dynamic_dashboard_srv.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ export class DynamicDashboardSrv {
1212
dashboard: any;
1313
variables: any;
1414

15-
init(dashboard, variableSrv) {
15+
init(dashboard) {
1616
this.dashboard = dashboard;
17-
this.variables = variableSrv.variables;
17+
this.variables = dashboard.templating.list;
1818
}
1919

20-
process(options) {
20+
process(options?) {
2121
if (this.dashboard.snapshot || this.variables.length === 0) {
2222
return;
2323
}
@@ -31,6 +31,8 @@ export class DynamicDashboardSrv {
3131
// cleanup scopedVars
3232
for (i = 0; i < this.dashboard.rows.length; i++) {
3333
row = this.dashboard.rows[i];
34+
delete row.scopedVars;
35+
3436
for (j = 0; j < row.panels.length; j++) {
3537
delete row.panels[j].scopedVars;
3638
}

public/app/features/dashboard/export/export_modal.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ export class DashExportCtrl {
1717
constructor(private backendSrv, dashboardSrv, datasourceSrv, $scope) {
1818
this.exporter = new DashboardExporter(datasourceSrv);
1919

20-
var current = dashboardSrv.getCurrent().getSaveModelClone();
21-
22-
this.exporter.makeExportable(current).then(dash => {
20+
this.exporter.makeExportable(dashboardSrv.getCurrent()).then(dash => {
2321
$scope.$apply(() => {
2422
this.dash = dash;
2523
});

public/app/features/dashboard/export/exporter.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,40 @@ export class DashboardExporter {
1111
constructor(private datasourceSrv) {
1212
}
1313

14-
makeExportable(dash) {
14+
makeExportable(dashboard) {
1515
var dynSrv = new DynamicDashboardSrv();
16-
dynSrv.init(dash, {variables: dash.templating.list});
16+
17+
// clean up repeated rows and panels,
18+
// this is done on the live real dashboard instance, not on a clone
19+
// so we need to undo this
20+
// this is pretty hacky and needs to be changed
21+
dynSrv.init(dashboard);
1722
dynSrv.process({cleanUpOnly: true});
1823

19-
dash.id = null;
24+
var saveModel = dashboard.getSaveModelClone();
25+
saveModel.id = null;
26+
27+
// undo repeat cleanup
28+
dynSrv.process();
2029

2130
var inputs = [];
2231
var requires = {};
2332
var datasources = {};
2433
var promises = [];
34+
var variableLookup: any = {};
35+
36+
for (let variable of saveModel.templating.list) {
37+
variableLookup[variable.name] = variable;
38+
}
2539

2640
var templateizeDatasourceUsage = obj => {
41+
// ignore data source properties that contain a variable
42+
if (obj.datasource && obj.datasource.indexOf('$') === 0) {
43+
if (variableLookup[obj.datasource.substring(1)]){
44+
return;
45+
}
46+
}
47+
2748
promises.push(this.datasourceSrv.get(obj.datasource).then(ds => {
2849
if (ds.meta.builtIn) {
2950
return;
@@ -50,7 +71,7 @@ export class DashboardExporter {
5071
};
5172

5273
// check up panel data sources
53-
for (let row of dash.rows) {
74+
for (let row of saveModel.rows) {
5475
for (let panel of row.panels) {
5576
if (panel.datasource !== undefined) {
5677
templateizeDatasourceUsage(panel);
@@ -77,7 +98,7 @@ export class DashboardExporter {
7798
}
7899

79100
// templatize template vars
80-
for (let variable of dash.templating.list) {
101+
for (let variable of saveModel.templating.list) {
81102
if (variable.type === 'query') {
82103
templateizeDatasourceUsage(variable);
83104
variable.options = [];
@@ -87,7 +108,7 @@ export class DashboardExporter {
87108
}
88109

89110
// templatize annotations vars
90-
for (let annotationDef of dash.annotations.list) {
111+
for (let annotationDef of saveModel.annotations.list) {
91112
templateizeDatasourceUsage(annotationDef);
92113
}
93114

@@ -105,7 +126,7 @@ export class DashboardExporter {
105126
});
106127

107128
// templatize constants
108-
for (let variable of dash.templating.list) {
129+
for (let variable of saveModel.templating.list) {
109130
if (variable.type === 'constant') {
110131
var refName = 'VAR_' + variable.name.replace(' ', '_').toUpperCase();
111132
inputs.push({
@@ -133,7 +154,7 @@ export class DashboardExporter {
133154
newObj["__inputs"] = inputs;
134155
newObj["__requires"] = requires;
135156

136-
_.defaults(newObj, dash);
157+
_.defaults(newObj, saveModel);
137158

138159
return newObj;
139160
}).catch(err => {

public/app/features/dashboard/model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export class DashboardModel {
105105

106106
// prepare save model
107107
this.rows = _.map(rows, row => row.getSaveModel());
108-
this.templating.list = _.map(variables, variable => variable.getSaveModel());
108+
this.templating.list = _.map(variables, variable => variable.getSaveModel ? variable.getSaveModel() : variable);
109109

110110
var copy = $.extend(true, {}, this);
111111

public/app/features/dashboard/row/row_model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ export class DashboardRow {
3333
}
3434

3535
getSaveModel() {
36+
this.model = {};
3637
assignModelProperties(this.model, this, this.defaults);
3738

3839
// remove properties that dont server persisted purpose
3940
delete this.model.isNew;
40-
4141
return this.model;
4242
}
4343

public/app/features/dashboard/specs/dynamic_dashboard_srv_specs.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ function dynamicDashScenario(desc, func) {
2020

2121
beforeEach(angularMocks.inject(function(dashboardSrv) {
2222
ctx.dashboardSrv = dashboardSrv;
23-
ctx.variableSrv = {};
2423

2524
var model = {
2625
rows: [],
@@ -29,9 +28,8 @@ function dynamicDashScenario(desc, func) {
2928

3029
setupFunc(model);
3130
ctx.dash = ctx.dashboardSrv.create(model);
32-
ctx.variableSrv.variables = ctx.dash.templating.list;
3331
ctx.dynamicDashboardSrv = new DynamicDashboardSrv();
34-
ctx.dynamicDashboardSrv.init(ctx.dash, ctx.variableSrv);
32+
ctx.dynamicDashboardSrv.init(ctx.dash);
3533
ctx.dynamicDashboardSrv.process();
3634
ctx.rows = ctx.dash.rows;
3735
}));

public/app/features/dashboard/specs/exporter_specs.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ describe('given dashboard with repeated panels', function() {
3434
options: []
3535
});
3636

37+
dash.templating.list.push({
38+
name: 'ds',
39+
type: 'datasource',
40+
query: 'testdb',
41+
current: {value: 'prod', text: 'prod'},
42+
options: []
43+
});
44+
3745
dash.annotations.list.push({
3846
name: 'logs',
3947
datasource: 'gfdb',
@@ -49,6 +57,7 @@ describe('given dashboard with repeated panels', function() {
4957
datasource: '-- Mixed --',
5058
targets: [{datasource: 'other'}],
5159
},
60+
{id: 5, datasource: '$ds'},
5261
]
5362
});
5463

@@ -87,7 +96,7 @@ describe('given dashboard with repeated panels', function() {
8796
});
8897

8998
it('exported dashboard should not contain repeated panels', function() {
90-
expect(exported.rows[0].panels.length).to.be(2);
99+
expect(exported.rows[0].panels.length).to.be(3);
91100
});
92101

93102
it('exported dashboard should not contain repeated rows', function() {

public/app/features/templating/datasource_variable.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ export class DatasourceVariable implements Variable {
3434
assignModelProperties(this.model, this, this.defaults);
3535

3636
// dont persist options
37-
if (this.refresh !== 0) {
38-
this.model.options = [];
39-
}
40-
37+
this.model.options = [];
4138
return this.model;
4239
}
4340

0 commit comments

Comments
 (0)