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

repeat row: handle collapsed rows

Alexander Zobnin 8 лет назад
Родитель
Сommit
dd9c727e60

+ 51 - 20
public/app/features/dashboard/dashboard_model.ts

@@ -181,6 +181,14 @@ export class DashboardModel {
       if (panel.id > max) {
         max = panel.id;
       }
+
+      if (panel.collapsed) {
+        for (let rowPanel of panel.panels) {
+          if (rowPanel.id > max) {
+            max = rowPanel.id;
+          }
+        }
+      }
     }
 
     return max + 1;
@@ -266,6 +274,7 @@ export class DashboardModel {
 
     this.sortPanelsByGridPos();
     this.events.emit('repeats-processed');
+    console.log(this.panels);
   }
 
   getPanelRepeatClone(sourcePanel, valueIndex, sourcePanelIndex) {
@@ -279,11 +288,18 @@ export class DashboardModel {
 
     if (sourcePanel.type === 'row') {
       // for row clones we need to figure out panels under row to clone and where to insert clone
-      let rowPanels = this.getRowPanels(sourcePanelIndex);
-      clone.panels = _.map(rowPanels, panel => panel.getSaveModel());
-
-      // insert copied row after preceding row's panels
-      let insertPos = sourcePanelIndex + ((rowPanels.length + 1)*valueIndex);
+      let rowPanels, insertPos;
+      if (sourcePanel.collapsed) {
+        rowPanels = sourcePanel.panels;
+        clone.panels = _.cloneDeep(rowPanels);
+        // insert copied row after preceding row
+        insertPos = sourcePanelIndex + valueIndex;
+      } else {
+        rowPanels = this.getRowPanels(sourcePanelIndex);
+        clone.panels = _.map(rowPanels, panel => panel.getSaveModel());
+        // insert copied row after preceding row's panels
+        insertPos = sourcePanelIndex + ((rowPanels.length + 1)*valueIndex);
+      }
       this.panels.splice(insertPos, 0, clone);
     } else {
       // insert after source panel + value index
@@ -324,27 +340,42 @@ export class DashboardModel {
       copy.scopedVars[variable.name] = option;
 
       if (copy.type === 'row') {
-        // place row below row panels
         let rowHeight = this.getRowHeight(copy);
         if (rowHeight) {
-          copy.gridPos.y += rowHeight * index;
+          let panelsBelowIndex;
           let rowPanels = copy.panels;
-          // insert after preceding row's panels
+          // insert after 'row' panel
           let insertPos = panelIndex + ((rowPanels.length + 1) * index) + 1;
-          _.each(rowPanels, (rowPanel, i) => {
-            let cloneRowPanel = new PanelModel(rowPanel);
-            cloneRowPanel.id = this.getNextPanelId();
-            cloneRowPanel.repeatIteration = this.iteration;
-            cloneRowPanel.repeatPanelId = rowPanel.id;
-            cloneRowPanel.repeat = null;
-            cloneRowPanel.gridPos.y += rowHeight * index;
-            this.panels.splice(insertPos+i, 0, cloneRowPanel);
-          });
-          copy.panels = [];
-          yPos += rowHeight;
+
+          if (copy.collapsed) {
+            copy.gridPos.y += index;
+            yPos += index;
+            panelsBelowIndex = panelIndex + index + 1;
+            _.each(copy.panels, (panel, i) => {
+              panel.id = this.getNextPanelId();
+              panel.repeatIteration = this.iteration;
+              panel.repeatPanelId = rowPanels[i].id;
+              panel.repeat = null;
+              copy.panels[i] = panel;
+            });
+          } else {
+            _.each(rowPanels, (rowPanel, i) => {
+              let cloneRowPanel = new PanelModel(rowPanel);
+              cloneRowPanel.id = this.getNextPanelId();
+              cloneRowPanel.repeatIteration = this.iteration;
+              cloneRowPanel.repeatPanelId = rowPanel.id;
+              cloneRowPanel.repeat = null;
+              cloneRowPanel.gridPos.y += rowHeight * index;
+              this.panels.splice(insertPos+i, 0, cloneRowPanel);
+            });
+            copy.panels = [];
+            copy.gridPos.y += rowHeight * index;
+            yPos += rowHeight;
+            panelsBelowIndex = insertPos+rowPanels.length;
+          }
 
           // Update gridPos for panels below
-          for (let i = insertPos+rowPanels.length; i< this.panels.length; i++) {
+          for (let i = panelsBelowIndex; i< this.panels.length; i++) {
             this.panels[i].gridPos.y += yPos;
           }
         }

+ 53 - 3
public/app/features/dashboard/specs/repeat.jest.ts

@@ -148,10 +148,10 @@ describe('given dashboard with panel repeat in vertical direction', function() {
 });
 
 describe('given dashboard with row repeat', function() {
-  var dashboard;
+  let dashboard, dashboardJSON;
 
   beforeEach(function() {
-    dashboard = new DashboardModel({
+    dashboardJSON = {
       panels: [
         {id: 1, type: 'row',   repeat: 'apps', gridPos: {x: 0, y: 0, h: 1 , w: 24}},
         {id: 2, type: 'graph', gridPos: {x: 0, y: 1, h: 1 , w: 6}},
@@ -173,7 +173,8 @@ describe('given dashboard with row repeat', function() {
           ]
         }]
       }
-    });
+    };
+    dashboard = new DashboardModel(dashboardJSON);
     dashboard.processRepeats();
   });
 
@@ -186,6 +187,55 @@ describe('given dashboard with row repeat', function() {
     ]);
   });
 
+  it('should repeat only row if it is collapsed', function() {
+    dashboardJSON.panels = [
+        {
+          id: 1, type: 'row', collapsed: true, repeat: 'apps', gridPos: {x: 0, y: 0, h: 1 , w: 24},
+          panels: [
+            {id: 2, type: 'graph', gridPos: {x: 0, y: 1, h: 1 , w: 6}},
+            {id: 3, type: 'graph', gridPos: {x: 6, y: 1, h: 1 , w: 6}},
+          ]
+        },
+        {id: 4, type: 'row',   gridPos: {x: 0, y: 1, h: 1 , w: 24}},
+        {id: 5, type: 'graph', gridPos: {x: 0, y: 2, h: 1 , w: 12}},
+    ];
+    dashboard = new DashboardModel(dashboardJSON);
+    dashboard.processRepeats();
+
+    const panel_types = _.map(dashboard.panels, 'type');
+    expect(panel_types).toEqual([
+      'row', 'row', 'row', 'graph'
+    ]);
+    expect(dashboard.panels[0].panels).toHaveLength(2);
+    expect(dashboard.panels[1].panels).toHaveLength(2);
+  });
+
+  it('should assign unique ids for repeated panels', function() {
+    dashboardJSON.panels = [
+        {
+          id: 1, type: 'row', collapsed: true, repeat: 'apps', gridPos: {x: 0, y: 0, h: 1 , w: 24},
+          panels: [
+            {id: 2, type: 'graph', gridPos: {x: 0, y: 1, h: 1 , w: 6}},
+            {id: 3, type: 'graph', gridPos: {x: 6, y: 1, h: 1 , w: 6}},
+          ]
+        },
+        {id: 4, type: 'row',   gridPos: {x: 0, y: 1, h: 1 , w: 24}},
+        {id: 5, type: 'graph', gridPos: {x: 0, y: 2, h: 1 , w: 12}},
+    ];
+    dashboard = new DashboardModel(dashboardJSON);
+    dashboard.processRepeats();
+
+    const panel_ids = _.flattenDeep(_.map(dashboard.panels, (panel) => {
+      let ids = [];
+      if (panel.panels && panel.panels.length) {
+        ids = _.map(panel.panels, 'id');
+      }
+      ids.push(panel.id);
+      return ids;
+    }));
+    expect(panel_ids.length).toEqual(_.uniq(panel_ids).length);
+  });
+
   // it('should set scopedVars on panels', function() {
   //   expect(dashboard.panels[1].scopedVars).toMatchObject({apps: {text: 'se1', value: 'se1'}})
   // });