Commit 2583cbed40eb0598581cb7fe28585ed9a8292ea4

Authored by Sergey Tarnavskiy
1 parent 32ece471

add extensions-widget

... ... @@ -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
... ...