浏览代码

grid: progress on row support

Torkel Ödegaard 8 年之前
父节点
当前提交
9f945578b8

+ 3 - 0
public/app/core/routes/dashboard_loaders.js

@@ -21,6 +21,9 @@ function (coreModule) {
     }
     }
 
 
     dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug).then(function(result) {
     dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug).then(function(result) {
+      if ($routeParams.keepRows) {
+        result.meta.keepRows = true;
+      }
       $scope.initDashboard(result, $scope);
       $scope.initDashboard(result, $scope);
     });
     });
 
 

+ 43 - 7
public/app/features/dashboard/dashgrid/dashgrid.ts

@@ -10,7 +10,7 @@ import 'gridstack.jquery-ui';
 
 
 const template = `
 const template = `
 <div class="grid-stack">
 <div class="grid-stack">
-  <dash-grid-item ng-repeat="panel in ctrl.panels"
+  <dash-grid-item ng-repeat="panel in ctrl.row.panels track by panel.id"
                   class="grid-stack-item"
                   class="grid-stack-item"
                   grid-ctrl="ctrl"
                   grid-ctrl="ctrl"
                   panel="panel">
                   panel="panel">
@@ -22,6 +22,7 @@ const template = `
 
 
 export class GridCtrl {
 export class GridCtrl {
   options: any;
   options: any;
+  row: any;
   dashboard: any;
   dashboard: any;
   panels: any;
   panels: any;
   gridstack: any;
   gridstack: any;
@@ -29,7 +30,6 @@ export class GridCtrl {
 
 
   /** @ngInject */
   /** @ngInject */
   constructor(private $rootScope, private $element, private $timeout) {
   constructor(private $rootScope, private $element, private $timeout) {
-    this.panels = this.dashboard.panels;
   }
   }
 
 
   init() {
   init() {
@@ -39,14 +39,48 @@ export class GridCtrl {
       animate: true,
       animate: true,
       cellHeight: CELL_HEIGHT,
       cellHeight: CELL_HEIGHT,
       verticalMargin: CELL_VMARGIN,
       verticalMargin: CELL_VMARGIN,
+      acceptWidgets: '.grid-stack-item',
+      handle: '.panel-header'
     }).data('gridstack');
     }).data('gridstack');
 
 
+    this.gridElem.on('added', (e, items) => {
+      for (let item of items) {
+        this.onGridStackItemAdded(item);
+      }
+    });
+
+    this.gridElem.on('removed', (e, items) => {
+      for (let item of items) {
+        this.onGridStackItemRemoved(item);
+      }
+    });
+
     this.gridElem.on('change', (e, items) => {
     this.gridElem.on('change', (e, items) => {
-      this.$timeout(() => this.itemsChanged(items), 50);
+      this.$timeout(() => this.onGridStackItemsChanged(items), 50);
+    });
+  }
+
+  onGridStackItemAdded(item) {
+    console.log('item added', item);
+    if (this.dashboard.tempPanel) {
+      //this.gridstack.removeWidget(item.el, false);
+
+      this.$timeout(() => {
+        this.row.panels.push(this.dashboard.tempPanel);
+      });
+    }
+  }
+
+  onGridStackItemRemoved(item) {
+    console.log('item removed', item.id);
+    let panel = this.dashboard.getPanelById(parseInt(item.id));
+    this.dashboard.tempPanel = panel;
+    this.$timeout(() => {
+      this.row.removePanel(panel, false);
     });
     });
   }
   }
 
 
-  itemsChanged(items) {
+  onGridStackItemsChanged(items) {
     for (let item of items) {
     for (let item of items) {
       var panel = this.dashboard.getPanelById(parseInt(item.id));
       var panel = this.dashboard.getPanelById(parseInt(item.id));
       panel.x = item.x;
       panel.x = item.x;
@@ -63,7 +97,8 @@ export class GridCtrl {
     }
     }
   }
   }
 
 
-  removeItem(element) {
+  itemScopeDestroyed(element) {
+    console.log('itemScopeDestroyed');
     if (this.gridstack) {
     if (this.gridstack) {
       this.gridstack.removeWidget(element, false);
       this.gridstack.removeWidget(element, false);
     }
     }
@@ -84,7 +119,8 @@ export function dashGrid($timeout) {
     bindToController: true,
     bindToController: true,
     controllerAs: 'ctrl',
     controllerAs: 'ctrl',
     scope: {
     scope: {
-      dashboard: "="
+      row: "=",
+      dashboard: "=",
     },
     },
     link: function(scope, elem, attrs, ctrl) {
     link: function(scope, elem, attrs, ctrl) {
       $timeout(function() {
       $timeout(function() {
@@ -133,7 +169,7 @@ export function dashGridItem($timeout, $rootScope) {
       }, scope);
       }, scope);
 
 
       scope.$on('$destroy', () => {
       scope.$on('$destroy', () => {
-        gridCtrl.removeItem(element);
+        gridCtrl.itemScopeDestroyed(element);
       });
       });
 
 
       //   scope.onItemRemoved({item: item});
       //   scope.onItemRemoved({item: item});

+ 23 - 37
public/app/features/dashboard/model.ts

@@ -47,7 +47,6 @@ export class DashboardModel {
   meta: any;
   meta: any;
   events: any;
   events: any;
   editMode: boolean;
   editMode: boolean;
-  panels: Panel[];
   folderId: number;
   folderId: number;
 
 
   constructor(data, meta?) {
   constructor(data, meta?) {
@@ -77,18 +76,17 @@ export class DashboardModel {
     this.version = data.version || 0;
     this.version = data.version || 0;
     this.links = data.links || [];
     this.links = data.links || [];
     this.gnetId = data.gnetId || null;
     this.gnetId = data.gnetId || null;
-    this.panels = data.panels || [];
     this.folderId = data.folderId || null;
     this.folderId = data.folderId || null;
-
     this.rows = [];
     this.rows = [];
+
     if (data.rows) {
     if (data.rows) {
       for (let row of data.rows) {
       for (let row of data.rows) {
         this.rows.push(new DashboardRow(row));
         this.rows.push(new DashboardRow(row));
       }
       }
     }
     }
 
 
-    this.updateSchema(data);
     this.initMeta(meta);
     this.initMeta(meta);
+    this.updateSchema(data);
   }
   }
 
 
   private initMeta(meta) {
   private initMeta(meta) {
@@ -170,9 +168,13 @@ export class DashboardModel {
   }
   }
 
 
   getPanelById(id) {
   getPanelById(id) {
-    for (let panel of this.panels) {
-      if (panel.id === id) {
-        return panel;
+    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;
+        }
       }
       }
     }
     }
     return null;
     return null;
@@ -302,34 +304,6 @@ export class DashboardModel {
     });
     });
   }
   }
 
 
-  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";
-      }
-
-      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;
-    }
-
-    var index = _.indexOf(this.panels, panel);
-    this.panels.splice(index, 1);
-    this.events.emit('panel-removed', panel);
-  }
-
   isTimezoneUtc() {
   isTimezoneUtc() {
     return this.getTimezone() === 'utc';
     return this.getTimezone() === 'utc';
   }
   }
@@ -671,6 +645,7 @@ export class DashboardModel {
 
 
     upgradeToGridLayout() {
     upgradeToGridLayout() {
       let yPos = 0;
       let yPos = 0;
+      let firstRow = this.rows[0];
 
 
       for (let row of this.rows) {
       for (let row of this.rows) {
         let xPos = 0;
         let xPos = 0;
@@ -693,12 +668,23 @@ export class DashboardModel {
           panel.width = panel.span;
           panel.width = panel.span;
           panel.height = height;
           panel.height = height;
 
 
-          this.panels.push(panel);
+          delete panel.span;
 
 
           xPos += panel.width;
           xPos += panel.width;
         }
         }
 
 
-        yPos += height;
+        if (!this.meta.keepRows) {
+          yPos += height;
+
+          // add to first row
+          if (row !== firstRow) {
+            firstRow.panels = firstRow.panels.concat(row.panels);
+          }
+        }
+      }
+
+      if (!this.meta.keepRows) {
+        this.rows = [firstRow];
       }
       }
     }
     }
 }
 }

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

@@ -1,4 +1,4 @@
-<div class="dash-row-header" ng-if="ctrl.row.showTitle || ctrl.row.collapse">
+<div class="dash-row-header">
 	<a class="dash-row-header-title" ng-click="ctrl.toggleCollapse()">
 	<a class="dash-row-header-title" ng-click="ctrl.toggleCollapse()">
 		<span class="dash-row-collapse-toggle pointer">
 		<span class="dash-row-collapse-toggle pointer">
 			<i class="fa fa-chevron-down" ng-show="!ctrl.row.collapse"></i>
 			<i class="fa fa-chevron-down" ng-show="!ctrl.row.collapse"></i>
@@ -8,66 +8,5 @@
 	</a>
 	</a>
 </div>
 </div>
 
 
-<div ng-if="ctrl.dropView === 1">
-	<dash-row-add-panel row-ctrl="ctrl"></dash-row-add-panel>
-</div>
-
-<div ng-if="ctrl.dropView === 2">
-	<dash-row-options row-ctrl="ctrl"></dash-row-options>
-</div>
-
-<div class="panels-wrapper" ng-if="!ctrl.row.collapse">
-  <div class="dash-row-menu-container" data-click-hide ng-hide="ctrl.dashboard.meta.fullscreen">
-    <ul class="dash-row-menu" role="menu">
-      <li>
-        <a ng-click="ctrl.toggleCollapse()">
-          <i class="fa fa-minus"></i> Collapse
-        </a>
-      </li>
-      <li ng-show="ctrl.dashboard.meta.canEdit">
-        <a ng-click="ctrl.onMenuAddPanel()">
-          <i class="fa fa-plus"></i> Add Panel
-        </a>
-      </li>
-      <li ng-show="ctrl.dashboard.meta.canEdit">
-        <a ng-click="ctrl.onMenuRowOptions()">
-          <i class="fa fa-cog"></i> Row Options
-        </a>
-      </li>
-      <li ng-show="ctrl.dashboard.meta.canEdit">
-        <a ng-click="ctrl.moveRow(-1)">
-          <i class="fa fa-arrow-up"></i> Move Up
-        </a>
-      </li>
-      <li ng-show="ctrl.dashboard.meta.canEdit">
-        <a ng-click="ctrl.moveRow(1)">
-          <i class="fa fa-arrow-down"></i> Move Down
-        </a>
-      </li>
-      <li ng-show="ctrl.dashboard.meta.canEdit">
-        <a ng-click="ctrl.onMenuDeleteRow()">
-          <i class="fa fa-trash"></i> Remove
-        </a>
-      </li>
-    </ul>
-    <div class="dash-row-menu-grip">
-      <i class="fa fa-ellipsis-v"></i>
-    </div>
-  </div>
-
-  <div ng-repeat="panel in ctrl.row.panels track by panel.id" class="panel" ui-draggable="!ctrl.dashboard.meta.fullscreen" drag="panel.id" ui-on-drop="ctrl.onDrop($data, panel)" drag-handle-class="drag-handle" panel-width>
-    <plugin-component type="panel" class="panel-margin">
-    </plugin-component>
-  </div>
-
-  <div panel-drop-zone class="panel panel-drop-zone" ui-on-drop="ctrl.onDrop($data)" data-drop="true">
-    <div class="panel-margin">
-      <div class="panel-container">
-        <div class="panel-drop-zone-text"></div>
-      </div>
-    </div>
-  </div>
-
-  <div class="clearfix"></div>
-</div>
+<dash-grid row="ctrl.row" dashboard="ctrl.dashboard"></dash-grid>
 
 

+ 0 - 194
public/app/features/dashboard/row/row_ctrl.ts

@@ -16,98 +16,12 @@ export class DashRowCtrl {
   /** @ngInject */
   /** @ngInject */
   constructor(private $scope, private $rootScope, private $timeout) {
   constructor(private $scope, private $rootScope, private $timeout) {
     this.row.title = this.row.title || 'Row title';
     this.row.title = this.row.title || 'Row title';
-
-    if (this.row.isNew) {
-      this.dropView = 1;
-    }
-  }
-
-  onDrop(panelId, dropTarget) {
-    var dragObject;
-
-    // if string it's a panel type
-    if (_.isString(panelId)) {
-      // setup new panel
-      dragObject = {
-        row: this.row,
-        panel: {
-          title: config.new_panel_title,
-          type: panelId,
-          id: this.dashboard.getNextPanelId(),
-          isNew: true,
-        },
-      };
-    } else {
-      dragObject = this.dashboard.getPanelInfoById(panelId);
-    }
-
-    if (dropTarget) {
-      dropTarget = this.dashboard.getPanelInfoById(dropTarget.id);
-      // if draging new panel onto existing panel split it
-      if (dragObject.panel.isNew) {
-        dragObject.panel.span = dropTarget.panel.span = dropTarget.panel.span/2;
-        // insert after
-        dropTarget.row.panels.splice(dropTarget.index+1, 0, dragObject.panel);
-      } else if (this.row === dragObject.row) {
-        // just move element
-        this.row.movePanel(dragObject.index, dropTarget.index);
-      } else {
-        // split drop target space
-        dragObject.panel.span = dropTarget.panel.span = dropTarget.panel.span/2;
-        // insert after
-        dropTarget.row.panels.splice(dropTarget.index+1, 0, dragObject.panel);
-        // remove from source row
-        dragObject.row.removePanel(dragObject.panel, false);
-      }
-    } else {
-      dragObject.panel.span = 12 - this.row.span;
-      this.row.panels.push(dragObject.panel);
-
-      // if not new remove from source row
-      if (!dragObject.panel.isNew) {
-        dragObject.row.removePanel(dragObject.panel, false);
-      }
-    }
-
-    this.dropView = 0;
-    this.row.panelSpanChanged();
-    this.$timeout(() => {
-      this.$rootScope.$broadcast('render');
-    });
-  }
-
-  setHeight(height) {
-    this.row.height = height;
-    this.$scope.$broadcast('render');
-  }
-
-  moveRow(direction) {
-    var rowsList = this.dashboard.rows;
-    var rowIndex = _.indexOf(rowsList, this.row);
-    var newIndex = rowIndex + direction;
-
-    if (newIndex >= 0 && newIndex <= (rowsList.length - 1)) {
-      _.move(rowsList, rowIndex, newIndex);
-    }
   }
   }
 
 
   toggleCollapse() {
   toggleCollapse() {
-    this.closeDropView();
     this.row.collapse = !this.row.collapse;
     this.row.collapse = !this.row.collapse;
   }
   }
 
 
-  onMenuAddPanel() {
-    this.dropView = 1;
-  }
-
-  onMenuRowOptions() {
-    this.dropView = 2;
-  }
-
-  closeDropView() {
-    this.dropView = 0;
-  }
-
   onMenuDeleteRow() {
   onMenuDeleteRow() {
     this.dashboard.removeRow(this.row);
     this.dashboard.removeRow(this.row);
   }
   }
@@ -127,116 +41,8 @@ coreModule.directive('dashRow', function($rootScope) {
     link: function(scope, element) {
     link: function(scope, element) {
       scope.$watchGroup(['ctrl.row.collapse', 'ctrl.row.height'], function() {
       scope.$watchGroup(['ctrl.row.collapse', 'ctrl.row.height'], function() {
         element.toggleClass('dash-row--collapse', scope.ctrl.row.collapse);
         element.toggleClass('dash-row--collapse', scope.ctrl.row.collapse);
-        element.find('.panels-wrapper').css({minHeight: scope.ctrl.row.collapse ? '5px' : scope.ctrl.row.height});
       });
       });
-
-      $rootScope.onAppEvent('panel-fullscreen-enter', function(evt, info) {
-        var hasPanel = _.find(scope.ctrl.row.panels, {id: info.panelId});
-        if (!hasPanel) {
-          element.hide();
-        }
-      }, scope);
-
-      $rootScope.onAppEvent('panel-fullscreen-exit', function() {
-        element.show();
-      }, scope);
-    }
-  };
-});
-
-coreModule.directive('panelWidth', function($rootScope) {
-  return function(scope, element) {
-    var fullscreen = false;
-
-    function updateWidth() {
-      if (!fullscreen) {
-        element[0].style.width = ((scope.panel.span / 1.2) * 10) + '%';
-      }
-    }
-
-    $rootScope.onAppEvent('panel-fullscreen-enter', function(evt, info) {
-      fullscreen = true;
-
-      if (scope.panel.id !== info.panelId) {
-        element.hide();
-      } else {
-        element[0].style.width = '100%';
-      }
-    }, scope);
-
-    $rootScope.onAppEvent('panel-fullscreen-exit', function(evt, info) {
-      fullscreen = false;
-
-      if (scope.panel.id !== info.panelId) {
-        element.show();
-      }
-
-      updateWidth();
-    }, scope);
-
-    scope.$watch('panel.span', updateWidth);
-
-    if (fullscreen) {
-      element.hide();
     }
     }
   };
   };
 });
 });
 
 
-
-coreModule.directive('panelDropZone', function($timeout) {
-  return function(scope, element) {
-    var row = scope.ctrl.row;
-    var dashboard = scope.ctrl.dashboard;
-    var indrag = false;
-    var textEl = element.find('.panel-drop-zone-text');
-
-    function showPanel(span, text) {
-      element.find('.panel-container').css('height', row.height);
-      element[0].style.width = ((span / 1.2) * 10) + '%';
-      textEl.text(text);
-      element.show();
-    }
-
-    function hidePanel() {
-      element.hide();
-    }
-
-    function updateState() {
-      if (row.panels.length === 0 && indrag === false) {
-        return showPanel(12, 'Empty Space');
-      }
-
-      var dropZoneSpan = 12 - row.span;
-      if (dropZoneSpan > 0) {
-        if (indrag)  {
-          return showPanel(dropZoneSpan, 'Drop Here');
-        } else {
-          return showPanel(dropZoneSpan, 'Empty Space');
-        }
-      }
-
-      if (indrag === true) {
-        if (dropZoneSpan > 1) {
-          return showPanel(dropZoneSpan, 'Drop Here');
-        }
-      }
-
-      hidePanel();
-    }
-
-    row.events.on('span-changed', updateState, scope);
-
-    scope.$on("ANGULAR_DRAG_START", function() {
-      indrag = true;
-      updateState();
-    });
-
-    scope.$on("ANGULAR_DRAG_END", function() {
-      indrag = false;
-      updateState();
-    });
-
-    updateState();
-  };
-});
-

+ 2 - 3
public/app/partials/dashboard.html

@@ -9,9 +9,8 @@
 
 
 		<div class="clearfix"></div>
 		<div class="clearfix"></div>
 
 
-		<dash-grid dashboard="dashboard">
-
-		</dash-grid>
+    <dash-row class="dash-row" ng-repeat="row in dashboard.rows" row="row" dashboard="dashboard">
+    </dash-row>
 
 
     <div ng-show='dashboard.meta.canEdit && !dashboard.meta.fullscreen' class="add-row-panel-hint">
     <div ng-show='dashboard.meta.canEdit && !dashboard.meta.fullscreen' class="add-row-panel-hint">
       <div class="span12" style="text-align:left;">
       <div class="span12" style="text-align:left;">