thingsboard-aplcache

Details

diff --git a/ui/src/app/common/dashboard-utils.service.js b/ui/src/app/common/dashboard-utils.service.js
index 64a2c64..c4b2486 100644
--- a/ui/src/app/common/dashboard-utils.service.js
+++ b/ui/src/app/common/dashboard-utils.service.js
@@ -425,12 +425,26 @@ function DashboardUtils(types, utils, timeService) {
         var prevColumns = prevGridSettings ? prevGridSettings.columns : 24;
         var ratio = gridSettings.columns / prevColumns;
         layout.gridSettings = gridSettings;
+        var maxRow = 0;
         for (var w in layout.widgets) {
             var widget = layout.widgets[w];
+            maxRow = Math.max(maxRow, widget.row + widget.sizeY);
+        }
+        var newMaxRow = Math.round(maxRow * ratio);
+        for (w in layout.widgets) {
+            widget = layout.widgets[w];
+            if (widget.row + widget.sizeY == maxRow) {
+                widget.row = Math.round(widget.row * ratio);
+                widget.sizeY = newMaxRow - widget.row;
+            } else {
+                widget.row = Math.round(widget.row * ratio);
+                widget.sizeY = Math.round(widget.sizeY * ratio);
+            }
             widget.sizeX = Math.round(widget.sizeX * ratio);
-            widget.sizeY = Math.round(widget.sizeY * ratio);
             widget.col = Math.round(widget.col * ratio);
-            widget.row = Math.round(widget.row * ratio);
+            if (widget.col + widget.sizeX > gridSettings.columns) {
+                widget.sizeX = gridSettings.columns - widget.col;
+            }
         }
     }
 
diff --git a/ui/src/app/components/dashboard.directive.js b/ui/src/app/components/dashboard.directive.js
index 36bda51..c489c32 100644
--- a/ui/src/app/components/dashboard.directive.js
+++ b/ui/src/app/components/dashboard.directive.js
@@ -235,61 +235,6 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
         removeResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
     });
 
