فهرست منبع

started on rows as panels in single grid

Torkel Ödegaard 8 سال پیش
والد
کامیت
55c6b4b99c

+ 65 - 0
public/app/core/directives/plugin_component.ts

@@ -7,6 +7,62 @@ import config from 'app/core/config';
 import coreModule from 'app/core/core_module';
 import {UnknownPanelCtrl} from 'app/plugins/panel/unknown/module';
 
+export class PanelRow {
+  static template = `
+    <h2 class="panel-header">Row</h2>
+    <a ng-click="ctrl.collapse()">Collapse</a>
+  `;
+
+  dashboard: any;
+  panel: any;
+
+  constructor(private $rootScope) {
+    console.log(this);
+    this.panel.hiddenPanels = this.panel.hiddenPanels || [];
+  }
+
+  collapse() {
+    if (this.panel.hiddenPanels.length > 0) {
+      let panelIndex = _.indexOf(this.dashboard.panels, this.panel);
+
+      for (let child of this.panel.hiddenPanels) {
+        this.dashboard.panels.splice(panelIndex+1, 0, child);
+        child.y = this.panel.y+1;
+        console.log('restoring child', child);
+      }
+
+      this.panel.hiddenPanels = [];
+      return;
+    }
+
+    let foundRow = false;
+    for (let i = 0; i < this.dashboard.panels.length; i++) {
+      let panel = this.dashboard.panels[i];
+
+      if (panel === this.panel) {
+        console.log('found row');
+        foundRow = true;
+        continue;
+      }
+
+      if (!foundRow) {
+        continue;
+      }
+
+      if (panel.type === 'row') {
+        break;
+      }
+
+      this.panel.hiddenPanels.push(panel);
+      console.log('hiding child', panel.id);
+    }
+
+    for (let hiddenPanel of this.panel.hiddenPanels) {
+      this.dashboard.removePanel(hiddenPanel, false);
+    }
+  }
+}
+
 /** @ngInject **/
 function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $templateCache) {
 
@@ -55,6 +111,15 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
   }
 
   function loadPanelComponentInfo(scope, attrs) {
+    if (scope.panel.type === 'row') {
+      return $q.when({
+        name: 'panel-row',
+        bindings: {dashboard: "=", panel: "="},
+        attrs: {dashboard: "ctrl.dashboard", panel: "panel"},
+        Component: PanelRow,
+      });
+    }
+
     var componentInfo: any = {
       name: 'panel-plugin-' + scope.panel.type,
       bindings: {dashboard: "=", panel: "=", row: "="},

+ 22 - 50
public/app/features/dashboard/dashgrid/dashgrid.ts

@@ -10,7 +10,7 @@ import 'gridstack.jquery-ui';
 
 const template = `
 <div class="grid-stack">
-  <dash-grid-item ng-repeat="panel in ctrl.row.panels track by panel.id"
+  <dash-grid-item ng-repeat="panel in ctrl.dashboard.panels track by panel.id"
                   class="grid-stack-item"
                   grid-ctrl="ctrl"
                   panel="panel">
@@ -24,7 +24,6 @@ var rowIndex = 0;
 
 export class GridCtrl {
   options: any;
-  row: any;
   dashboard: any;
   panels: any;
   gridstack: any;
@@ -35,6 +34,7 @@ export class GridCtrl {
 
   /** @ngInject */
   constructor(private $scope, private $element, private $timeout) {
+    console.log(this.dashboard);
     this.index = rowIndex;
     rowIndex += 1;
   }
@@ -71,71 +71,39 @@ export class GridCtrl {
 
   onGridStackItemAdded(item) {
     console.log('row: ' + this.index + ' item added', item);
-    // if item has id dont need to do anything
-    if (item.id) {
-      return;
-    }
-
-    // if this comes from another row we need to remove it
-    this.$timeout(() => this.gridstack.removeWidget(item.el, true));
   }
 
   onGridStackItemRemoved(item) {
     console.log('row: ' + this.index + ' item removed', item.id, item);
-    // ignore items that have no panel id
-    // if (!item.id) {
-    //   return;
-    // }
-    //
-    // let panel = this.dashboard.getPanelById(parseInt(item.id));
-    //
-    // if (panel) {
-    //   panelChangingRow = panel
-    //   this.row.removePanel(panel, false);
-    // }
   }
 
   onGridStackItemsChanged(items) {
-    console.log('row: ' +this.index + ' changes', items);
-
     for (let item of items) {
-      let isFromOtherRow = false;
-
-      if (!item.id) {
-        item.id  = parseInt(item.el.attr('data-gs-id'));
-        isFromOtherRow = true;
-      }
-
       // find panel
-      var panelInfo = this.dashboard.getPanelInfoById(parseInt(item.id));
+      var panel = this.dashboard.getPanelById(parseInt(item.id));
 
-      if (!panelInfo) {
-        console.log('row: ' + this.index + ' item change but no panel found for item', item);
+      if (!panel) {
+        console.log('item change but no panel found for item', item);
         continue;
       }
 
       // update panel model position
-      let panel = panelInfo.panel;
       panel.x = item.x;
       panel.y = item.y;
       panel.width = item.width;
       panel.height = item.height;
 
-      // wait a bit before adding
-      if (isFromOtherRow) {
-        let movePanelFn = (panel, row) => {
-          return this.$timeout(() => {
-            console.log('moving panel movel to another row', panel);
-            // remove from source row
-            row.removePanel(panel, false);
-            // add this this row
-            this.row.panels.push(panel);
-          });
-        };
-        movePanelFn(panelInfo.panel, panelInfo.row);
-      }
+      console.log('updating panel: ' + panel.id + ' x: ' + panel.x + ' y: ' + panel.y);
     }
 
+    this.dashboard.panels.sort(function (a, b) {
+      let aScore = a.x + (a.y * 12);
+      let bScore = b.x + (b.y * 12);
+      if (aScore < bScore) { return -1; }
+      if (aScore > bScore) { return 1; }
+      return 0;
+    });
+
     this.$scope.$broadcast('render');
   }
 
@@ -155,7 +123,6 @@ export function dashGrid($timeout) {
     bindToController: true,
     controllerAs: 'ctrl',
     scope: {
-      row: "=",
       dashboard: "=",
     },
     link: function(scope, elem, attrs, ctrl) {
@@ -181,6 +148,7 @@ export function dashGridItem($timeout, $rootScope) {
     link: function (scope, element, attrs) {
       let gridCtrl = scope.gridCtrl;
       let panel = scope.panel;
+      let gridStackNode = null;
 
       element.attr({
         'data-gs-id': panel.id,
@@ -210,15 +178,19 @@ export function dashGridItem($timeout, $rootScope) {
           return;
         }
 
-        let node = element.data('_gridstack_node');
-        if (node) {
+        if (gridStackNode) {
           console.log('grid-item scope $destroy removeWidget');
-          node._grid.removeWidget(element);
+          gridStackNode._grid.removeWidget(element);
         }
       });
 
       if (gridCtrl.isInitialized) {
         gridCtrl.gridstack.makeWidget(element);
+        gridStackNode = element.data('_gridstack_node');
+      } else {
+        setTimeout(function() {
+          gridStackNode = element.data('_gridstack_node');
+        }, 500);
       }
 
       //   scope.onItemRemoved({item: item});

+ 1 - 1
public/app/features/dashboard/dashnav/dashnav.html

@@ -69,7 +69,7 @@
 					</li>
 				</ul>
 			</li>
-			<li class="navbar-mini-btn-wrapper">
+			<li class="navbar-mini-btn-wrapper" ng-show="::ctrl.dashboard.meta.canSave">
 				<button class="btn btn-secondary btn-mini" ng-click="ctrl.openEditView('add-panel')">
 					<i class="fa fa-plus-circle"></i> Add Panel
 				</button>

+ 53 - 50
public/app/features/dashboard/model.ts

@@ -16,6 +16,8 @@ export interface Panel {
   y: number;
   width: number;
   height: number;
+  type: string;
+  title: string;
 }
 
 export const CELL_HEIGHT = 60;
@@ -48,6 +50,7 @@ export class DashboardModel {
   events: any;
   editMode: boolean;
   folderId: number;
+  panels: Panel[];
 
   constructor(data, meta?) {
     if (!data) {
@@ -77,14 +80,9 @@ export class DashboardModel {
     this.links = data.links || [];
     this.gnetId = data.gnetId || null;
     this.folderId = data.folderId || null;
+    this.panels = data.panels || [];
     this.rows = [];
 
-    if (data.rows) {
-      for (let row of data.rows) {
-        this.rows.push(new DashboardRow(row));
-      }
-    }
-
     this.initMeta(meta);
     this.updateSchema(data);
   }
@@ -158,23 +156,15 @@ export class DashboardModel {
   }
 
   forEachPanel(callback) {
-    var i, j, row;
-    for (i = 0; i < this.rows.length; i++) {
-      row = this.rows[i];
-      for (j = 0; j < row.panels.length; j++) {
-        callback(row.panels[j], j, row, i);
-      }
+    for (let i = 0; i < this.panels.length; i++) {
+      callback(this.panels[i], i);
     }
   }
 
   getPanelById(id) {
-    for (var i = 0; i < this.rows.length; i++) {
-      var row = this.rows[i];
-      for (var j = 0; j < row.panels.length; j++) {
-        var panel = row.panels[j];
-        if (panel.id === id) {
-          return panel;
-        }
+    for (let panel of this.panels) {
+      if (panel.id === id) {
+        return panel;
       }
     }
     return null;
@@ -185,25 +175,32 @@ export class DashboardModel {
     row.addPanel(panel);
   }
 
-  removeRow(row, force?) {
-    var index = _.indexOf(this.rows, row);
+  removePanel(panel, ask?) {
+    // confirm deletion
+    if (ask !== false) {
+      var text2, confirmText;
+      if (panel.alert) {
+        text2 = "Panel includes an alert rule, removing panel will also remove alert rule";
+        confirmText = "YES";
+      }
 
-    if (!row.panels.length || force) {
-      this.rows.splice(index, 1);
-      row.destroy();
+      appEvents.emit('confirm-modal', {
+        title: 'Remove Panel',
+        text: 'Are you sure you want to remove this panel?',
+        text2: text2,
+        icon: 'fa-trash',
+        confirmText: confirmText,
+        yesText: 'Remove',
+        onConfirm: () => {
+          this.removePanel(panel, false);
+        }
+      });
       return;
     }
 
-    appEvents.emit('confirm-modal', {
-      title: 'Remove Row',
-      text: 'Are you sure you want to remove this row?',
-      icon: 'fa-trash',
-      yesText: 'Delete',
-      onConfirm: () => {
-        this.rows.splice(index, 1);
-        row.destroy();
-      }
-    });
+    var index = _.indexOf(this.panels, panel);
+    this.panels.splice(index, 1);
+    this.events.emit('panel-removed', panel);
   }
 
   setPanelFocus(id) {
@@ -626,7 +623,7 @@ export class DashboardModel {
       }
 
       if (oldVersion < 15) {
-        this.upgradeToGridLayout();
+        this.upgradeToGridLayout(old);
       }
 
       if (panelUpgrades.length === 0) {
@@ -643,14 +640,28 @@ export class DashboardModel {
       }
     }
 
-    upgradeToGridLayout() {
+    upgradeToGridLayout(old) {
       let yPos = 0;
-      let firstRow = this.rows[0];
+      let rowIds = 1000;
 
-      for (let row of this.rows) {
+      for (let row of old.rows) {
         let xPos = 0;
         let height: any = row.height;
 
+        if (this.meta.keepRows) {
+          this.panels.push({
+            id: rowIds++,
+            type: 'row',
+            title: row.title,
+            x: 0,
+            y: yPos,
+            height: 1,
+            width: 12
+          });
+
+          yPos += 1;
+        }
+
         if (_.isString(height)) {
           height = parseInt(height.replace('px', ''), 10);
         }
@@ -671,21 +682,13 @@ export class DashboardModel {
           delete panel.span;
 
           xPos += panel.width;
-        }
-
-        if (!this.meta.keepRows) {
-          yPos += height;
 
-          // add to first row
-          if (row !== firstRow) {
-            firstRow.panels = firstRow.panels.concat(row.panels);
-          }
+          this.panels.push(panel);
         }
-      }
 
-      if (!this.meta.keepRows) {
-        this.rows = [firstRow];
+        yPos += height;
       }
+
+      console.log('panels', this.panels);
     }
 }
-

+ 4 - 2
public/app/features/dashboard/row/row.html

@@ -7,6 +7,8 @@
 <!-- 		<span ng&#45;class="ctrl.row.titleSize">{{ctrl.row.title | interpolateTemplateVars:this}}</span> -->
 <!-- 	</a> -->
 <!-- </div> -->
+<!--  -->
+<!-- <dash&#45;grid ng&#45;if="!ctrl.row.collapse" row="ctrl.row" dashboard="ctrl.dashboard"></dash&#45;grid> -->
+<!--  -->
 
-<dash-grid ng-if="!ctrl.row.collapse" row="ctrl.row" dashboard="ctrl.dashboard"></dash-grid>
-
+<h2>Row</h2>

+ 1 - 7
public/app/partials/dashboard.html

@@ -8,14 +8,8 @@
 
 				<dashboard-submenu ng-if="dashboard.meta.submenuEnabled" dashboard="dashboard"></dashboard-submenu>
 
-				<div class="clearfix"></div>
+        <dash-grid dashboard="dashboard"></dash-grid>
 
-				<dashboard-submenu ng-if="dashboard.meta.submenuEnabled" dashboard="dashboard"></dashboard-submenu>
-
-				<div class="clearfix"></div>
-
-				<dash-row class="dash-row" ng-repeat="row in dashboard.rows" row="row" dashboard="dashboard">
-				</dash-row>
 			</div>
 		</div>
 	</div>