Просмотр исходного кода

More optimizations and unit tests for panel repeats, #1888

Torkel Ödegaard 10 лет назад
Родитель
Сommit
32fe723da6

+ 31 - 15
public/app/features/dashboard/dynamicDashboardSrv.js

@@ -8,14 +8,20 @@ function (angular, _) {
   var module = angular.module('grafana.services');
 
   module.service('dynamicDashboardSrv', function()  {
+    var self = this;
+
     this.init = function(dashboard) {
-      this.iteration = 0;
+      this.dashboard = dashboard;
+      this.iteration = new Date().getTime();
 
       this.handlePanelRepeats(dashboard);
       this.handleRowRepeats(dashboard);
     };
 
     this.update = function(dashboard) {
+      this.dashboard = dashboard;
+      this.iteration = this.iteration + 1;
+
       this.handlePanelRepeats(dashboard);
       this.handleRowRepeats(dashboard);
     };
@@ -36,8 +42,6 @@ function (angular, _) {
     };
 
     this.handlePanelRepeats = function(dashboard) {
-      this.removeLinkedPanels(dashboard);
-
       var i, j, row, panel;
       for (i = 0; i < dashboard.rows.length; i++) {
         row = dashboard.rows[i];
@@ -46,6 +50,11 @@ function (angular, _) {
           if (panel.repeat) {
             this.repeatPanel(panel, row, dashboard);
           }
+          // clean up old left overs
+          else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
+            row.panels = _.without(row.panels, panel);
+            j = j - 1;
+          }
         }
       }
     };
@@ -111,13 +120,27 @@ function (angular, _) {
       });
     };
 
-    this.getRepeatPanel = function(sourcePanel, row) {
+    this.getPanelClone = function(sourcePanel, row, index) {
+      // if first clone return source
+      if (index === 0) {
+        return sourcePanel;
+      }
+
+      // first try finding an existing clone to use
       for (var i = 0; i < row.panels.length; i++) {
         var panel = row.panels[i];
-        if (panel.sourcePanel === sourcePanel) {
+        if (panel.repeatIteration !== this.iteration &&
+            panel.repeatPanelId === sourcePanel.id) {
+          panel.repeatIteration = this.iteration;
           return panel;
         }
       }
+
+      var clone = this.dashboard.duplicatePanel(sourcePanel, row);
+      clone.repeatIteration = this.iteration;
+      clone.repeatPanelId = sourcePanel.id;
+      clone.repeat = null;
+      return clone;
     };
 
     this.repeatPanel = function(panel, row, dashboard) {
@@ -135,16 +158,9 @@ function (angular, _) {
       }
 
       _.each(selected, function(option, index) {
-        if (index > 0) {
-          var copy = dashboard.duplicatePanel(panel, row);
-          copy.repeat = null;
-          copy.linked = true;
-          copy.scopedVars = {};
-          copy.scopedVars[variable.name] = option;
-        } else {
-          panel.scopedVars = {};
-          panel.scopedVars[variable.name] = option;
-        }
+        var copy = self.getPanelClone(panel, row, index);
+        copy.scopedVars = {};
+        copy.scopedVars[variable.name] = option;
       });
     };
 

+ 29 - 8
public/test/specs/dynamicDashboardSrv-specs.js

@@ -26,13 +26,10 @@ define([
           ctx.dash = ctx.dashboardSrv.create(model);
           ctx.dynamicDashboardSrv.init(ctx.dash);
           ctx.rows = ctx.dash.rows;
-
         }));
-
       };
 
       func(ctx);
-
     });
   }
 
@@ -59,10 +56,8 @@ define([
     });
 
     it('should mark panel repeated', function() {
-      expect(ctx.rows[0].panels[0].linked).to.be(undefined);
       expect(ctx.rows[0].panels[0].repeat).to.be('$apps');
-      expect(ctx.rows[0].panels[1].linked).to.be(true);
-      expect(ctx.rows[0].panels[1].repeat).to.be(null);
+      expect(ctx.rows[0].panels[1].repeatPanelId).to.be(2);
     });
 
     it('should set scopedVars on panels', function() {
@@ -70,6 +65,34 @@ define([
       expect(ctx.rows[0].panels[1].scopedVars.apps.value).to.be('se2');
     });
 
+    describe('After a second iteration', function() {
+      var repeatedPanelAfterIteration1;
+
+      beforeEach(function() {
+        repeatedPanelAfterIteration1 = ctx.rows[0].panels[1];
+        ctx.dynamicDashboardSrv.update(ctx.dash);
+      });
+
+      it('should have reused same panel instances', function() {
+        expect(ctx.rows[0].panels[1]).to.be(repeatedPanelAfterIteration1);
+      });
+
+      it('should have same panel count', function() {
+        expect(ctx.rows[0].panels.length).to.be(2);
+      });
+    });
+
+    describe('After a second iteration and selected values reduced', function() {
+      beforeEach(function() {
+        ctx.dash.templating.list[0].options[1].selected = false;
+        ctx.dynamicDashboardSrv.update(ctx.dash);
+      });
+
+      it('should clean up repeated panel', function() {
+        expect(ctx.rows[0].panels.length).to.be(1);
+      });
+    });
+
   });
 
   dynamicDashScenario('given dashboard with row repeat', function(ctx) {
@@ -110,8 +133,6 @@ define([
       expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
       expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
     });
-
   });
 
-
 });