diff --git a/CHANGELOG.md b/CHANGELOG.md index 70aaa67ab22..d0358f7e572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # 2.1.0 (unreleased - master branch) +**New dashboard features** +- [Issue #1144](https://github.com/grafana/grafana/issues/1144). Templating: You can now select multiple template variables values at the same time. +- [Issue #1888](https://github.com/grafana/grafana/issues/1144). Templating: Repeat panel or row for each selected template variable value + **Backend** - [Issue #1905](https://github.com/grafana/grafana/issues/1905). Github OAuth: You can now configure a Github team membership requirement, thx @dewski diff --git a/public/app/directives/all.js b/public/app/directives/all.js index 3ef0b669d6c..4ab92d111d6 100644 --- a/public/app/directives/all.js +++ b/public/app/directives/all.js @@ -11,7 +11,7 @@ define([ './spectrumPicker', './bootstrap-tagsinput', './bodyClass', - './templateParamSelector', + './variableValueSelect', './graphiteSegment', './grafanaVersionCheck', './dropdown.typeahead', diff --git a/public/app/directives/templateParamSelector.js b/public/app/directives/variableValueSelect.js similarity index 100% rename from public/app/directives/templateParamSelector.js rename to public/app/directives/variableValueSelect.js diff --git a/public/app/features/dashboard/dynamicDashboardSrv.js b/public/app/features/dashboard/dynamicDashboardSrv.js index cfa824e3402..dcb4e31340c 100644 --- a/public/app/features/dashboard/dynamicDashboardSrv.js +++ b/public/app/features/dashboard/dynamicDashboardSrv.js @@ -28,7 +28,17 @@ function (angular, _) { for (i = 0; i < this.dashboard.rows.length; i++) { row = this.dashboard.rows[i]; - // repeat panels first + // handle row repeats + if (row.repeat) { + this.repeatRow(row); + } + // clean up old left overs + else if (row.repeatRowId && row.repeatIteration !== this.iteration) { + this.dashboard.rows.splice(i, 1); + i = i - 1; + } + + // repeat panels for (j = 0; j < row.panels.length; j++) { panel = row.panels[j]; if (panel.repeat) { @@ -40,16 +50,6 @@ function (angular, _) { j = j - 1; } } - - // handle row repeats - if (row.repeat) { - this.repeatRow(row); - } - // clean up old left overs - else if (row.repeatRowId && row.repeatIteration !== this.iteration) { - this.dashboard.rows.splice(i, 1); - i = i - 1; - } } }; @@ -108,7 +108,7 @@ function (angular, _) { for (i = 0; i < copy.panels.length; i++) { panel = copy.panels[i]; - panel.scopedVars = panel.scopedVars || {}; + panel.scopedVars = {}; panel.scopedVars[variable.name] = option; } }); @@ -139,7 +139,7 @@ function (angular, _) { // save id tmpId = clone.id; // copy properties from source - angular.extend(clone, sourcePanel); + angular.copy(sourcePanel, clone); // restore id clone.id = tmpId; clone.repeatIteration = this.iteration; @@ -162,11 +162,10 @@ function (angular, _) { _.each(selected, function(option, index) { var copy = self.getPanelClone(panel, row, index); - copy.scopedVars = {}; + copy.scopedVars = copy.scopedVars || {}; copy.scopedVars[variable.name] = option; }); }; }); - }); diff --git a/public/app/partials/roweditor.html b/public/app/partials/roweditor.html index 37e258a9b89..5780d624302 100644 --- a/public/app/partials/roweditor.html +++ b/public/app/partials/roweditor.html @@ -34,7 +34,7 @@
  • -
  • +
  • diff --git a/public/test/specs/dynamicDashboardSrv-specs.js b/public/test/specs/dynamicDashboardSrv-specs.js index 08a2f1af561..905b8896cd4 100644 --- a/public/test/specs/dynamicDashboardSrv-specs.js +++ b/public/test/specs/dynamicDashboardSrv-specs.js @@ -177,4 +177,61 @@ define([ }); }); }); + + dynamicDashScenario('given dashboard with row repeat and panel repeat', function(ctx) { + ctx.setup(function(dash) { + dash.rows.push({ + repeat: 'servers', + panels: [{id: 2, repeat: 'metric'}] + }); + dash.templating.list.push({ + name: 'servers', + current: { text: 'se1, se2', value: ['se1', 'se2'] }, + options: [ + {text: 'se1', value: 'se1', selected: true}, + {text: 'se2', value: 'se2', selected: true}, + ] + }); + dash.templating.list.push({ + name: 'metric', + current: { text: 'm1, m2', value: ['m1', 'm2'] }, + options: [ + {text: 'm1', value: 'm1', selected: true}, + {text: 'm2', value: 'm2', selected: true}, + ] + }); + }); + + it('should repeat row one time', function() { + expect(ctx.rows.length).to.be(2); + }); + + it('should repeat panel on both rows', function() { + expect(ctx.rows[0].panels.length).to.be(2); + expect(ctx.rows[1].panels.length).to.be(2); + }); + + it('should keep panel ids on first row', function() { + expect(ctx.rows[0].panels[0].id).to.be(2); + }); + + it('should mark second row as repeated', function() { + expect(ctx.rows[0].repeat).to.be('servers'); + }); + + it('should clear repeat field on repeated row', function() { + expect(ctx.rows[1].repeat).to.be(null); + }); + + it('should generate a repeartRowId based on repeat row index', function() { + expect(ctx.rows[1].repeatRowId).to.be(1); + }); + + it('should set scopedVars on row panels', function() { + expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1'); + expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2'); + }); + + }); + });