From 9f945578b8331e0dc4eaceb6a7644ae48007ce67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 10 Aug 2017 17:17:15 +0200 Subject: [PATCH] grid: progress on row support --- public/app/core/routes/dashboard_loaders.js | 3 + .../features/dashboard/dashgrid/dashgrid.ts | 50 ++++- public/app/features/dashboard/model.ts | 60 +++--- public/app/features/dashboard/row/row.html | 65 +----- public/app/features/dashboard/row/row_ctrl.ts | 194 ------------------ public/app/partials/dashboard.html | 5 +- 6 files changed, 73 insertions(+), 304 deletions(-) diff --git a/public/app/core/routes/dashboard_loaders.js b/public/app/core/routes/dashboard_loaders.js index 869f486fbfd..91bbff84100 100644 --- a/public/app/core/routes/dashboard_loaders.js +++ b/public/app/core/routes/dashboard_loaders.js @@ -21,6 +21,9 @@ function (coreModule) { } dashboardLoaderSrv.loadDashboard($routeParams.type, $routeParams.slug).then(function(result) { + if ($routeParams.keepRows) { + result.meta.keepRows = true; + } $scope.initDashboard(result, $scope); }); diff --git a/public/app/features/dashboard/dashgrid/dashgrid.ts b/public/app/features/dashboard/dashgrid/dashgrid.ts index 6b9c6c360b8..ccadf1c0592 100644 --- a/public/app/features/dashboard/dashgrid/dashgrid.ts +++ b/public/app/features/dashboard/dashgrid/dashgrid.ts @@ -10,7 +10,7 @@ import 'gridstack.jquery-ui'; const template = `
- @@ -22,6 +22,7 @@ const template = ` export class GridCtrl { options: any; + row: any; dashboard: any; panels: any; gridstack: any; @@ -29,7 +30,6 @@ export class GridCtrl { /** @ngInject */ constructor(private $rootScope, private $element, private $timeout) { - this.panels = this.dashboard.panels; } init() { @@ -39,14 +39,48 @@ export class GridCtrl { animate: true, cellHeight: CELL_HEIGHT, verticalMargin: CELL_VMARGIN, + acceptWidgets: '.grid-stack-item', + handle: '.panel-header' }).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.$timeout(() => this.itemsChanged(items), 50); + this.$timeout(() => this.onGridStackItemsChanged(items), 50); }); } - itemsChanged(items) { + 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); + }); + } + + onGridStackItemsChanged(items) { for (let item of items) { var panel = this.dashboard.getPanelById(parseInt(item.id)); panel.x = item.x; @@ -63,7 +97,8 @@ export class GridCtrl { } } - removeItem(element) { + itemScopeDestroyed(element) { + console.log('itemScopeDestroyed'); if (this.gridstack) { this.gridstack.removeWidget(element, false); } @@ -84,7 +119,8 @@ export function dashGrid($timeout) { bindToController: true, controllerAs: 'ctrl', scope: { - dashboard: "=" + row: "=", + dashboard: "=", }, link: function(scope, elem, attrs, ctrl) { $timeout(function() { @@ -133,7 +169,7 @@ export function dashGridItem($timeout, $rootScope) { }, scope); scope.$on('$destroy', () => { - gridCtrl.removeItem(element); + gridCtrl.itemScopeDestroyed(element); }); // scope.onItemRemoved({item: item}); diff --git a/public/app/features/dashboard/model.ts b/public/app/features/dashboard/model.ts index 635485952d1..e9026447dab 100644 --- a/public/app/features/dashboard/model.ts +++ b/public/app/features/dashboard/model.ts @@ -47,7 +47,6 @@ export class DashboardModel { meta: any; events: any; editMode: boolean; - panels: Panel[]; folderId: number; constructor(data, meta?) { @@ -77,18 +76,17 @@ export class DashboardModel { this.version = data.version || 0; this.links = data.links || []; this.gnetId = data.gnetId || null; - this.panels = data.panels || []; this.folderId = data.folderId || null; - this.rows = []; + if (data.rows) { for (let row of data.rows) { this.rows.push(new DashboardRow(row)); } } - this.updateSchema(data); this.initMeta(meta); + this.updateSchema(data); } private initMeta(meta) { @@ -170,9 +168,13 @@ export class DashboardModel { } 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; @@ -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() { return this.getTimezone() === 'utc'; } @@ -671,6 +645,7 @@ export class DashboardModel { upgradeToGridLayout() { let yPos = 0; + let firstRow = this.rows[0]; for (let row of this.rows) { let xPos = 0; @@ -693,12 +668,23 @@ export class DashboardModel { panel.width = panel.span; panel.height = height; - this.panels.push(panel); + delete panel.span; 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]; } } } diff --git a/public/app/features/dashboard/row/row.html b/public/app/features/dashboard/row/row.html index 3beddaf7844..4d2fbd9e4cd 100644 --- a/public/app/features/dashboard/row/row.html +++ b/public/app/features/dashboard/row/row.html @@ -1,4 +1,4 @@ -
+ -
- -
- -
- -
- -
- - -
- - -
- -
-
-
-
-
-
-
- -
-
+ diff --git a/public/app/features/dashboard/row/row_ctrl.ts b/public/app/features/dashboard/row/row_ctrl.ts index 34b03b3c3be..d2aa50de627 100644 --- a/public/app/features/dashboard/row/row_ctrl.ts +++ b/public/app/features/dashboard/row/row_ctrl.ts @@ -16,98 +16,12 @@ export class DashRowCtrl { /** @ngInject */ constructor(private $scope, private $rootScope, private $timeout) { 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() { - this.closeDropView(); this.row.collapse = !this.row.collapse; } - onMenuAddPanel() { - this.dropView = 1; - } - - onMenuRowOptions() { - this.dropView = 2; - } - - closeDropView() { - this.dropView = 0; - } - onMenuDeleteRow() { this.dashboard.removeRow(this.row); } @@ -127,116 +41,8 @@ coreModule.directive('dashRow', function($rootScope) { link: function(scope, element) { scope.$watchGroup(['ctrl.row.collapse', 'ctrl.row.height'], function() { 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(); - }; -}); - diff --git a/public/app/partials/dashboard.html b/public/app/partials/dashboard.html index cb32a9a667b..b25ba94ff84 100644 --- a/public/app/partials/dashboard.html +++ b/public/app/partials/dashboard.html @@ -9,9 +9,8 @@
- - - + +