-    $scope.$watchCollection('vm.widgets', function () {
-        var ids = [];
-        for (var i=0;i<vm.widgets.length;i++) {
-            var widget = vm.widgets[i];
-            if (!widget.id) {
-                widget.id = utils.guid();
-            }
-            ids.push(widget.id);
-        }
-        ids.sort(function (id1, id2) {
-            return id1.localeCompare(id2);
-        });
-        if (angular.equals(ids, vm.widgetIds)) {
-            return;
-        }
-        vm.widgetIds = ids;
-        for (i=0;i<vm.widgets.length;i++) {
-            widget = vm.widgets[i];
-            var layoutInfoObject = vm.widgetLayoutInfo[widget.id];
-            if (!layoutInfoObject) {
-                layoutInfoObject = {
-                    widget: widget
-                };
-                Object.defineProperty(layoutInfoObject, 'sizeX', {
-                    get: function() { return widgetSizeX(this.widget) },
-                    set: function(newSizeX) { setWidgetSizeX(this.widget, newSizeX)}
-                });
-                Object.defineProperty(layoutInfoObject, 'sizeY', {
-                    get: function() { return widgetSizeY(this.widget) },
-                    set: function(newSizeY) { setWidgetSizeY(this.widget, newSizeY)}
-                });
-                Object.defineProperty(layoutInfoObject, 'row', {
-                    get: function() { return widgetRow(this.widget) },
-                    set: function(newRow) { setWidgetRow(this.widget, newRow)}
-                });
-                Object.defineProperty(layoutInfoObject, 'col', {
-                    get: function() { return widgetCol(this.widget) },
-                    set: function(newCol) { setWidgetCol(this.widget, newCol)}
-                });
-                vm.widgetLayoutInfo[widget.id] = layoutInfoObject;
-            }
-        }
-        for (var widgetId in vm.widgetLayoutInfo) {
-            if (ids.indexOf(widgetId) === -1) {
-                delete vm.widgetLayoutInfo[widgetId];
-            }
-        }
-        sortWidgets();
-        $mdUtil.nextTick(function () {
-            if (autofillHeight()) {
-                updateMobileOpts();
-            }
-        });
-    });
-
     function onGridsterParentResize() {
         if (gridsterParent.height() && autofillHeight()) {
             updateMobileOpts();
@@ -340,38 +285,6 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
         return isMobileSize;
     }
 
-    $scope.$watch(function() { return $mdMedia('gt-sm'); }, function() {
-        updateMobileOpts();
-        sortWidgets();
-    });
-
-    $scope.$watch('vm.isMobile', function () {
-        updateMobileOpts();
-        sortWidgets();
-    });
-
-    $scope.$watch('vm.autofillHeight', function () {
-        updateMobileOpts();
-    });
-
-    $scope.$watch('vm.mobileAutofillHeight', function () {
-        updateMobileOpts();
-    });
-
-    $scope.$watch('vm.mobileRowHeight', function () {
-        updateMobileOpts();
-    });
-
-    $scope.$watch('vm.isMobileDisabled', function () {
-        updateMobileOpts();
-        sortWidgets();
-    });
-
-    $scope.$watch('vm.widgetLayouts', function () {
-        updateMobileOpts();
-        sortWidgets();
-    });
-
     $scope.$watch('vm.columns', function () {
         var columns = vm.columns ? vm.columns : 24;
         if (vm.gridsterOpts.columns != columns) {
@@ -385,6 +298,19 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
         }
     });
 
+    $scope.$watch(function() {
+        return $mdMedia('gt-sm') + ',' + vm.isMobile + ',' + vm.isMobileDisabled;
+    }, function() {
+        updateMobileOpts();
+        sortWidgets();
+    });
+
+    $scope.$watch(function() {
+        return vm.autofillHeight + ',' + vm.mobileAutofillHeight + ',' + vm.mobileRowHeight;
+    }, function () {
+        updateMobileOpts();
+    });
+
     $scope.$watch('vm.margins', function () {
         var margins = vm.margins ? vm.margins : [10, 10];
         if (!angular.equals(vm.gridsterOpts.margins, margins)) {
@@ -411,6 +337,66 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
         }
     });
 
+    $scope.$watchCollection('vm.widgets', function () {
+        var ids = [];
+        for (var i=0;i<vm.widgets.length;i++) {
+            var widget = vm.widgets[i];
+            if (!widget.id) {
+                widget.id = utils.guid();
+            }
+            ids.push(widget.id);
+        }
+        ids.sort(function (id1, id2) {
+            return id1.localeCompare(id2);
+        });
+        if (angular.equals(ids, vm.widgetIds)) {
+            return;
+        }
+        vm.widgetIds = ids;
+        for (i=0;i<vm.widgets.length;i++) {
+            widget = vm.widgets[i];
+            var layoutInfoObject = vm.widgetLayoutInfo[widget.id];
+            if (!layoutInfoObject) {
+                layoutInfoObject = {
+                    widget: widget
+                };
+                Object.defineProperty(layoutInfoObject, 'sizeX', {
+                    get: function() { return widgetSizeX(this.widget) },
+                    set: function(newSizeX) { setWidgetSizeX(this.widget, newSizeX)}
+                });
+                Object.defineProperty(layoutInfoObject, 'sizeY', {
+                    get: function() { return widgetSizeY(this.widget) },
+                    set: function(newSizeY) { setWidgetSizeY(this.widget, newSizeY)}
+                });
+                Object.defineProperty(layoutInfoObject, 'row', {
+                    get: function() { return widgetRow(this.widget) },
+                    set: function(newRow) { setWidgetRow(this.widget, newRow)}
+                });
+                Object.defineProperty(layoutInfoObject, 'col', {
+                    get: function() { return widgetCol(this.widget) },
+                    set: function(newCol) { setWidgetCol(this.widget, newCol)}
+                });
+                vm.widgetLayoutInfo[widget.id] = layoutInfoObject;
+            }
+        }
+        for (var widgetId in vm.widgetLayoutInfo) {
+            if (ids.indexOf(widgetId) === -1) {
+                delete vm.widgetLayoutInfo[widgetId];
+            }
+        }
+        sortWidgets();
+        $mdUtil.nextTick(function () {
+            if (autofillHeight()) {
+                updateMobileOpts();
+            }
+        });
+    });
+
+    $scope.$watch('vm.widgetLayouts', function () {
+        updateMobileOpts();
+        sortWidgets();
+    });
+
     $scope.$on('gridster-resized', function (event, sizes, theGridster) {
         if (checkIsLocalGridsterElement(theGridster)) {
             vm.gridster = theGridster;