Commit bfd654d84fe4a270a76e815eb8eb428cde02e62e
1 parent
912c572a
Add social share buttons for public dashboards sharing. Improve dashboard toolba…
…r configuration. Add project version information to bottom right part of the dashboard.
Showing
17 changed files
with
290 additions
and
29 deletions
... | ... | @@ -19,6 +19,7 @@ import angular from 'angular'; |
19 | 19 | import ngMaterial from 'angular-material'; |
20 | 20 | import ngMdIcons from 'angular-material-icons'; |
21 | 21 | import ngCookies from 'angular-cookies'; |
22 | +import angularSocialshare from 'angular-socialshare'; | |
22 | 23 | import 'angular-translate'; |
23 | 24 | import 'angular-translate-loader-static-files'; |
24 | 25 | import 'angular-translate-storage-local'; |
... | ... | @@ -82,6 +83,7 @@ angular.module('thingsboard', [ |
82 | 83 | ngMaterial, |
83 | 84 | ngMdIcons, |
84 | 85 | ngCookies, |
86 | + angularSocialshare, | |
85 | 87 | 'pascalprecht.translate', |
86 | 88 | 'mdColorPicker', |
87 | 89 | mdPickers, | ... | ... |
... | ... | @@ -106,7 +106,8 @@ function Utils($mdColorPalette, $rootScope, $window, $q, deviceService, types) { |
106 | 106 | isDescriptorSchemaNotEmpty: isDescriptorSchemaNotEmpty, |
107 | 107 | filterSearchTextEntities: filterSearchTextEntities, |
108 | 108 | guid: guid, |
109 | - createDatasoucesFromSubscriptionsInfo: createDatasoucesFromSubscriptionsInfo | |
109 | + createDatasoucesFromSubscriptionsInfo: createDatasoucesFromSubscriptionsInfo, | |
110 | + isLocalUrl: isLocalUrl | |
110 | 111 | } |
111 | 112 | |
112 | 113 | return service; |
... | ... | @@ -428,4 +429,15 @@ function Utils($mdColorPalette, $rootScope, $window, $q, deviceService, types) { |
428 | 429 | return deferred.promise; |
429 | 430 | } |
430 | 431 | |
432 | + function isLocalUrl(url) { | |
433 | + var parser = document.createElement('a'); //eslint-disable-line | |
434 | + parser.href = url; | |
435 | + var host = parser.hostname; | |
436 | + if (host === "localhost" || host === "127.0.0.1") { | |
437 | + return true; | |
438 | + } else { | |
439 | + return false; | |
440 | + } | |
441 | + } | |
442 | + | |
431 | 443 | } | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +/* eslint-disable import/no-unresolved, import/default */ | |
18 | + | |
19 | +import socialsharePanelTemplate from './socialshare-panel.tpl.html'; | |
20 | + | |
21 | +/* eslint-enable import/no-unresolved, import/default */ | |
22 | + | |
23 | + | |
24 | +export default angular.module('thingsboard.directives.socialsharePanel', []) | |
25 | + .directive('tbSocialSharePanel', SocialsharePanel) | |
26 | + .name; | |
27 | + | |
28 | +/*@ngInject*/ | |
29 | +function SocialsharePanel() { | |
30 | + return { | |
31 | + restrict: "E", | |
32 | + scope: true, | |
33 | + bindToController: { | |
34 | + shareTitle: '@', | |
35 | + shareText: '@', | |
36 | + shareLink: '@', | |
37 | + shareHashTags: '@' | |
38 | + }, | |
39 | + controller: SocialsharePanelController, | |
40 | + controllerAs: 'vm', | |
41 | + templateUrl: socialsharePanelTemplate | |
42 | + }; | |
43 | +} | |
44 | + | |
45 | +/*@ngInject*/ | |
46 | +function SocialsharePanelController(utils) { | |
47 | + | |
48 | + let vm = this; | |
49 | + | |
50 | + vm.isShareLinkLocal = function() { | |
51 | + if (vm.shareLink && vm.shareLink.length > 0) { | |
52 | + return utils.isLocalUrl(vm.shareLink); | |
53 | + } else { | |
54 | + return true; | |
55 | + } | |
56 | + } | |
57 | + | |
58 | +} | |
\ No newline at end of file | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2017 The Thingsboard Authors | |
4 | + | |
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + you may not use this file except in compliance with the License. | |
7 | + You may obtain a copy of the License at | |
8 | + | |
9 | + http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + | |
11 | + Unless required by applicable law or agreed to in writing, software | |
12 | + distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + See the License for the specific language governing permissions and | |
15 | + limitations under the License. | |
16 | + | |
17 | +--> | |
18 | + | |
19 | +<div layout="row" ng-show="!vm.isShareLinkLocal()"> | |
20 | + <md-button class="md-icon-button md-raised md-primary" | |
21 | + socialshare | |
22 | + socialshare-provider="facebook" | |
23 | + socialshare-title="{{ vm.shareTitle }}" | |
24 | + socialshare-text="{{ vm.shareText }}" | |
25 | + socialshare-url="{{ vm.shareLink }}"> | |
26 | + <ng-md-icon icon="facebook" aria-label="Facebook"></ng-md-icon> | |
27 | + <md-tooltip md-direction="top"> | |
28 | + {{ 'action.share-via' | translate:{provider:'Facebook'} }} | |
29 | + </md-tooltip> | |
30 | + </md-button> | |
31 | + <md-button class="md-icon-button md-raised md-primary" | |
32 | + socialshare | |
33 | + socialshare-provider="twitter" | |
34 | + socialshare-text="{{ vm.shareTitle }}" | |
35 | + socialshare-hashtags="{{ vm.shareHashTags }}" | |
36 | + socialshare-url="{{ vm.shareLink }}"> | |
37 | + <ng-md-icon icon="twitter" aria-label="Twitter"></ng-md-icon> | |
38 | + <md-tooltip md-direction="top"> | |
39 | + {{ 'action.share-via' | translate:{provider:'Twitter'} }} | |
40 | + </md-tooltip> | |
41 | + </md-button> | |
42 | + <md-button class="md-icon-button md-raised md-primary" | |
43 | + socialshare | |
44 | + socialshare-provider="linkedin" | |
45 | + socialshare-text="{{ vm.shareTitle }}" | |
46 | + socialshare-url="{{ vm.shareLink }}"> | |
47 | + <ng-md-icon icon="linkedin" aria-label="Linkedin"></ng-md-icon> | |
48 | + <md-tooltip md-direction="top"> | |
49 | + {{ 'action.share-via' | translate:{provider:'Linkedin'} }} | |
50 | + </md-tooltip> | |
51 | + </md-button> | |
52 | + <md-button class="md-icon-button md-raised md-primary" | |
53 | + socialshare | |
54 | + socialshare-provider="reddit" | |
55 | + socialshare-text="{{ vm.shareTitle }}" | |
56 | + socialshare-url="{{ vm.shareLink }}"> | |
57 | + <md-icon md-svg-icon="mdi:reddit" aria-label="Reddit"></md-icon> | |
58 | + <md-tooltip md-direction="top"> | |
59 | + {{ 'action.share-via' | translate:{provider:'Reddit'} }} | |
60 | + </md-tooltip> | |
61 | + </md-button> | |
62 | +</div> | |
\ No newline at end of file | ... | ... |
... | ... | @@ -36,20 +36,28 @@ |
36 | 36 | <label translate>dashboard.assignedToCustomer</label> |
37 | 37 | <input ng-model="assignedCustomer.title" disabled> |
38 | 38 | </md-input-container> |
39 | - <div layout="row" ng-show="!isEdit && isPublic && (dashboardScope === 'customer' || dashboardScope === 'tenant')"> | |
40 | - <md-input-container class="md-block" flex> | |
41 | - <label translate>dashboard.public-link</label> | |
42 | - <input ng-model="publicLink" disabled> | |
43 | - </md-input-container> | |
44 | - <md-button class="md-icon-button" style="margin-top: 14px;" | |
45 | - ngclipboard | |
46 | - data-clipboard-text="{{ publicLink }}" | |
47 | - ngclipboard-success="onPublicLinkCopied(e)"> | |
48 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
49 | - <md-tooltip md-direction="top"> | |
50 | - {{ 'dashboard.copy-public-link' | translate }} | |
51 | - </md-tooltip> | |
52 | - </md-button> | |
39 | + <div layout="column" ng-show="!isEdit && isPublic && (dashboardScope === 'customer' || dashboardScope === 'tenant')"> | |
40 | + <tb-social-share-panel style="padding-bottom: 10px;" | |
41 | + share-title="{{ 'dashboard.socialshare-title' | translate:{dashboardTitle: dashboard.title} }}" | |
42 | + share-text="{{ 'dashboard.socialshare-text' | translate:{dashboardTitle: dashboard.title} }}" | |
43 | + share-link="{{ publicLink }}" | |
44 | + share-hash-tags="thingsboard, iot"> | |
45 | + </tb-social-share-panel> | |
46 | + <div layout="row"> | |
47 | + <md-input-container class="md-block" flex> | |
48 | + <label translate>dashboard.public-link</label> | |
49 | + <input ng-model="publicLink" disabled> | |
50 | + </md-input-container> | |
51 | + <md-button class="md-icon-button" style="margin-top: 14px;" | |
52 | + ngclipboard | |
53 | + data-clipboard-text="{{ publicLink }}" | |
54 | + ngclipboard-success="onPublicLinkCopied(e)"> | |
55 | + <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
56 | + <md-tooltip md-direction="top"> | |
57 | + {{ 'dashboard.copy-public-link' | translate }} | |
58 | + </md-tooltip> | |
59 | + </md-button> | |
60 | + </div> | |
53 | 61 | </div> |
54 | 62 | <fieldset ng-disabled="loading || !isEdit"> |
55 | 63 | <md-input-container class="md-block"> | ... | ... |
... | ... | @@ -31,6 +31,18 @@ export default function DashboardSettingsController($scope, $mdDialog, gridSetti |
31 | 31 | vm.gridSettings.showTitle = true; |
32 | 32 | } |
33 | 33 | |
34 | + if (angular.isUndefined(vm.gridSettings.showDevicesSelect)) { | |
35 | + vm.gridSettings.showDevicesSelect = true; | |
36 | + } | |
37 | + | |
38 | + if (angular.isUndefined(vm.gridSettings.showDashboardTimewindow)) { | |
39 | + vm.gridSettings.showDashboardTimewindow = true; | |
40 | + } | |
41 | + | |
42 | + if (angular.isUndefined(vm.gridSettings.showDashboardExport)) { | |
43 | + vm.gridSettings.showDashboardExport = true; | |
44 | + } | |
45 | + | |
34 | 46 | vm.gridSettings.backgroundColor = vm.gridSettings.backgroundColor || 'rgba(0,0,0,0)'; |
35 | 47 | vm.gridSettings.titleColor = vm.gridSettings.titleColor || 'rgba(0,0,0,0.870588)'; |
36 | 48 | vm.gridSettings.columns = vm.gridSettings.columns || 24; | ... | ... |
... | ... | @@ -48,6 +48,17 @@ |
48 | 48 | md-color-history="false" |
49 | 49 | ></div> |
50 | 50 | </div> |
51 | + <div layout="row" layout-align="start center"> | |
52 | + <md-checkbox flex aria-label="{{ 'dashboard.display-device-selection' | translate }}" | |
53 | + ng-model="vm.gridSettings.showDevicesSelect">{{ 'dashboard.display-device-selection' | translate }} | |
54 | + </md-checkbox> | |
55 | + <md-checkbox flex aria-label="{{ 'dashboard.display-dashboard-timewindow' | translate }}" | |
56 | + ng-model="vm.gridSettings.showDashboardTimewindow">{{ 'dashboard.display-dashboard-timewindow' | translate }} | |
57 | + </md-checkbox> | |
58 | + <md-checkbox flex aria-label="{{ 'dashboard.display-dashboard-export' | translate }}" | |
59 | + ng-model="vm.gridSettings.showDashboardExport">{{ 'dashboard.display-dashboard-export' | translate }} | |
60 | + </md-checkbox> | |
61 | + </div> | |
51 | 62 | <md-input-container class="md-block"> |
52 | 63 | <label translate>dashboard.columns-count</label> |
53 | 64 | <input required type="number" step="any" name="columns" ng-model="vm.gridSettings.columns" min="10" | ... | ... |
... | ... | @@ -48,6 +48,8 @@ export default function DashboardController(types, widgetService, userService, |
48 | 48 | |
49 | 49 | vm.isToolbarOpened = false; |
50 | 50 | |
51 | + vm.thingsboardVersion = THINGSBOARD_VERSION; //eslint-disable-line | |
52 | + | |
51 | 53 | vm.currentDashboardId = $stateParams.dashboardId; |
52 | 54 | if ($stateParams.customerId) { |
53 | 55 | vm.currentCustomerId = $stateParams.customerId; |
... | ... | @@ -105,6 +107,9 @@ export default function DashboardController(types, widgetService, userService, |
105 | 107 | vm.onRevertWidgetEdit = onRevertWidgetEdit; |
106 | 108 | vm.helpLinkIdForWidgetType = helpLinkIdForWidgetType; |
107 | 109 | vm.displayTitle = displayTitle; |
110 | + vm.displayExport = displayExport; | |
111 | + vm.displayDashboardTimewindow = displayDashboardTimewindow; | |
112 | + vm.displayDevicesSelect = displayDevicesSelect; | |
108 | 113 | |
109 | 114 | vm.widgetsBundle; |
110 | 115 | |
... | ... | @@ -565,6 +570,33 @@ export default function DashboardController(types, widgetService, userService, |
565 | 570 | } |
566 | 571 | } |
567 | 572 | |
573 | + function displayExport() { | |
574 | + if (vm.dashboard && vm.dashboard.configuration.gridSettings && | |
575 | + angular.isDefined(vm.dashboard.configuration.gridSettings.showDashboardExport)) { | |
576 | + return vm.dashboard.configuration.gridSettings.showDashboardExport; | |
577 | + } else { | |
578 | + return true; | |
579 | + } | |
580 | + } | |
581 | + | |
582 | + function displayDashboardTimewindow() { | |
583 | + if (vm.dashboard && vm.dashboard.configuration.gridSettings && | |
584 | + angular.isDefined(vm.dashboard.configuration.gridSettings.showDashboardTimewindow)) { | |
585 | + return vm.dashboard.configuration.gridSettings.showDashboardTimewindow; | |
586 | + } else { | |
587 | + return true; | |
588 | + } | |
589 | + } | |
590 | + | |
591 | + function displayDevicesSelect() { | |
592 | + if (vm.dashboard && vm.dashboard.configuration.gridSettings && | |
593 | + angular.isDefined(vm.dashboard.configuration.gridSettings.showDevicesSelect)) { | |
594 | + return vm.dashboard.configuration.gridSettings.showDevicesSelect; | |
595 | + } else { | |
596 | + return true; | |
597 | + } | |
598 | + } | |
599 | + | |
568 | 600 | function onRevertWidgetEdit(widgetForm) { |
569 | 601 | if (widgetForm.$dirty) { |
570 | 602 | widgetForm.$setPristine(); | ... | ... |
... | ... | @@ -49,16 +49,21 @@ |
49 | 49 | </md-button> |
50 | 50 | <tb-user-menu ng-if="!vm.isPublicUser() && forceFullscreen" display-user-info="true"> |
51 | 51 | </tb-user-menu> |
52 | - <md-button aria-label="{{ 'action.export' | translate }}" class="md-icon-button" | |
52 | + <md-button ng-show="vm.isEdit || vm.displayExport()" | |
53 | + aria-label="{{ 'action.export' | translate }}" class="md-icon-button" | |
53 | 54 | ng-click="vm.exportDashboard($event)"> |
54 | 55 | <md-tooltip md-direction="bottom"> |
55 | 56 | {{ 'dashboard.export' | translate }} |
56 | 57 | </md-tooltip> |
57 | 58 | <md-icon aria-label="{{ 'action.export' | translate }}" class="material-icons">file_download</md-icon> |
58 | 59 | </md-button> |
59 | - <tb-timewindow is-toolbar direction="left" tooltip-direction="bottom" aggregation ng-model="vm.dashboardConfiguration.timewindow"> | |
60 | + <tb-timewindow ng-show="vm.isEdit || vm.displayDashboardTimewindow()" | |
61 | + is-toolbar | |
62 | + direction="left" | |
63 | + tooltip-direction="bottom" aggregation | |
64 | + ng-model="vm.dashboardConfiguration.timewindow"> | |
60 | 65 | </tb-timewindow> |
61 | - <tb-aliases-device-select ng-show="!vm.isEdit" | |
66 | + <tb-aliases-device-select ng-show="!vm.isEdit && vm.displayDevicesSelect()" | |
62 | 67 | tooltip-direction="bottom" |
63 | 68 | ng-model="vm.aliasesInfo.deviceAliases" |
64 | 69 | device-aliases-info="vm.aliasesInfo.deviceAliasesInfo"> |
... | ... | @@ -304,6 +309,6 @@ |
304 | 309 | </section> |
305 | 310 | </section> |
306 | 311 | <section class="tb-powered-by-footer" ng-style="{'color': vm.dashboard.configuration.gridSettings.titleColor}"> |
307 | - <span>Powered by <a href="https://thingsboard.io" target="_blank">Thingsboard</a></span> | |
312 | + <span>Powered by <a href="https://thingsboard.io" target="_blank">Thingsboard v.{{ vm.thingsboardVersion }}</a></span> | |
308 | 313 | </section> |
309 | 314 | </md-content> | ... | ... |
... | ... | @@ -224,7 +224,7 @@ export function DashboardsController(userService, dashboardService, customerServ |
224 | 224 | onAction: function ($event, item) { |
225 | 225 | unassignFromCustomer($event, item, true); |
226 | 226 | }, |
227 | - name: function() { return $translate.instant('action.unshare') }, | |
227 | + name: function() { return $translate.instant('action.make-private') }, | |
228 | 228 | details: function() { return $translate.instant('dashboard.make-private') }, |
229 | 229 | icon: "reply", |
230 | 230 | isEnabled: function(dashboard) { |
... | ... | @@ -329,7 +329,7 @@ export function DashboardsController(userService, dashboardService, customerServ |
329 | 329 | onAction: function ($event, item) { |
330 | 330 | unassignFromCustomer($event, item, true); |
331 | 331 | }, |
332 | - name: function() { return $translate.instant('action.unshare') }, | |
332 | + name: function() { return $translate.instant('action.make-private') }, | |
333 | 333 | details: function() { return $translate.instant('dashboard.make-private') }, |
334 | 334 | icon: "reply", |
335 | 335 | isEnabled: function(dashboard) { |
... | ... | @@ -404,7 +404,28 @@ export function DashboardsController(userService, dashboardService, customerServ |
404 | 404 | } |
405 | 405 | |
406 | 406 | function saveDashboard(dashboard) { |
407 | - return dashboardService.saveDashboard(dashboard); | |
407 | + var deferred = $q.defer(); | |
408 | + dashboardService.saveDashboard(dashboard).then( | |
409 | + function success(savedDashboard) { | |
410 | + var dashboards = [ savedDashboard ]; | |
411 | + customerService.applyAssignedCustomersInfo(dashboards).then( | |
412 | + function success(items) { | |
413 | + if (items && items.length == 1) { | |
414 | + deferred.resolve(items[0]); | |
415 | + } else { | |
416 | + deferred.reject(); | |
417 | + } | |
418 | + }, | |
419 | + function fail() { | |
420 | + deferred.reject(); | |
421 | + } | |
422 | + ); | |
423 | + }, | |
424 | + function fail() { | |
425 | + deferred.reject(); | |
426 | + } | |
427 | + ); | |
428 | + return deferred.promise; | |
408 | 429 | } |
409 | 430 | |
410 | 431 | function assignToCustomer($event, dashboardIds) { | ... | ... |
... | ... | @@ -30,6 +30,7 @@ import thingsboardDashboardSelect from '../components/dashboard-select.directive |
30 | 30 | import thingsboardDashboard from '../components/dashboard.directive'; |
31 | 31 | import thingsboardExpandFullscreen from '../components/expand-fullscreen.directive'; |
32 | 32 | import thingsboardWidgetsBundleSelect from '../components/widgets-bundle-select.directive'; |
33 | +import thingsboardSocialsharePanel from '../components/socialshare-panel.directive'; | |
33 | 34 | import thingsboardTypes from '../common/types.constant'; |
34 | 35 | import thingsboardItemBuffer from '../services/item-buffer.service'; |
35 | 36 | import thingsboardImportExport from '../import-export'; |
... | ... | @@ -64,7 +65,8 @@ export default angular.module('thingsboard.dashboard', [ |
64 | 65 | thingsboardDashboardSelect, |
65 | 66 | thingsboardDashboard, |
66 | 67 | thingsboardExpandFullscreen, |
67 | - thingsboardWidgetsBundleSelect | |
68 | + thingsboardWidgetsBundleSelect, | |
69 | + thingsboardSocialsharePanel | |
68 | 70 | ]) |
69 | 71 | .config(DashboardRoutes) |
70 | 72 | .controller('DashboardsController', DashboardsController) | ... | ... |
... | ... | @@ -43,6 +43,12 @@ |
43 | 43 | </md-button> |
44 | 44 | </div> |
45 | 45 | <div class="tb-notice" translate>dashboard.public-dashboard-notice</div> |
46 | + <tb-social-share-panel style="padding-top: 15px;" | |
47 | + share-title="{{ 'dashboard.socialshare-title' | translate:{dashboardTitle:vm.dashboard.title} }}" | |
48 | + share-text="{{ 'dashboard.socialshare-text' | translate:{dashboardTitle:vm.dashboard.title} }}" | |
49 | + share-link="{{ vm.publicLink }}" | |
50 | + share-hash-tags="thingsboard, iot"> | |
51 | + </tb-social-share-panel> | |
46 | 52 | </md-content> |
47 | 53 | </div> |
48 | 54 | </md-dialog-content> | ... | ... |
... | ... | @@ -185,7 +185,7 @@ export function DeviceController(userService, deviceService, customerService, $s |
185 | 185 | onAction: function ($event, item) { |
186 | 186 | unassignFromCustomer($event, item, true); |
187 | 187 | }, |
188 | - name: function() { return $translate.instant('action.unshare') }, | |
188 | + name: function() { return $translate.instant('action.make-private') }, | |
189 | 189 | details: function() { return $translate.instant('device.make-private') }, |
190 | 190 | icon: "reply", |
191 | 191 | isEnabled: function(device) { |
... | ... | @@ -271,7 +271,7 @@ export function DeviceController(userService, deviceService, customerService, $s |
271 | 271 | onAction: function ($event, item) { |
272 | 272 | unassignFromCustomer($event, item, true); |
273 | 273 | }, |
274 | - name: function() { return $translate.instant('action.unshare') }, | |
274 | + name: function() { return $translate.instant('action.make-private') }, | |
275 | 275 | details: function() { return $translate.instant('device.make-private') }, |
276 | 276 | icon: "reply", |
277 | 277 | isEnabled: function(device) { |
... | ... | @@ -364,8 +364,29 @@ export function DeviceController(userService, deviceService, customerService, $s |
364 | 364 | return device ? device.name : ''; |
365 | 365 | } |
366 | 366 | |
367 | - function saveDevice (device) { | |
368 | - return deviceService.saveDevice(device); | |
367 | + function saveDevice(device) { | |
368 | + var deferred = $q.defer(); | |
369 | + deviceService.saveDevice(device).then( | |
370 | + function success(savedDevice) { | |
371 | + var devices = [ savedDevice ]; | |
372 | + customerService.applyAssignedCustomersInfo(devices).then( | |
373 | + function success(items) { | |
374 | + if (items && items.length == 1) { | |
375 | + deferred.resolve(items[0]); | |
376 | + } else { | |
377 | + deferred.reject(); | |
378 | + } | |
379 | + }, | |
380 | + function fail() { | |
381 | + deferred.reject(); | |
382 | + } | |
383 | + ); | |
384 | + }, | |
385 | + function fail() { | |
386 | + deferred.reject(); | |
387 | + } | |
388 | + ); | |
389 | + return deferred.promise; | |
369 | 390 | } |
370 | 391 | |
371 | 392 | function isCustomerUser() { | ... | ... |
... | ... | @@ -44,7 +44,7 @@ export default angular.module('thingsboard.locale', []) |
44 | 44 | "assign": "Assign", |
45 | 45 | "unassign": "Unassign", |
46 | 46 | "share": "Share", |
47 | - "unshare": "Unshare", | |
47 | + "make-private": "Make private", | |
48 | 48 | "apply": "Apply", |
49 | 49 | "apply-changes": "Apply changes", |
50 | 50 | "edit-mode": "Edit mode", |
... | ... | @@ -63,7 +63,8 @@ export default angular.module('thingsboard.locale', []) |
63 | 63 | "copy": "Copy", |
64 | 64 | "paste": "Paste", |
65 | 65 | "import": "Import", |
66 | - "export": "Export" | |
66 | + "export": "Export", | |
67 | + "share-via": "Share via {{provider}}" | |
67 | 68 | }, |
68 | 69 | "aggregation": { |
69 | 70 | "aggregation": "Aggregation", |
... | ... | @@ -233,6 +234,8 @@ export default angular.module('thingsboard.locale', []) |
233 | 234 | "make-private-dashboard-title": "Are you sure you want to make the dashboard '{{dashboardTitle}}' private?", |
234 | 235 | "make-private-dashboard-text": "After the confirmation the dashboard will be made private and won't be accessible by others.", |
235 | 236 | "make-private-dashboard": "Make dashboard private", |
237 | + "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", | |
238 | + "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", | |
236 | 239 | "select-dashboard": "Select dashboard", |
237 | 240 | "no-dashboards-matching": "No dashboards matching '{{dashboard}}' were found.", |
238 | 241 | "dashboard-required": "Dashboard is required.", |
... | ... | @@ -262,6 +265,9 @@ export default angular.module('thingsboard.locale', []) |
262 | 265 | "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.", |
263 | 266 | "display-title": "Display dashboard title", |
264 | 267 | "title-color": "Title color", |
268 | + "display-device-selection": "Display device selection", | |
269 | + "display-dashboard-timewindow": "Display timewindow", | |
270 | + "display-dashboard-export": "Display export", | |
265 | 271 | "import": "Import dashboard", |
266 | 272 | "export": "Export dashboard", |
267 | 273 | "export-failed-error": "Unable to export dashboard: {{error}}", | ... | ... |