diff --git a/CHANGELOG.md b/CHANGELOG.md index 272c752bf63..d68dc949c30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * **Playlist**: Fix for memory leak when running a playlist, closes [#3794](https://github.com/grafana/grafana/pull/3794) * **InfluxDB**: Fix for InfluxDB and table panel when using Format As Table and having group by time, fixes [#3928](https://github.com/grafana/grafana/issues/3928) * **Panel Time shift**: Fix for panel time range and using dashboard times liek `Today` and `This Week`, fixes [#3941](https://github.com/grafana/grafana/issues/3941) +* **Row repeat**: Repeated rows will now appear next to each other and not by the bottom of the dashboard, fixes [#3942](https://github.com/grafana/grafana/issues/3942) # 2.6.1 (unrelased, 2.6.x branch) diff --git a/public/app/features/dashboard/dynamicDashboardSrv.js b/public/app/features/dashboard/dynamicDashboardSrv.js index 8e3c24f7202..5c0101be10f 100644 --- a/public/app/features/dashboard/dynamicDashboardSrv.js +++ b/public/app/features/dashboard/dynamicDashboardSrv.js @@ -34,7 +34,7 @@ function (angular, _) { // handle row repeats if (row.repeat) { - this.repeatRow(row); + this.repeatRow(row, i); } // clean up old left overs else if (row.repeatRowId && row.repeatIteration !== this.iteration) { @@ -58,13 +58,13 @@ function (angular, _) { }; // returns a new row clone or reuses a clone from previous iteration - this.getRowClone = function(sourceRow, index) { - if (index === 0) { + this.getRowClone = function(sourceRow, repeatIndex, sourceRowIndex) { + if (repeatIndex === 0) { return sourceRow; } var i, panel, row, copy; - var sourceRowId = _.indexOf(this.dashboard.rows, sourceRow) + 1; + var sourceRowId = sourceRowIndex + 1; // look for row to reuse for (i = 0; i < this.dashboard.rows.length; i++) { @@ -77,7 +77,7 @@ function (angular, _) { if (!copy) { copy = angular.copy(sourceRow); - this.dashboard.rows.push(copy); + this.dashboard.rows.splice(sourceRowIndex + repeatIndex, 0, copy); // set new panel ids for (i = 0; i < copy.panels.length; i++) { @@ -92,8 +92,8 @@ function (angular, _) { return copy; }; - // returns a new panel clone or reuses a clone from previous iteration - this.repeatRow = function(row) { + // returns a new row clone or reuses a clone from previous iteration + this.repeatRow = function(row, rowIndex) { var variables = this.dashboard.templating.list; var variable = _.findWhere(variables, {name: row.repeat}); if (!variable) { @@ -108,7 +108,7 @@ function (angular, _) { } _.each(selected, function(option, index) { - copy = self.getRowClone(row, index); + copy = self.getRowClone(row, index, rowIndex); copy.scopedVars = {}; copy.scopedVars[variable.name] = option; diff --git a/public/test/specs/dynamicDashboardSrv-specs.js b/public/test/specs/dynamicDashboardSrv-specs.js index 2c3405e152f..b7ff61c3684 100644 --- a/public/test/specs/dynamicDashboardSrv-specs.js +++ b/public/test/specs/dynamicDashboardSrv-specs.js @@ -106,6 +106,7 @@ define([ repeat: 'servers', panels: [{id: 2}] }); + dash.rows.push({panels: []}); dash.templating.list.push({ name: 'servers', current: { @@ -120,14 +121,14 @@ define([ }); it('should repeat row one time', function() { - expect(ctx.rows.length).to.be(2); + expect(ctx.rows.length).to.be(3); }); 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() { + it('should keep first row as repeat', function() { expect(ctx.rows[0].repeat).to.be('servers'); }); @@ -159,7 +160,7 @@ define([ }); it('should still only have 2 rows', function() { - expect(ctx.rows.length).to.be(2); + expect(ctx.rows.length).to.be(3); }); it.skip('should have updated props from source', function() { @@ -178,7 +179,7 @@ define([ }); it('should remove repeated second row', function() { - expect(ctx.rows.length).to.be(1); + expect(ctx.rows.length).to.be(2); }); }); });