thingsboard-memoizeit
Changes
ui/src/app/components/dashboard.directive.js 86(+66 -20)
ui/src/app/locale/locale.constant.js 7(+7 -0)
Details
diff --git a/ui/src/app/common/dashboard-utils.service.js b/ui/src/app/common/dashboard-utils.service.js
index 915d550..0fc940d 100644
--- a/ui/src/app/common/dashboard-utils.service.js
+++ b/ui/src/app/common/dashboard-utils.service.js
@@ -215,6 +215,12 @@ function DashboardUtils(types, utils, timeService) {
row: widget.row,
col: widget.col,
};
+ if (angular.isDefined(widget.config.mobileHeight)) {
+ mainLayout.widgets[id].mobileHeight = widget.config.mobileHeight;
+ }
+ if (angular.isDefined(widget.config.mobileOrder)) {
+ mainLayout.widgets[id].mobileOrder = widget.config.mobileOrder;
+ }
}
} else {
var states = dashboard.configuration.states;
ui/src/app/components/dashboard.directive.js 86(+66 -20)
diff --git a/ui/src/app/components/dashboard.directive.js b/ui/src/app/components/dashboard.directive.js
index 1a4cdba..a722e04 100644
--- a/ui/src/app/components/dashboard.directive.js
+++ b/ui/src/app/components/dashboard.directive.js
@@ -60,6 +60,8 @@ function Dashboard() {
margins: '=',
isEdit: '=',
autofillHeight: '=',
+ mobileAutofillHeight: '=?',
+ mobileRowHeight: '=?',
isMobile: '=',
isMobileDisabled: '=?',
isEditActionEnabled: '=',
@@ -124,8 +126,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
maxRows: 100,
columns: vm.columns ? vm.columns : 24,
margins: vm.margins ? vm.margins : [10, 10],
- minSizeX: 2,
- minSizeY: 2,
+ minSizeX: 1,
+ minSizeY: 1,
defaultSizeX: 8,
defaultSizeY: 6,
resizable: {
@@ -170,6 +172,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
vm.onWidgetFullscreenChanged = onWidgetFullscreenChanged;
+ vm.isAutofillHeight = autofillHeight;
+
vm.widgetMouseDown = widgetMouseDown;
vm.widgetClicked = widgetClicked;
@@ -177,9 +181,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
vm.widgetSizeY = widgetSizeY;
vm.widgetRow = widgetRow;
vm.widgetCol = widgetCol;
- vm.widgetColor = widgetColor;
- vm.widgetBackgroundColor = widgetBackgroundColor;
- vm.widgetPadding = widgetPadding;
+ vm.widgetStyle = widgetStyle;
vm.showWidgetTitle = showWidgetTitle;
vm.hasWidgetTitleTemplate = hasWidgetTitleTemplate;
vm.widgetTitleTemplate = widgetTitleTemplate;
@@ -236,7 +238,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
});
function onGirdsterParentResize() {
- if (gridsterParent.height() && vm.autofillHeight) {
+ if (gridsterParent.height() && autofillHeight()) {
updateMobileOpts();
}
}
@@ -279,7 +281,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
delete vm.widgetLayoutInfo[widgetId];
}
}
- if (vm.autofillHeight) {
+ if (autofillHeight()) {
updateMobileOpts();
}
});
@@ -295,15 +297,13 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
function updateMobileOpts() {
var isMobileDisabled = vm.isMobileDisabled === true;
- var isMobile = vm.isMobile === true && !isMobileDisabled || vm.autofillHeight;
+ var isMobile = vm.isMobile === true && !isMobileDisabled;
var mobileBreakPoint = isMobileDisabled ? 0 : (isMobile ? 20000 : 960);
if (!isMobile && !isMobileDisabled) {
isMobile = !$mdMedia('gt-sm');
}
- var rowHeight = detectRowSize(isMobile);
-
if (vm.gridsterOpts.isMobile != isMobile) {
vm.gridsterOpts.isMobile = isMobile;
vm.gridsterOpts.mobileModeEnabled = isMobile;
@@ -311,6 +311,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
if (vm.gridsterOpts.mobileBreakPoint != mobileBreakPoint) {
vm.gridsterOpts.mobileBreakPoint = mobileBreakPoint;
}
+ var rowHeight = detectRowSize(isMobile);
if (vm.gridsterOpts.rowHeight != rowHeight) {
vm.gridsterOpts.rowHeight = rowHeight;
}
@@ -339,6 +340,14 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
updateMobileOpts();
});
+ $scope.$watch('vm.mobileAutofillHeight', function () {
+ updateMobileOpts();
+ });
+
+ $scope.$watch('vm.mobileRowHeight', function () {
+ updateMobileOpts();
+ });
+
$scope.$watch('vm.isMobileDisabled', function () {
updateMobileOpts();
});
@@ -408,32 +417,49 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
});
+ function autofillHeight() {
+ if (vm.gridsterOpts.isMobile) {
+ return angular.isDefined(vm.mobileAutofillHeight) ? vm.mobileAutofillHeight : false;
+ } else {
+ return angular.isDefined(vm.autofillHeight) ? vm.autofillHeight : false;
+ }
+ }
+
function detectRowSize(isMobile) {
- var rowHeight = isMobile ? 70 : 'match';
- if (vm.autofillHeight) {
+ var rowHeight;
+ if (autofillHeight()) {
var viewportHeight = gridsterParent.height();
var totalRows = 0;
for (var i = 0; i < vm.widgets.length; i++) {
var w = vm.widgets[i];
var sizeY = widgetSizeY(w);
- totalRows += sizeY;
+ if (isMobile) {
+ totalRows += sizeY;
+ } else {
+ var row = widgetRow(w);
+ var bottom = row + sizeY;
+ totalRows = Math.max(totalRows, bottom);
+ }
}
rowHeight = (viewportHeight - vm.gridsterOpts.margins[1]*(vm.widgets.length+1) + vm.gridsterOpts.margins[0]*vm.widgets.length) / totalRows;
+ } else if (isMobile) {
+ rowHeight = angular.isDefined(vm.mobileRowHeight) ? vm.mobileRowHeight : 70;
+ } else {
+ rowHeight = 'match';
}
return rowHeight;
}
function widgetOrder(widget) {
var order;
- if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) {
- if (angular.isDefined(vm.widgetLayouts[widget.id].mobileOrder)
+ var hasLayout = vm.widgetLayouts && vm.widgetLayouts[widget.id];
+ if (hasLayout && angular.isDefined(vm.widgetLayouts[widget.id].mobileOrder)
&& vm.widgetLayouts[widget.id].mobileOrder >= 0) {
- order = vm.widgetLayouts[widget.id].mobileOrder;
- } else {
- order = vm.widgetLayouts[widget.id].row;
- }
+ order = vm.widgetLayouts[widget.id].mobileOrder;
} else if (angular.isDefined(widget.config.mobileOrder) && widget.config.mobileOrder >= 0) {
order = widget.config.mobileOrder;
+ } else if (hasLayout) {
+ order = vm.widgetLayouts[widget.id].row;
} else {
order = widget.row;
}
@@ -722,7 +748,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
function widgetSizeY(widget) {
- if (vm.gridsterOpts.isMobile && !vm.autofillHeight) {
+ if (vm.gridsterOpts.isMobile && !vm.mobileAutofillHeight) {
var mobileHeight;
if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) {
mobileHeight = vm.widgetLayouts[widget.id].mobileHeight;
@@ -790,6 +816,18 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
}
+ function widgetStyle(widget) {
+ var style = {cursor: 'pointer',
+ color: widgetColor(widget),
+ backgroundColor: widgetBackgroundColor(widget),
+ padding: widgetPadding(widget),
+ margin: widgetMargin(widget)};
+ if (angular.isDefined(widget.config.widgetStyle)) {
+ Object.assign(style, widget.config.widgetStyle);
+ }
+ return style;
+ }
+
function widgetColor(widget) {
if (widget.config.color) {
return widget.config.color;
@@ -814,6 +852,14 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
}
+ function widgetMargin(widget) {
+ if (widget.config.margin) {
+ return widget.config.margin;
+ } else {
+ return '0px';
+ }
+ }
+
function showWidgetTitle(widget) {
if (angular.isDefined(widget.config.showTitle)) {
return widget.config.showTitle;
diff --git a/ui/src/app/components/dashboard.tpl.html b/ui/src/app/components/dashboard.tpl.html
index 5d46fea..2887419 100644
--- a/ui/src/app/components/dashboard.tpl.html
+++ b/ui/src/app/components/dashboard.tpl.html
@@ -22,7 +22,8 @@
</md-progress-circular>
</md-content>
<md-menu md-position-mode="target target" tb-mousepoint-menu>
- <md-content id="gridster-parent" class="tb-dashboard-content" flex layout-wrap ng-click="" tb-contextmenu="vm.openDashboardContextMenu($event, $mdOpenMousepointMenu)">
+ <md-content id="gridster-parent" class="tb-dashboard-content" flex layout-wrap ng-click="" ng-style="{'overflowY': vm.isAutofillHeight() ? 'hidden' : 'auto'}"
+ tb-contextmenu="vm.openDashboardContextMenu($event, $mdOpenMousepointMenu)">
<div ng-class="vm.dashboardClass" id="gridster-background" style="height: auto; min-height: 100%; display: inline;">
<div id="gridster-child" gridster="vm.gridsterOpts">
<ul>
@@ -42,10 +43,7 @@
tb-mousedown="vm.widgetMouseDown($event, widget)"
ng-click="vm.widgetClicked($event, widget)"
tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)"
- ng-style="{cursor: 'pointer',
- color: vm.widgetColor(widget),
- backgroundColor: vm.widgetBackgroundColor(widget),
- padding: vm.widgetPadding(widget)}">
+ ng-style="vm.widgetStyle(widget)">
<div class="tb-widget-title" layout="column" layout-align="center start" ng-show="vm.showWidgetTitlePanel(widget)">
<div ng-if="vm.hasWidgetTitleTemplate(widget)" ng-include="vm.widgetTitleTemplate(widget)"></div>
<span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{vm.widgetTitle(widget)}}</span>
diff --git a/ui/src/app/components/widget/widget-config.directive.js b/ui/src/app/components/widget/widget-config.directive.js
index afdaf8d..8ec91a8 100644
--- a/ui/src/app/components/widget/widget-config.directive.js
+++ b/ui/src/app/components/widget/widget-config.directive.js
@@ -64,7 +64,7 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
'*'
];
- scope.titleStyleEditorOptions = {
+ scope.styleEditorOptions = {
useWrapMode: true,
mode: 'json',
advanced: {
@@ -106,6 +106,9 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
scope.backgroundColor = config.backgroundColor;
scope.color = config.color;
scope.padding = config.padding;
+ scope.margin = config.margin;
+ scope.widgetStyle =
+ angular.toJson(angular.isDefined(config.widgetStyle) ? config.widgetStyle : {}, true);
scope.titleStyle =
angular.toJson(angular.isDefined(config.titleStyle) ? config.titleStyle : {
fontSize: '16px',
@@ -205,6 +208,12 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
ngModelCtrl.$setValidity('datasources', valid);
}
try {
+ angular.fromJson(scope.widgetStyle);
+ ngModelCtrl.$setValidity('widgetStyle', true);
+ } catch (e) {
+ ngModelCtrl.$setValidity('widgetStyle', false);
+ }
+ try {
angular.fromJson(scope.titleStyle);
ngModelCtrl.$setValidity('titleStyle', true);
} catch (e) {
@@ -215,7 +224,7 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
};
scope.$watch('title + showTitle + dropShadow + enableFullscreen + backgroundColor + color + ' +
- 'padding + titleStyle + mobileOrder + mobileHeight + units + decimals + useDashboardTimewindow + ' +
+ 'padding + margin + widgetStyle + titleStyle + mobileOrder + mobileHeight + units + decimals + useDashboardTimewindow + ' +
'alarmSearchStatus + alarmsPollingInterval + showLegend', function () {
if (ngModelCtrl.$viewValue) {
var value = ngModelCtrl.$viewValue;
@@ -228,6 +237,12 @@ function WidgetConfig($compile, $templateCache, $rootScope, $translate, $timeout
config.backgroundColor = scope.backgroundColor;
config.color = scope.color;
config.padding = scope.padding;
+ config.margin = scope.margin;
+ try {
+ config.widgetStyle = angular.fromJson(scope.widgetStyle);
+ } catch (e) {
+ config.widgetStyle = {};
+ }
try {
config.titleStyle = angular.fromJson(scope.titleStyle);
} catch (e) {
diff --git a/ui/src/app/components/widget/widget-config.tpl.html b/ui/src/app/components/widget/widget-config.tpl.html
index f2ee0f1..6851ee8 100644
--- a/ui/src/app/components/widget/widget-config.tpl.html
+++ b/ui/src/app/components/widget/widget-config.tpl.html
@@ -179,7 +179,7 @@
</md-input-container>
<div flex ng-show="showTitle">
<label translate>widget-config.title-style</label>
- <div ui-ace="titleStyleEditorOptions" ng-model="titleStyle" ng-style="{ minHeight: '100px' }">
+ <div ui-ace="styleEditorOptions" ng-model="titleStyle" ng-style="{ minHeight: '100px' }">
</div>
</div>
</div>
@@ -199,6 +199,11 @@
ng-model="enableFullscreen">{{ 'widget-config.enable-fullscreen' | translate }}
</md-checkbox>
</div>
+ <div flex>
+ <label translate>widget-config.widget-style</label>
+ <div ui-ace="styleEditorOptions" ng-model="widgetStyle" ng-style="{ minHeight: '100px' }">
+ </div>
+ </div>
</div>
<div layout='column' layout-align="center" layout-gt-sm='row' layout-align-gt-sm="start center">
<div flex
@@ -227,6 +232,10 @@
<label translate>widget-config.padding</label>
<input ng-model="padding">
</md-input-container>
+ <md-input-container flex>
+ <label translate>widget-config.margin</label>
+ <input ng-model="margin">
+ </md-input-container>
</div>
<div layout='column' layout-align="center" layout-gt-sm='row' layout-align-gt-sm="start center">
<md-input-container flex>
diff --git a/ui/src/app/dashboard/dashboard-settings.controller.js b/ui/src/app/dashboard/dashboard-settings.controller.js
index c5743c9..749b7d6 100644
--- a/ui/src/app/dashboard/dashboard-settings.controller.js
+++ b/ui/src/app/dashboard/dashboard-settings.controller.js
@@ -69,6 +69,8 @@ export default function DashboardSettingsController($scope, $mdDialog, statesCon
vm.gridSettings.columns = vm.gridSettings.columns || 24;
vm.gridSettings.margins = vm.gridSettings.margins || [10, 10];
vm.gridSettings.autoFillHeight = angular.isDefined(vm.gridSettings.autoFillHeight) ? vm.gridSettings.autoFillHeight : false;
+ vm.gridSettings.mobileAutoFillHeight = angular.isDefined(vm.gridSettings.mobileAutoFillHeight) ? vm.gridSettings.mobileAutoFillHeight : false;
+ vm.gridSettings.mobileRowHeight = angular.isDefined(vm.gridSettings.mobileRowHeight) ? vm.gridSettings.mobileRowHeight : 70;
vm.hMargin = vm.gridSettings.margins[0];
vm.vMargin = vm.gridSettings.margins[1];
vm.gridSettings.backgroundSizeMode = vm.gridSettings.backgroundSizeMode || '100%';
diff --git a/ui/src/app/dashboard/dashboard-settings.tpl.html b/ui/src/app/dashboard/dashboard-settings.tpl.html
index 427ca19..0d69287 100644
--- a/ui/src/app/dashboard/dashboard-settings.tpl.html
+++ b/ui/src/app/dashboard/dashboard-settings.tpl.html
@@ -171,6 +171,22 @@
<md-option value="auto">Original size</md-option>
</md-select>
</md-input-container>
+ <small translate>dashboard.mobile-layout</small>
+ <div flex layout="row" layout-align="start center">
+ <md-checkbox flex aria-label="{{ 'dashboard.autofill-height' | translate }}"
+ ng-model="vm.gridSettings.mobileAutoFillHeight">{{ 'dashboard.autofill-height' | translate }}
+ </md-checkbox>
+ <md-input-container flex class="md-block">
+ <label translate>dashboard.mobile-row-height</label>
+ <input ng-required="vm.gridSettings" type="number" step="any" name="mobileRowHeight" ng-model="vm.gridSettings.mobileRowHeight"
+ min="5" max="200" />
+ <div ng-messages="theForm.mobileRowHeight.$error" multiple md-auto-hide="false">
+ <div ng-message="required" translate>dashboard.mobile-row-height-required</div>
+ <div ng-message="min" translate>dashboard.min-mobile-row-height-message</div>
+ <div ng-message="max" translate>dashboard.max-mobile-row-height-message</div>
+ </div>
+ </md-input-container>
+ </div>
</div>
</fieldset>
</div>
diff --git a/ui/src/app/dashboard/layouts/dashboard-layout.tpl.html b/ui/src/app/dashboard/layouts/dashboard-layout.tpl.html
index 3df1327..90a10b1 100644
--- a/ui/src/app/dashboard/layouts/dashboard-layout.tpl.html
+++ b/ui/src/app/dashboard/layouts/dashboard-layout.tpl.html
@@ -50,6 +50,8 @@
dashboard-timewindow="vm.dashboardCtx.dashboardTimewindow"
is-edit="vm.isEdit"
autofill-height="vm.layoutCtx.gridSettings.autoFillHeight && !vm.isEdit"
+ mobile-autofill-height="vm.layoutCtx.gridSettings.mobileAutoFillHeight && !vm.isEdit"
+ mobile-row-height="vm.layoutCtx.gridSettings.mobileRowHeight"
is-mobile="vm.isMobile"
is-mobile-disabled="vm.widgetEditMode"
is-edit-action-enabled="vm.isEdit"
ui/src/app/locale/locale.constant.js 7(+7 -0)
diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js
index 4d4ebe2..819afbb 100644
--- a/ui/src/app/locale/locale.constant.js
+++ b/ui/src/app/locale/locale.constant.js
@@ -432,6 +432,11 @@ export default angular.module('thingsboard.locale', [])
"min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.",
"max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.",
"autofill-height": "Auto fill layout height",
+ "mobile-layout": "Mobile layout settings",
+ "mobile-row-height": "Mobile row height, px",
+ "mobile-row-height-required": "Mobile row height value is required.",
+ "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.",
+ "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.",
"display-title": "Display dashboard title",
"toolbar-always-open": "Keep toolbar opened",
"title-color": "Title color",
@@ -1154,6 +1159,8 @@ export default angular.module('thingsboard.locale', [])
"background-color": "Background color",
"text-color": "Text color",
"padding": "Padding",
+ "margin": "Margin",
+ "widget-style": "Widget style",
"title-style": "Title style",
"mobile-mode-settings": "Mobile mode settings",
"order": "Order",