Showing
7 changed files
with
240 additions
and
17 deletions
... | ... | @@ -21,6 +21,7 @@ import thingsboardLedLight from '../components/led-light.directive'; |
21 | 21 | import thingsboardTimeseriesTableWidget from '../widget/lib/timeseries-table-widget'; |
22 | 22 | import thingsboardAlarmsTableWidget from '../widget/lib/alarms-table-widget'; |
23 | 23 | import thingsboardEntitiesTableWidget from '../widget/lib/entities-table-widget'; |
24 | +import thingsboardExtensionsTableWidget from '../widget/lib/extensions-table-widget'; | |
24 | 25 | |
25 | 26 | import thingsboardRpcWidgets from '../widget/lib/rpc'; |
26 | 27 | |
... | ... | @@ -42,7 +43,7 @@ import thingsboardTypes from '../common/types.constant'; |
42 | 43 | import thingsboardUtils from '../common/utils.service'; |
43 | 44 | |
44 | 45 | export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight, thingsboardTimeseriesTableWidget, |
45 | - thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget, thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils]) | |
46 | + thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget, thingsboardExtensionsTableWidget, thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils]) | |
46 | 47 | .factory('widgetService', WidgetService) |
47 | 48 | .name; |
48 | 49 | ... | ... |
... | ... | @@ -34,7 +34,9 @@ export default function ExtensionTableDirective() { |
34 | 34 | scope: true, |
35 | 35 | bindToController: { |
36 | 36 | entityId: '=', |
37 | - entityType: '@' | |
37 | + entityType: '@', | |
38 | + inWidget: '@?', | |
39 | + ctx: '=?' | |
38 | 40 | }, |
39 | 41 | controller: ExtensionTableController, |
40 | 42 | controllerAs: 'vm', |
... | ... | @@ -70,7 +72,6 @@ function ExtensionTableController($scope, $filter, $document, $translate, types, |
70 | 72 | vm.reloadExtensions = reloadExtensions; |
71 | 73 | vm.updateExtensions = updateExtensions; |
72 | 74 | |
73 | - | |
74 | 75 | $scope.$watch("vm.entityId", function(newVal) { |
75 | 76 | if (newVal) { |
76 | 77 | if ($scope.subscriber) { |
... | ... | @@ -92,13 +93,50 @@ function ExtensionTableController($scope, $filter, $document, $translate, types, |
92 | 93 | } |
93 | 94 | }); |
94 | 95 | |
96 | + $scope.$watch('vm.selectedExtensions.length', function (newLength) { | |
97 | + var selectionMode = newLength ? true : false; | |
98 | + if (vm.ctx) { | |
99 | + if (selectionMode) { | |
100 | + vm.ctx.hideTitlePanel = true; | |
101 | + $scope.$emit("selectedExtensions", true); | |
102 | + } else if (vm.query.search == null) { | |
103 | + vm.ctx.hideTitlePanel = false; | |
104 | + $scope.$emit("selectedExtensions", false); | |
105 | + } | |
106 | + } | |
107 | + }); | |
108 | + | |
109 | + $scope.$on("showSearch", function($event, source) { | |
110 | + if(source.entityId == vm.entityId) { | |
111 | + enterFilterMode(); | |
112 | + $scope.$emit("filterMode", true); | |
113 | + } | |
114 | + }); | |
115 | + $scope.$on("refreshExtensions", function($event, source) { | |
116 | + if(source.entityId == vm.entityId) { | |
117 | + reloadExtensions(); | |
118 | + } | |
119 | + }); | |
120 | + $scope.$on("addExtension", function($event, source) { | |
121 | + if(source.entityId == vm.entityId) { | |
122 | + addExtension(); | |
123 | + } | |
124 | + }); | |
125 | + | |
95 | 126 | function enterFilterMode() { |
96 | 127 | vm.query.search = ''; |
128 | + if(vm.inWidget) { | |
129 | + vm.ctx.hideTitlePanel = true; | |
130 | + } | |
97 | 131 | } |
98 | 132 | |
99 | 133 | function exitFilterMode() { |
100 | 134 | vm.query.search = null; |
101 | 135 | updateExtensions(); |
136 | + if(vm.inWidget) { | |
137 | + vm.ctx.hideTitlePanel = false; | |
138 | + $scope.$emit("filterMode", false); | |
139 | + } | |
102 | 140 | } |
103 | 141 | |
104 | 142 | function onReorder() { |
... | ... | @@ -256,8 +294,7 @@ function ExtensionTableController($scope, $filter, $document, $translate, types, |
256 | 294 | vm.extensions = result.slice(startIndex, startIndex + vm.query.limit); |
257 | 295 | |
258 | 296 | vm.extensionsJSON = angular.toJson(vm.extensions); |
259 | - checkForSync() | |
260 | - | |
297 | + checkForSync(); | |
261 | 298 | } |
262 | 299 | |
263 | 300 | function subscribeForClientAttributes() { |
... | ... | @@ -320,7 +357,6 @@ function ExtensionTableController($scope, $filter, $document, $translate, types, |
320 | 357 | d = d.getFullYear() +'/'+ addZero(d.getMonth()+1) +'/'+ addZero(d.getDate()) + ' ' + addZero(d.getHours()) + ':' + addZero(d.getMinutes()) +':'+ addZero(d.getSeconds()); |
321 | 358 | return d; |
322 | 359 | |
323 | - | |
324 | 360 | function addZero(num) { |
325 | 361 | if ((angular.isNumber(num) && num < 10) || (angular.isString(num) && num.length === 1)) { |
326 | 362 | num = '0' + num; | ... | ... |
... | ... | @@ -20,6 +20,18 @@ |
20 | 20 | min-height: 0; |
21 | 21 | } |
22 | 22 | |
23 | +.extension-table { | |
24 | + .sync-widget { | |
25 | + max-height: 90px; | |
26 | + overflow: hidden; | |
27 | + } | |
28 | + .toolbar-widget { | |
29 | + min-height: 39px; | |
30 | + max-height: 39px; | |
31 | + } | |
32 | +} | |
33 | + | |
34 | + | |
23 | 35 | .extension__syncStatus--black { |
24 | 36 | color: #000000!important; |
25 | 37 | } | ... | ... |
... | ... | @@ -17,9 +17,9 @@ |
17 | 17 | --> |
18 | 18 | |
19 | 19 | <md-content flex class="md-padding tb-absolute-fill tb-data-table extension-table" layout="column"> |
20 | - <div layout="column" class="md-whiteframe-z1"> | |
21 | - <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedExtensions.length | |
22 | - && vm.query.search === null"> | |
20 | + <div layout="column" class="md-whiteframe-z1" ng-class="{'tb-absolute-fill' : vm.inWidget}"> | |
21 | + <md-toolbar ng-if="!vm.inWidget" class="md-table-toolbar md-default" ng-show="!vm.selectedExtensions.length | |
22 | + && vm.query.search === null"> | |
23 | 23 | <div class="md-toolbar-tools"> |
24 | 24 | <span translate>{{ 'extension.extensions' }}</span> |
25 | 25 | <span flex></span> |
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | </div> |
45 | 45 | </md-toolbar> |
46 | 46 | <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedExtensions.length |
47 | - && vm.query.search != null""> | |
47 | + && vm.query.search != null" ng-class="{'toolbar-widget' : vm.inWidget}"> | |
48 | 48 | <div class="md-toolbar-tools"> |
49 | 49 | <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> |
50 | 50 | <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon> |
... | ... | @@ -58,13 +58,13 @@ |
58 | 58 | </md-input-container> |
59 | 59 | <md-button class="md-icon-button" aria-label="{{ 'action.back' | translate }}" ng-click="vm.exitFilterMode()"> |
60 | 60 | <md-icon aria-label="{{ 'action.close' | translate }}" class="material-icons">close</md-icon> |
61 | - <md-tooltip md-direction="top"> | |
61 | + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
62 | 62 | {{ 'action.close' | translate }} |
63 | 63 | </md-tooltip> |
64 | 64 | </md-button> |
65 | 65 | </div> |
66 | 66 | </md-toolbar> |
67 | - <md-toolbar class="md-table-toolbar alternate" ng-show="vm.selectedExtensions.length"> | |
67 | + <md-toolbar class="md-table-toolbar alternate" ng-show="vm.selectedExtensions.length" ng-class="{'toolbar-widget' : vm.inWidget}"> | |
68 | 68 | <div class="md-toolbar-tools"> |
69 | 69 | <span translate |
70 | 70 | translate-values="{count: vm.selectedExtensions.length}" |
... | ... | @@ -72,14 +72,14 @@ |
72 | 72 | <span flex></span> |
73 | 73 | <md-button class="md-icon-button" ng-click="vm.deleteExtensions($event)"> |
74 | 74 | <md-icon>delete</md-icon> |
75 | - <md-tooltip md-direction="top"> | |
75 | + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
76 | 76 | {{ 'action.delete' | translate }} |
77 | 77 | </md-tooltip> |
78 | 78 | </md-button> |
79 | 79 | </div> |
80 | 80 | </md-toolbar> |
81 | 81 | |
82 | - <div class="md-padding" flex layout="row"> | |
82 | + <div class="md-padding" flex layout="row" ng-class="{'sync-widget' : vm.inWidget}"> | |
83 | 83 | <md-input-container flex="50" class="md-block"> |
84 | 84 | <label translate>extension.sync.status</label> |
85 | 85 | <input ng-model="vm.syncStatus" |
... | ... | @@ -97,7 +97,7 @@ |
97 | 97 | </md-input-container> |
98 | 98 | </div> |
99 | 99 | |
100 | - <md-table-container> | |
100 | + <md-table-container flex> | |
101 | 101 | <table md-table md-row-select multiple="" ng-model="vm.selectedExtensions" md-progress="vm.extensionsDeferred.promise"> |
102 | 102 | <thead md-head md-order="vm.query.order" md-on-reorder="vm.onReorder"> |
103 | 103 | <tr md-row> |
... | ... | @@ -117,7 +117,7 @@ |
117 | 117 | {{ 'extension.edit' | translate }} |
118 | 118 | </md-tooltip> |
119 | 119 | </md-button> |
120 | - <md-button class="md-icon-button" aria-label="{{ 'action.delete' | translate }}" ng-click="vm.deleteExtension($event, extension)"> <!-- add click-function --> | |
120 | + <md-button class="md-icon-button" aria-label="{{ 'action.delete' | translate }}" ng-click="vm.deleteExtension($event, extension)"> | |
121 | 121 | <md-icon aria-label="{{ 'action.delete' | translate }}" class="material-icons">delete</md-icon> |
122 | 122 | <md-tooltip md-direction="top"> |
123 | 123 | {{ 'extension.delete' | translate }} |
... | ... | @@ -127,11 +127,12 @@ |
127 | 127 | </tr> |
128 | 128 | </tbody> |
129 | 129 | </table> |
130 | + <md-divider ng-if="vm.inWidget"></md-divider> | |
130 | 131 | </md-table-container> |
131 | 132 | <md-table-pagination md-limit="vm.query.limit" md-limit-options="[5, 10, 15]" |
132 | 133 | md-page="vm.query.page" md-total="{{vm.extensionsCount}}" |
133 | 134 | md-on-paginate="vm.onPaginate" md-page-select> |
134 | 135 | </md-table-pagination> |
135 | 136 | </div> |
136 | - <div></div> <!-- div for testing values --> | |
137 | + | |
137 | 138 | </md-content> |
\ No newline at end of file | ... | ... |
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 | +import './extensions-table-widget.scss'; | |
18 | + | |
19 | +/* eslint-disable import/no-unresolved, import/default */ | |
20 | + | |
21 | +import extensionsTableWidgetTemplate from './extensions-table-widget.tpl.html'; | |
22 | + | |
23 | +/* eslint-enable import/no-unresolved, import/default */ | |
24 | + | |
25 | +export default angular.module('thingsboard.widgets.extensionsTableWidget', []) | |
26 | + .directive('tbExtensionsTableWidget', ExtensionsTableWidget) | |
27 | + .name; | |
28 | + | |
29 | +/*@ngInject*/ | |
30 | +function ExtensionsTableWidget() { | |
31 | + return { | |
32 | + restrict: "E", | |
33 | + scope: true, | |
34 | + bindToController: { | |
35 | + ctx: '=' | |
36 | + }, | |
37 | + controller: ExtensionsTableWidgetController, | |
38 | + controllerAs: 'vm', | |
39 | + templateUrl: extensionsTableWidgetTemplate | |
40 | + }; | |
41 | +} | |
42 | + | |
43 | +/*@ngInject*/ | |
44 | +function ExtensionsTableWidgetController($scope, $translate, utils) { | |
45 | + var vm = this; | |
46 | + | |
47 | + vm.datasources = null; | |
48 | + vm.tabsHidden = false; | |
49 | + | |
50 | + $scope.$watch('vm.ctx', function() { | |
51 | + if (vm.ctx && vm.ctx.defaultSubscription) { | |
52 | + vm.settings = vm.ctx.settings; | |
53 | + vm.subscription = vm.ctx.defaultSubscription; | |
54 | + vm.datasources = vm.subscription.datasources; | |
55 | + initializeConfig(); | |
56 | + updateDatasources(); | |
57 | + } | |
58 | + }); | |
59 | + | |
60 | + function initializeConfig() { | |
61 | + | |
62 | + if (vm.settings.extensionsTitle && vm.settings.extensionsTitle.length) { | |
63 | + vm.extensionsTitle = utils.customTranslation(vm.settings.extensionsTitle, vm.settings.extensionsTitle); | |
64 | + } else { | |
65 | + vm.extensionsTitle = $translate.instant('extension.extensions'); | |
66 | + } | |
67 | + vm.ctx.widgetTitle = vm.extensionsTitle; | |
68 | + | |
69 | + vm.ctx.widgetActions = [vm.addAction, vm.searchAction, vm.refreshAction]; | |
70 | + } | |
71 | + | |
72 | + function updateDatasources() { | |
73 | + | |
74 | + var datasource = vm.datasources[0]; | |
75 | + vm.selectedSource = vm.datasources[0]; | |
76 | + vm.ctx.widgetTitle = utils.createLabelFromDatasource(datasource, vm.extensionsTitle); | |
77 | + } | |
78 | + | |
79 | + vm.changeSelectedSource = function(source) { | |
80 | + vm.selectedSource = source; | |
81 | + } | |
82 | + | |
83 | + vm.searchAction = { | |
84 | + name: "action.search", | |
85 | + show: true, | |
86 | + onAction: function() { | |
87 | + $scope.$broadcast("showSearch", vm.selectedSource); | |
88 | + }, | |
89 | + icon: "search" | |
90 | + }; | |
91 | + | |
92 | + vm.refreshAction = { | |
93 | + name: "action.refresh", | |
94 | + show: true, | |
95 | + onAction: function() { | |
96 | + $scope.$broadcast("refreshExtensions", vm.selectedSource); | |
97 | + }, | |
98 | + icon: "refresh" | |
99 | + } | |
100 | + | |
101 | + vm.addAction = { | |
102 | + name: "action.add", | |
103 | + show: true, | |
104 | + onAction: function() { | |
105 | + $scope.$broadcast("addExtension", vm.selectedSource); | |
106 | + }, | |
107 | + icon: "add" | |
108 | + } | |
109 | + | |
110 | + $scope.$on("filterMode", function($event, mode) { | |
111 | + vm.tabsHidden = mode; | |
112 | + }); | |
113 | + | |
114 | + $scope.$on("selectedExtensions", function($event, mode) { | |
115 | + vm.tabsHidden = mode; | |
116 | + }); | |
117 | +} | |
\ No newline at end of file | ... | ... |
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 | +tb-extension-table { | |
18 | + md-content { | |
19 | + background-color: #fff; | |
20 | + } | |
21 | +} | |
22 | +md-tabs.hide-tabs-menu { | |
23 | + md-tabs-wrapper { | |
24 | + display: none; | |
25 | + } | |
26 | + md-tabs-content-wrapper { | |
27 | + top: 0 !important; | |
28 | + } | |
29 | +} | |
\ 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 | +<md-tabs id="tabs" md-border-bottom flex class="tb-absolute-fill" ng-class="{'hide-tabs-menu': vm.datasources.length == 1 || vm.tabsHidden}"> | |
19 | + <md-tab ng-repeat="source in vm.datasources" label="{{ source.name }}" md-on-select="vm.changeSelectedSource(source)"> | |
20 | + <tb-extension-table flex | |
21 | + entity-id="source.entityId" | |
22 | + entity-type="{{source.entityType}}" | |
23 | + in-widget="true" | |
24 | + ctx="vm.ctx"> | |
25 | + </tb-extension-table> | |
26 | + </md-tab> | |
27 | +</md-tabs> | |
\ No newline at end of file | ... | ... |