diff --git a/ui/package.json b/ui/package.json
index 5f00611bff..ddcc96e4f7 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -33,6 +33,7 @@
"angular-messages": "1.5.8",
"angular-route": "1.5.8",
"angular-sanitize": "1.5.8",
+ "angular-socialshare": "^2.3.8",
"angular-storage": "0.0.15",
"angular-touch": "1.5.8",
"angular-translate": "2.13.1",
diff --git a/ui/src/app/app.js b/ui/src/app/app.js
index e3b36e3c6b..290e9cdf1c 100644
--- a/ui/src/app/app.js
+++ b/ui/src/app/app.js
@@ -19,6 +19,7 @@ import angular from 'angular';
import ngMaterial from 'angular-material';
import ngMdIcons from 'angular-material-icons';
import ngCookies from 'angular-cookies';
+import angularSocialshare from 'angular-socialshare';
import 'angular-translate';
import 'angular-translate-loader-static-files';
import 'angular-translate-storage-local';
@@ -82,6 +83,7 @@ angular.module('thingsboard', [
ngMaterial,
ngMdIcons,
ngCookies,
+ angularSocialshare,
'pascalprecht.translate',
'mdColorPicker',
mdPickers,
diff --git a/ui/src/app/common/utils.service.js b/ui/src/app/common/utils.service.js
index 09d0fc894b..6e05bbbf6c 100644
--- a/ui/src/app/common/utils.service.js
+++ b/ui/src/app/common/utils.service.js
@@ -106,7 +106,8 @@ function Utils($mdColorPalette, $rootScope, $window, $q, deviceService, types) {
isDescriptorSchemaNotEmpty: isDescriptorSchemaNotEmpty,
filterSearchTextEntities: filterSearchTextEntities,
guid: guid,
- createDatasoucesFromSubscriptionsInfo: createDatasoucesFromSubscriptionsInfo
+ createDatasoucesFromSubscriptionsInfo: createDatasoucesFromSubscriptionsInfo,
+ isLocalUrl: isLocalUrl
}
return service;
@@ -428,4 +429,15 @@ function Utils($mdColorPalette, $rootScope, $window, $q, deviceService, types) {
return deferred.promise;
}
+ function isLocalUrl(url) {
+ var parser = document.createElement('a'); //eslint-disable-line
+ parser.href = url;
+ var host = parser.hostname;
+ if (host === "localhost" || host === "127.0.0.1") {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
}
diff --git a/ui/src/app/components/socialshare-panel.directive.js b/ui/src/app/components/socialshare-panel.directive.js
new file mode 100644
index 0000000000..891d91368e
--- /dev/null
+++ b/ui/src/app/components/socialshare-panel.directive.js
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* eslint-disable import/no-unresolved, import/default */
+
+import socialsharePanelTemplate from './socialshare-panel.tpl.html';
+
+/* eslint-enable import/no-unresolved, import/default */
+
+
+export default angular.module('thingsboard.directives.socialsharePanel', [])
+ .directive('tbSocialSharePanel', SocialsharePanel)
+ .name;
+
+/*@ngInject*/
+function SocialsharePanel() {
+ return {
+ restrict: "E",
+ scope: true,
+ bindToController: {
+ shareTitle: '@',
+ shareText: '@',
+ shareLink: '@',
+ shareHashTags: '@'
+ },
+ controller: SocialsharePanelController,
+ controllerAs: 'vm',
+ templateUrl: socialsharePanelTemplate
+ };
+}
+
+/*@ngInject*/
+function SocialsharePanelController(utils) {
+
+ let vm = this;
+
+ vm.isShareLinkLocal = function() {
+ if (vm.shareLink && vm.shareLink.length > 0) {
+ return utils.isLocalUrl(vm.shareLink);
+ } else {
+ return true;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/components/socialshare-panel.tpl.html b/ui/src/app/components/socialshare-panel.tpl.html
new file mode 100644
index 0000000000..7b9560de36
--- /dev/null
+++ b/ui/src/app/components/socialshare-panel.tpl.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+ {{ 'action.share-via' | translate:{provider:'Facebook'} }}
+
+
+
+
+
+ {{ 'action.share-via' | translate:{provider:'Twitter'} }}
+
+
+
+
+
+ {{ 'action.share-via' | translate:{provider:'Linkedin'} }}
+
+
+
+
+
+ {{ 'action.share-via' | translate:{provider:'Reddit'} }}
+
+
+
\ No newline at end of file
diff --git a/ui/src/app/dashboard/dashboard-fieldset.tpl.html b/ui/src/app/dashboard/dashboard-fieldset.tpl.html
index 1d11fb2c60..954d881588 100644
--- a/ui/src/app/dashboard/dashboard-fieldset.tpl.html
+++ b/ui/src/app/dashboard/dashboard-fieldset.tpl.html
@@ -36,20 +36,28 @@
dashboard.assignedToCustomer
-
-
- dashboard.public-link
-
-
-
-
-
- {{ 'dashboard.copy-public-link' | translate }}
-
-
+
+
+
+
+
+ dashboard.public-link
+
+
+
+
+
+ {{ 'dashboard.copy-public-link' | translate }}
+
+
+
diff --git a/ui/src/app/dashboard/dashboard-settings.controller.js b/ui/src/app/dashboard/dashboard-settings.controller.js
index aac6da3dd0..06c64eb757 100644
--- a/ui/src/app/dashboard/dashboard-settings.controller.js
+++ b/ui/src/app/dashboard/dashboard-settings.controller.js
@@ -31,6 +31,18 @@ export default function DashboardSettingsController($scope, $mdDialog, gridSetti
vm.gridSettings.showTitle = true;
}
+ if (angular.isUndefined(vm.gridSettings.showDevicesSelect)) {
+ vm.gridSettings.showDevicesSelect = true;
+ }
+
+ if (angular.isUndefined(vm.gridSettings.showDashboardTimewindow)) {
+ vm.gridSettings.showDashboardTimewindow = true;
+ }
+
+ if (angular.isUndefined(vm.gridSettings.showDashboardExport)) {
+ vm.gridSettings.showDashboardExport = true;
+ }
+
vm.gridSettings.backgroundColor = vm.gridSettings.backgroundColor || 'rgba(0,0,0,0)';
vm.gridSettings.titleColor = vm.gridSettings.titleColor || 'rgba(0,0,0,0.870588)';
vm.gridSettings.columns = vm.gridSettings.columns || 24;
diff --git a/ui/src/app/dashboard/dashboard-settings.tpl.html b/ui/src/app/dashboard/dashboard-settings.tpl.html
index 2ed25d3edf..ec6f28b369 100644
--- a/ui/src/app/dashboard/dashboard-settings.tpl.html
+++ b/ui/src/app/dashboard/dashboard-settings.tpl.html
@@ -48,6 +48,17 @@
md-color-history="false"
>
+
+ {{ 'dashboard.display-device-selection' | translate }}
+
+ {{ 'dashboard.display-dashboard-timewindow' | translate }}
+
+ {{ 'dashboard.display-dashboard-export' | translate }}
+
+
dashboard.columns-count
-
{{ 'dashboard.export' | translate }}
file_download
-
+
-
@@ -304,6 +309,6 @@
diff --git a/ui/src/app/dashboard/dashboards.controller.js b/ui/src/app/dashboard/dashboards.controller.js
index d0fa95860c..134baffc59 100644
--- a/ui/src/app/dashboard/dashboards.controller.js
+++ b/ui/src/app/dashboard/dashboards.controller.js
@@ -224,7 +224,7 @@ export function DashboardsController(userService, dashboardService, customerServ
onAction: function ($event, item) {
unassignFromCustomer($event, item, true);
},
- name: function() { return $translate.instant('action.unshare') },
+ name: function() { return $translate.instant('action.make-private') },
details: function() { return $translate.instant('dashboard.make-private') },
icon: "reply",
isEnabled: function(dashboard) {
@@ -329,7 +329,7 @@ export function DashboardsController(userService, dashboardService, customerServ
onAction: function ($event, item) {
unassignFromCustomer($event, item, true);
},
- name: function() { return $translate.instant('action.unshare') },
+ name: function() { return $translate.instant('action.make-private') },
details: function() { return $translate.instant('dashboard.make-private') },
icon: "reply",
isEnabled: function(dashboard) {
@@ -404,7 +404,28 @@ export function DashboardsController(userService, dashboardService, customerServ
}
function saveDashboard(dashboard) {
- return dashboardService.saveDashboard(dashboard);
+ var deferred = $q.defer();
+ dashboardService.saveDashboard(dashboard).then(
+ function success(savedDashboard) {
+ var dashboards = [ savedDashboard ];
+ customerService.applyAssignedCustomersInfo(dashboards).then(
+ function success(items) {
+ if (items && items.length == 1) {
+ deferred.resolve(items[0]);
+ } else {
+ deferred.reject();
+ }
+ },
+ function fail() {
+ deferred.reject();
+ }
+ );
+ },
+ function fail() {
+ deferred.reject();
+ }
+ );
+ return deferred.promise;
}
function assignToCustomer($event, dashboardIds) {
diff --git a/ui/src/app/dashboard/index.js b/ui/src/app/dashboard/index.js
index 4587001281..88d71fb0e2 100644
--- a/ui/src/app/dashboard/index.js
+++ b/ui/src/app/dashboard/index.js
@@ -30,6 +30,7 @@ import thingsboardDashboardSelect from '../components/dashboard-select.directive
import thingsboardDashboard from '../components/dashboard.directive';
import thingsboardExpandFullscreen from '../components/expand-fullscreen.directive';
import thingsboardWidgetsBundleSelect from '../components/widgets-bundle-select.directive';
+import thingsboardSocialsharePanel from '../components/socialshare-panel.directive';
import thingsboardTypes from '../common/types.constant';
import thingsboardItemBuffer from '../services/item-buffer.service';
import thingsboardImportExport from '../import-export';
@@ -64,7 +65,8 @@ export default angular.module('thingsboard.dashboard', [
thingsboardDashboardSelect,
thingsboardDashboard,
thingsboardExpandFullscreen,
- thingsboardWidgetsBundleSelect
+ thingsboardWidgetsBundleSelect,
+ thingsboardSocialsharePanel
])
.config(DashboardRoutes)
.controller('DashboardsController', DashboardsController)
diff --git a/ui/src/app/dashboard/make-dashboard-public-dialog.tpl.html b/ui/src/app/dashboard/make-dashboard-public-dialog.tpl.html
index 31f49fbc34..8d96b30225 100644
--- a/ui/src/app/dashboard/make-dashboard-public-dialog.tpl.html
+++ b/ui/src/app/dashboard/make-dashboard-public-dialog.tpl.html
@@ -43,6 +43,12 @@
dashboard.public-dashboard-notice
+
+
diff --git a/ui/src/app/device/device.controller.js b/ui/src/app/device/device.controller.js
index ed9ff6ff8c..55b70832e2 100644
--- a/ui/src/app/device/device.controller.js
+++ b/ui/src/app/device/device.controller.js
@@ -185,7 +185,7 @@ export function DeviceController(userService, deviceService, customerService, $s
onAction: function ($event, item) {
unassignFromCustomer($event, item, true);
},
- name: function() { return $translate.instant('action.unshare') },
+ name: function() { return $translate.instant('action.make-private') },
details: function() { return $translate.instant('device.make-private') },
icon: "reply",
isEnabled: function(device) {
@@ -271,7 +271,7 @@ export function DeviceController(userService, deviceService, customerService, $s
onAction: function ($event, item) {
unassignFromCustomer($event, item, true);
},
- name: function() { return $translate.instant('action.unshare') },
+ name: function() { return $translate.instant('action.make-private') },
details: function() { return $translate.instant('device.make-private') },
icon: "reply",
isEnabled: function(device) {
@@ -364,8 +364,29 @@ export function DeviceController(userService, deviceService, customerService, $s
return device ? device.name : '';
}
- function saveDevice (device) {
- return deviceService.saveDevice(device);
+ function saveDevice(device) {
+ var deferred = $q.defer();
+ deviceService.saveDevice(device).then(
+ function success(savedDevice) {
+ var devices = [ savedDevice ];
+ customerService.applyAssignedCustomersInfo(devices).then(
+ function success(items) {
+ if (items && items.length == 1) {
+ deferred.resolve(items[0]);
+ } else {
+ deferred.reject();
+ }
+ },
+ function fail() {
+ deferred.reject();
+ }
+ );
+ },
+ function fail() {
+ deferred.reject();
+ }
+ );
+ return deferred.promise;
}
function isCustomerUser() {
diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js
index 37a2b93b48..32b422bca0 100644
--- a/ui/src/app/locale/locale.constant.js
+++ b/ui/src/app/locale/locale.constant.js
@@ -44,7 +44,7 @@ export default angular.module('thingsboard.locale', [])
"assign": "Assign",
"unassign": "Unassign",
"share": "Share",
- "unshare": "Unshare",
+ "make-private": "Make private",
"apply": "Apply",
"apply-changes": "Apply changes",
"edit-mode": "Edit mode",
@@ -63,7 +63,8 @@ export default angular.module('thingsboard.locale', [])
"copy": "Copy",
"paste": "Paste",
"import": "Import",
- "export": "Export"
+ "export": "Export",
+ "share-via": "Share via {{provider}}"
},
"aggregation": {
"aggregation": "Aggregation",
@@ -233,6 +234,8 @@ export default angular.module('thingsboard.locale', [])
"make-private-dashboard-title": "Are you sure you want to make the dashboard '{{dashboardTitle}}' private?",
"make-private-dashboard-text": "After the confirmation the dashboard will be made private and won't be accessible by others.",
"make-private-dashboard": "Make dashboard private",
+ "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard",
+ "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard",
"select-dashboard": "Select dashboard",
"no-dashboards-matching": "No dashboards matching '{{dashboard}}' were found.",
"dashboard-required": "Dashboard is required.",
@@ -262,6 +265,9 @@ export default angular.module('thingsboard.locale', [])
"max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.",
"display-title": "Display dashboard title",
"title-color": "Title color",
+ "display-device-selection": "Display device selection",
+ "display-dashboard-timewindow": "Display timewindow",
+ "display-dashboard-export": "Display export",
"import": "Import dashboard",
"export": "Export dashboard",
"export-failed-error": "Unable to export dashboard: {{error}}",
diff --git a/ui/webpack.config.dev.js b/ui/webpack.config.dev.js
index c669ec5b22..fa019d3292 100644
--- a/ui/webpack.config.dev.js
+++ b/ui/webpack.config.dev.js
@@ -60,6 +60,7 @@ module.exports = {
allChunks: true,
}),
new webpack.DefinePlugin({
+ THINGSBOARD_VERSION: JSON.stringify(require('./package.json').version),
'__DEVTOOLS__': false,
'process.env': {
NODE_ENV: JSON.stringify('development'),
diff --git a/ui/webpack.config.prod.js b/ui/webpack.config.prod.js
index 09374fb6a5..a746488850 100644
--- a/ui/webpack.config.prod.js
+++ b/ui/webpack.config.prod.js
@@ -58,6 +58,7 @@ module.exports = {
allChunks: true,
}),
new webpack.DefinePlugin({
+ THINGSBOARD_VERSION: JSON.stringify(require('./package.json').version),
'__DEVTOOLS__': false,
'process.env': {
NODE_ENV: JSON.stringify('production'),