mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 19:30:36 -06:00
fix(templating): work on fixing exporting issues when using templating variables, like data source variables, and panel repeats, requires more work #6189
This commit is contained in:
parent
9d5928ddd6
commit
98d1748e43
@ -47,7 +47,7 @@ function (coreModule, kbn, rangeUtil) {
|
||||
if (ctrl.$isEmpty(modelValue)) {
|
||||
return true;
|
||||
}
|
||||
if (viewValue.indexOf('$') === 0) {
|
||||
if (viewValue.indexOf('$') === 0 || viewValue.indexOf('+$') === 0) {
|
||||
return true; // allow template variable
|
||||
}
|
||||
var info = rangeUtil.describeTextRange(viewValue);
|
||||
|
@ -52,7 +52,7 @@ export class DashboardCtrl {
|
||||
.catch($scope.onInitFailed.bind(this, 'Templating init failed', false))
|
||||
// continue
|
||||
.finally(function() {
|
||||
dynamicDashboardSrv.init(dashboard, variableSrv);
|
||||
dynamicDashboardSrv.init(dashboard);
|
||||
dynamicDashboardSrv.process();
|
||||
|
||||
unsavedChangesSrv.init(dashboard, $scope);
|
||||
|
@ -12,12 +12,12 @@ export class DynamicDashboardSrv {
|
||||
dashboard: any;
|
||||
variables: any;
|
||||
|
||||
init(dashboard, variableSrv) {
|
||||
init(dashboard) {
|
||||
this.dashboard = dashboard;
|
||||
this.variables = variableSrv.variables;
|
||||
this.variables = dashboard.templating.list;
|
||||
}
|
||||
|
||||
process(options) {
|
||||
process(options?) {
|
||||
if (this.dashboard.snapshot || this.variables.length === 0) {
|
||||
return;
|
||||
}
|
||||
@ -31,6 +31,8 @@ export class DynamicDashboardSrv {
|
||||
// cleanup scopedVars
|
||||
for (i = 0; i < this.dashboard.rows.length; i++) {
|
||||
row = this.dashboard.rows[i];
|
||||
delete row.scopedVars;
|
||||
|
||||
for (j = 0; j < row.panels.length; j++) {
|
||||
delete row.panels[j].scopedVars;
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ export class DashExportCtrl {
|
||||
constructor(private backendSrv, dashboardSrv, datasourceSrv, $scope) {
|
||||
this.exporter = new DashboardExporter(datasourceSrv);
|
||||
|
||||
var current = dashboardSrv.getCurrent().getSaveModelClone();
|
||||
|
||||
this.exporter.makeExportable(current).then(dash => {
|
||||
this.exporter.makeExportable(dashboardSrv.getCurrent()).then(dash => {
|
||||
$scope.$apply(() => {
|
||||
this.dash = dash;
|
||||
});
|
||||
|
@ -11,19 +11,40 @@ export class DashboardExporter {
|
||||
constructor(private datasourceSrv) {
|
||||
}
|
||||
|
||||
makeExportable(dash) {
|
||||
makeExportable(dashboard) {
|
||||
var dynSrv = new DynamicDashboardSrv();
|
||||
dynSrv.init(dash, {variables: dash.templating.list});
|
||||
|
||||
// clean up repeated rows and panels,
|
||||
// this is done on the live real dashboard instance, not on a clone
|
||||
// so we need to undo this
|
||||
// this is pretty hacky and needs to be changed
|
||||
dynSrv.init(dashboard);
|
||||
dynSrv.process({cleanUpOnly: true});
|
||||
|
||||
dash.id = null;
|
||||
var saveModel = dashboard.getSaveModelClone();
|
||||
saveModel.id = null;
|
||||
|
||||
// undo repeat cleanup
|
||||
dynSrv.process();
|
||||
|
||||
var inputs = [];
|
||||
var requires = {};
|
||||
var datasources = {};
|
||||
var promises = [];
|
||||
var variableLookup: any = {};
|
||||
|
||||
for (let variable of saveModel.templating.list) {
|
||||
variableLookup[variable.name] = variable;
|
||||
}
|
||||
|
||||
var templateizeDatasourceUsage = obj => {
|
||||
// ignore data source properties that contain a variable
|
||||
if (obj.datasource && obj.datasource.indexOf('$') === 0) {
|
||||
if (variableLookup[obj.datasource.substring(1)]){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
promises.push(this.datasourceSrv.get(obj.datasource).then(ds => {
|
||||
if (ds.meta.builtIn) {
|
||||
return;
|
||||
@ -50,7 +71,7 @@ export class DashboardExporter {
|
||||
};
|
||||
|
||||
// check up panel data sources
|
||||
for (let row of dash.rows) {
|
||||
for (let row of saveModel.rows) {
|
||||
for (let panel of row.panels) {
|
||||
if (panel.datasource !== undefined) {
|
||||
templateizeDatasourceUsage(panel);
|
||||
@ -77,7 +98,7 @@ export class DashboardExporter {
|
||||
}
|
||||
|
||||
// templatize template vars
|
||||
for (let variable of dash.templating.list) {
|
||||
for (let variable of saveModel.templating.list) {
|
||||
if (variable.type === 'query') {
|
||||
templateizeDatasourceUsage(variable);
|
||||
variable.options = [];
|
||||
@ -87,7 +108,7 @@ export class DashboardExporter {
|
||||
}
|
||||
|
||||
// templatize annotations vars
|
||||
for (let annotationDef of dash.annotations.list) {
|
||||
for (let annotationDef of saveModel.annotations.list) {
|
||||
templateizeDatasourceUsage(annotationDef);
|
||||
}
|
||||
|
||||
@ -105,7 +126,7 @@ export class DashboardExporter {
|
||||
});
|
||||
|
||||
// templatize constants
|
||||
for (let variable of dash.templating.list) {
|
||||
for (let variable of saveModel.templating.list) {
|
||||
if (variable.type === 'constant') {
|
||||
var refName = 'VAR_' + variable.name.replace(' ', '_').toUpperCase();
|
||||
inputs.push({
|
||||
@ -133,7 +154,7 @@ export class DashboardExporter {
|
||||
newObj["__inputs"] = inputs;
|
||||
newObj["__requires"] = requires;
|
||||
|
||||
_.defaults(newObj, dash);
|
||||
_.defaults(newObj, saveModel);
|
||||
|
||||
return newObj;
|
||||
}).catch(err => {
|
||||
|
@ -105,7 +105,7 @@ export class DashboardModel {
|
||||
|
||||
// prepare save model
|
||||
this.rows = _.map(rows, row => row.getSaveModel());
|
||||
this.templating.list = _.map(variables, variable => variable.getSaveModel());
|
||||
this.templating.list = _.map(variables, variable => variable.getSaveModel ? variable.getSaveModel() : variable);
|
||||
|
||||
var copy = $.extend(true, {}, this);
|
||||
|
||||
|
@ -33,11 +33,11 @@ export class DashboardRow {
|
||||
}
|
||||
|
||||
getSaveModel() {
|
||||
this.model = {};
|
||||
assignModelProperties(this.model, this, this.defaults);
|
||||
|
||||
// remove properties that dont server persisted purpose
|
||||
delete this.model.isNew;
|
||||
|
||||
return this.model;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ function dynamicDashScenario(desc, func) {
|
||||
|
||||
beforeEach(angularMocks.inject(function(dashboardSrv) {
|
||||
ctx.dashboardSrv = dashboardSrv;
|
||||
ctx.variableSrv = {};
|
||||
|
||||
var model = {
|
||||
rows: [],
|
||||
@ -29,9 +28,8 @@ function dynamicDashScenario(desc, func) {
|
||||
|
||||
setupFunc(model);
|
||||
ctx.dash = ctx.dashboardSrv.create(model);
|
||||
ctx.variableSrv.variables = ctx.dash.templating.list;
|
||||
ctx.dynamicDashboardSrv = new DynamicDashboardSrv();
|
||||
ctx.dynamicDashboardSrv.init(ctx.dash, ctx.variableSrv);
|
||||
ctx.dynamicDashboardSrv.init(ctx.dash);
|
||||
ctx.dynamicDashboardSrv.process();
|
||||
ctx.rows = ctx.dash.rows;
|
||||
}));
|
||||
|
@ -34,6 +34,14 @@ describe('given dashboard with repeated panels', function() {
|
||||
options: []
|
||||
});
|
||||
|
||||
dash.templating.list.push({
|
||||
name: 'ds',
|
||||
type: 'datasource',
|
||||
query: 'testdb',
|
||||
current: {value: 'prod', text: 'prod'},
|
||||
options: []
|
||||
});
|
||||
|
||||
dash.annotations.list.push({
|
||||
name: 'logs',
|
||||
datasource: 'gfdb',
|
||||
@ -49,6 +57,7 @@ describe('given dashboard with repeated panels', function() {
|
||||
datasource: '-- Mixed --',
|
||||
targets: [{datasource: 'other'}],
|
||||
},
|
||||
{id: 5, datasource: '$ds'},
|
||||
]
|
||||
});
|
||||
|
||||
@ -87,7 +96,7 @@ describe('given dashboard with repeated panels', function() {
|
||||
});
|
||||
|
||||
it('exported dashboard should not contain repeated panels', function() {
|
||||
expect(exported.rows[0].panels.length).to.be(2);
|
||||
expect(exported.rows[0].panels.length).to.be(3);
|
||||
});
|
||||
|
||||
it('exported dashboard should not contain repeated rows', function() {
|
||||
|
@ -34,10 +34,7 @@ export class DatasourceVariable implements Variable {
|
||||
assignModelProperties(this.model, this, this.defaults);
|
||||
|
||||
// dont persist options
|
||||
if (this.refresh !== 0) {
|
||||
this.model.options = [];
|
||||
}
|
||||
|
||||
this.model.options = [];
|
||||
return this.model;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@ describe('QueryVariable', function() {
|
||||
var model = variable.getSaveModel();
|
||||
expect(model.options.length).to.be(0);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user