Commit 9f87e4a73d5558507e47175ccf9f122ec239eca4

Authored by Igor Kulikov
1 parent bce5d933

Remove Rules and Plugins UI

... ... @@ -21,8 +21,7 @@ export default angular.module('thingsboard.api.entity', [thingsboardTypes])
21 21
22 22 /*@ngInject*/
23 23 function EntityService($http, $q, $filter, $translate, $log, userService, deviceService,
24   - assetService, tenantService, customerService,
25   - ruleService, pluginService, ruleChainService, dashboardService, entityRelationService, attributeService, types, utils) {
  24 + assetService, tenantService, customerService, ruleChainService, dashboardService, entityRelationService, attributeService, types, utils) {
26 25 var service = {
27 26 getEntity: getEntity,
28 27 getEntities: getEntities,
... ... @@ -61,12 +60,6 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
61 60 case types.entityType.customer:
62 61 promise = customerService.getCustomer(entityId, config);
63 62 break;
64   - case types.entityType.rule:
65   - promise = ruleService.getRule(entityId, config);
66   - break;
67   - case types.entityType.plugin:
68   - promise = pluginService.getPlugin(entityId, config);
69   - break;
70 63 case types.entityType.dashboard:
71 64 promise = dashboardService.getDashboardInfo(entityId, config);
72 65 break;
... ... @@ -146,14 +139,6 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
146 139 promise = getEntitiesByIdsPromise(
147 140 (id) => customerService.getCustomer(id, config), entityIds);
148 141 break;
149   - case types.entityType.rule:
150   - promise = getEntitiesByIdsPromise(
151   - (id) => ruleService.getRule(id, config), entityIds);
152   - break;
153   - case types.entityType.plugin:
154   - promise = getEntitiesByIdsPromise(
155   - (id) => pluginService.getPlugin(id, config), entityIds);
156   - break;
157 142 case types.entityType.dashboard:
158 143 promise = getEntitiesByIdsPromise(
159 144 (id) => dashboardService.getDashboardInfo(id, config), entityIds);
... ... @@ -268,12 +253,6 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
268 253 promise = customerService.getCustomers(pageLink, config);
269 254 }
270 255 break;
271   - case types.entityType.rule:
272   - promise = ruleService.getAllRules(pageLink, config);
273   - break;
274   - case types.entityType.plugin:
275   - promise = pluginService.getAllPlugins(pageLink, config);
276   - break;
277 256 case types.entityType.rulechain:
278 257 promise = ruleChainService.getRuleChains(pageLink, config);
279 258 break;
... ... @@ -742,16 +721,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
742 721 switch(authority) {
743 722 case 'SYS_ADMIN':
744 723 entityTypes.tenant = types.entityType.tenant;
745   - entityTypes.rule = types.entityType.rule;
746   - entityTypes.plugin = types.entityType.plugin;
747 724 break;
748 725 case 'TENANT_ADMIN':
749 726 entityTypes.device = types.entityType.device;
750 727 entityTypes.asset = types.entityType.asset;
751 728 entityTypes.tenant = types.entityType.tenant;
752 729 entityTypes.customer = types.entityType.customer;
753   - entityTypes.rule = types.entityType.rule;
754   - entityTypes.plugin = types.entityType.plugin;
755 730 entityTypes.dashboard = types.entityType.dashboard;
756 731 if (useAliasEntityTypes) {
757 732 entityTypes.current_customer = types.aliasEntityType.current_customer;
... ...
1   -/*
2   - * Copyright © 2016-2018 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   -export default angular.module('thingsboard.api.plugin', [])
17   - .factory('pluginService', PluginService).name;
18   -
19   -/*@ngInject*/
20   -function PluginService($http, $q, $rootScope, $filter, componentDescriptorService, types, utils) {
21   -
22   - var allPlugins = undefined;
23   - var allActionPlugins = undefined;
24   - var systemPlugins = undefined;
25   - var tenantPlugins = undefined;
26   -
27   - $rootScope.pluginServiceStateChangeStartHandle = $rootScope.$on('$stateChangeStart', function () {
28   - invalidatePluginsCache();
29   - });
30   -
31   - var service = {
32   - getSystemPlugins: getSystemPlugins,
33   - getTenantPlugins: getTenantPlugins,
34   - getAllPlugins: getAllPlugins,
35   - getAllActionPlugins: getAllActionPlugins,
36   - getPluginByToken: getPluginByToken,
37   - getPlugin: getPlugin,
38   - deletePlugin: deletePlugin,
39   - savePlugin: savePlugin,
40   - activatePlugin: activatePlugin,
41   - suspendPlugin: suspendPlugin
42   - }
43   -
44   - return service;
45   -
46   - function invalidatePluginsCache() {
47   - allPlugins = undefined;
48   - allActionPlugins = undefined;
49   - systemPlugins = undefined;
50   - tenantPlugins = undefined;
51   - }
52   -
53   - function loadPluginsCache(config) {
54   - var deferred = $q.defer();
55   - if (!allPlugins) {
56   - var url = '/api/plugins';
57   - $http.get(url, config).then(function success(response) {
58   - componentDescriptorService.getComponentDescriptorsByType(types.componentType.plugin).then(
59   - function success(pluginComponents) {
60   - allPlugins = response.data;
61   - allActionPlugins = [];
62   - systemPlugins = [];
63   - tenantPlugins = [];
64   - allPlugins = $filter('orderBy')(allPlugins, ['+name', '-createdTime']);
65   - var pluginHasActionsByClazz = {};
66   - for (var index in pluginComponents) {
67   - pluginHasActionsByClazz[pluginComponents[index].clazz] =
68   - (pluginComponents[index].actions != null && pluginComponents[index].actions.length > 0);
69   - }
70   - for (var i = 0; i < allPlugins.length; i++) {
71   - var plugin = allPlugins[i];
72   - if (pluginHasActionsByClazz[plugin.clazz] === true) {
73   - allActionPlugins.push(plugin);
74   - }
75   - if (plugin.tenantId.id === types.id.nullUid) {
76   - systemPlugins.push(plugin);
77   - } else {
78   - tenantPlugins.push(plugin);
79   - }
80   - }
81   - deferred.resolve();
82   - },
83   - function fail() {
84   - deferred.reject();
85   - }
86   - );
87   - }, function fail() {
88   - deferred.reject();
89   - });
90   - } else {
91   - deferred.resolve();
92   - }
93   - return deferred.promise;
94   - }
95   -
96   - function getSystemPlugins(pageLink, config) {
97   - var deferred = $q.defer();
98   - loadPluginsCache(config).then(
99   - function success() {
100   - utils.filterSearchTextEntities(systemPlugins, 'name', pageLink, deferred);
101   - },
102   - function fail() {
103   - deferred.reject();
104   - }
105   - );
106   - return deferred.promise;
107   - }
108   -
109   - function getTenantPlugins(pageLink, config) {
110   - var deferred = $q.defer();
111   - loadPluginsCache(config).then(
112   - function success() {
113   - utils.filterSearchTextEntities(tenantPlugins, 'name', pageLink, deferred);
114   - },
115   - function fail() {
116   - deferred.reject();
117   - }
118   - );
119   - return deferred.promise;
120   - }
121   -
122   - function getAllActionPlugins(pageLink, config) {
123   - var deferred = $q.defer();
124   - loadPluginsCache(config).then(
125   - function success() {
126   - utils.filterSearchTextEntities(allActionPlugins, 'name', pageLink, deferred);
127   - },
128   - function fail() {
129   - deferred.reject();
130   - }
131   - );
132   - return deferred.promise;
133   - }
134   -
135   - function getAllPlugins(pageLink, config) {
136   - var deferred = $q.defer();
137   - loadPluginsCache(config).then(
138   - function success() {
139   - utils.filterSearchTextEntities(allPlugins, 'name', pageLink, deferred);
140   - },
141   - function fail() {
142   - deferred.reject();
143   - }
144   - );
145   - return deferred.promise;
146   - }
147   -
148   - function getPluginByToken(pluginToken) {
149   - var deferred = $q.defer();
150   - var url = '/api/plugin/token/' + pluginToken;
151   - $http.get(url, null).then(function success(response) {
152   - deferred.resolve(response.data);
153   - }, function fail() {
154   - deferred.reject();
155   - });
156   - return deferred.promise;
157   - }
158   -
159   - function getPlugin(pluginId, config) {
160   - var deferred = $q.defer();
161   - var url = '/api/plugin/' + pluginId;
162   - $http.get(url, config).then(function success(response) {
163   - deferred.resolve(response.data);
164   - }, function fail(response) {
165   - deferred.reject(response.data);
166   - });
167   - return deferred.promise;
168   - }
169   -
170   - function savePlugin(plugin) {
171   - var deferred = $q.defer();
172   - var url = '/api/plugin';
173   - $http.post(url, plugin).then(function success(response) {
174   - invalidatePluginsCache();
175   - deferred.resolve(response.data);
176   - }, function fail(response) {
177   - deferred.reject(response.data);
178   - });
179   - return deferred.promise;
180   - }
181   -
182   - function deletePlugin(pluginId) {
183   - var deferred = $q.defer();
184   - var url = '/api/plugin/' + pluginId;
185   - $http.delete(url).then(function success() {
186   - invalidatePluginsCache();
187   - deferred.resolve();
188   - }, function fail(response) {
189   - deferred.reject(response.data);
190   - });
191   - return deferred.promise;
192   - }
193   -
194   - function activatePlugin(pluginId) {
195   - var deferred = $q.defer();
196   - var url = '/api/plugin/' + pluginId + '/activate';
197   - $http.post(url, null).then(function success(response) {
198   - invalidatePluginsCache();
199   - deferred.resolve(response.data);
200   - }, function fail(response) {
201   - deferred.reject(response.data);
202   - });
203   - return deferred.promise;
204   - }
205   -
206   - function suspendPlugin(pluginId) {
207   - var deferred = $q.defer();
208   - var url = '/api/plugin/' + pluginId + '/suspend';
209   - $http.post(url, null).then(function success(response) {
210   - invalidatePluginsCache();
211   - deferred.resolve(response.data);
212   - }, function fail(response) {
213   - deferred.reject(response.data);
214   - });
215   - return deferred.promise;
216   - }
217   -
218   -}
1   -/*
2   - * Copyright © 2016-2018 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   -export default angular.module('thingsboard.api.rule', [])
17   - .factory('ruleService', RuleService).name;
18   -
19   -/*@ngInject*/
20   -function RuleService($http, $q, $rootScope, $filter, types, utils) {
21   -
22   - var allRules = undefined;
23   - var systemRules = undefined;
24   - var tenantRules = undefined;
25   -
26   - $rootScope.ruleServiceStateChangeStartHandle = $rootScope.$on('$stateChangeStart', function () {
27   - invalidateRulesCache();
28   - });
29   -
30   - var service = {
31   - getSystemRules: getSystemRules,
32   - getTenantRules: getTenantRules,
33   - getAllRules: getAllRules,
34   - getRulesByPluginToken: getRulesByPluginToken,
35   - getRule: getRule,
36   - deleteRule: deleteRule,
37   - saveRule: saveRule,
38   - activateRule: activateRule,
39   - suspendRule: suspendRule
40   - }
41   -
42   - return service;
43   -
44   - function invalidateRulesCache() {
45   - allRules = undefined;
46   - systemRules = undefined;
47   - tenantRules = undefined;
48   - }
49   -
50   - function loadRulesCache(config) {
51   - var deferred = $q.defer();
52   - if (!allRules) {
53   - var url = '/api/rules';
54   - $http.get(url, config).then(function success(response) {
55   - allRules = response.data;
56   - systemRules = [];
57   - tenantRules = [];
58   - allRules = $filter('orderBy')(allRules, ['+name', '-createdTime']);
59   - for (var i = 0; i < allRules.length; i++) {
60   - var rule = allRules[i];
61   - if (rule.tenantId.id === types.id.nullUid) {
62   - systemRules.push(rule);
63   - } else {
64   - tenantRules.push(rule);
65   - }
66   - }
67   - deferred.resolve();
68   - }, function fail() {
69   - deferred.reject();
70   - });
71   - } else {
72   - deferred.resolve();
73   - }
74   - return deferred.promise;
75   - }
76   -
77   - function getSystemRules(pageLink) {
78   - var deferred = $q.defer();
79   - loadRulesCache().then(
80   - function success() {
81   - utils.filterSearchTextEntities(systemRules, 'name', pageLink, deferred);
82   - },
83   - function fail() {
84   - deferred.reject();
85   - }
86   - );
87   - return deferred.promise;
88   - }
89   -
90   - function getTenantRules(pageLink) {
91   - var deferred = $q.defer();
92   - loadRulesCache().then(
93   - function success() {
94   - utils.filterSearchTextEntities(tenantRules, 'name', pageLink, deferred);
95   - },
96   - function fail() {
97   - deferred.reject();
98   - }
99   - );
100   - return deferred.promise;
101   - }
102   -
103   - function getAllRules(pageLink, config) {
104   - var deferred = $q.defer();
105   - loadRulesCache(config).then(
106   - function success() {
107   - utils.filterSearchTextEntities(allRules, 'name', pageLink, deferred);
108   - },
109   - function fail() {
110   - deferred.reject();
111   - }
112   - );
113   - return deferred.promise;
114   - }
115   -
116   - function getRulesByPluginToken(pluginToken) {
117   - var deferred = $q.defer();
118   - var url = '/api/rule/token/' + pluginToken;
119   - $http.get(url, null).then(function success(response) {
120   - deferred.resolve(response.data);
121   - }, function fail() {
122   - deferred.reject();
123   - });
124   - return deferred.promise;
125   - }
126   -
127   - function getRule(ruleId, config) {
128   - var deferred = $q.defer();
129   - var url = '/api/rule/' + ruleId;
130   - $http.get(url, config).then(function success(response) {
131   - deferred.resolve(response.data);
132   - }, function fail(response) {
133   - deferred.reject(response.data);
134   - });
135   - return deferred.promise;
136   - }
137   -
138   - function saveRule(rule) {
139   - var deferred = $q.defer();
140   - var url = '/api/rule';
141   - $http.post(url, rule).then(function success(response) {
142   - invalidateRulesCache();
143   - deferred.resolve(response.data);
144   - }, function fail(response) {
145   - deferred.reject(response.data);
146   - });
147   - return deferred.promise;
148   - }
149   -
150   - function deleteRule(ruleId) {
151   - var deferred = $q.defer();
152   - var url = '/api/rule/' + ruleId;
153   - $http.delete(url).then(function success() {
154   - invalidateRulesCache();
155   - deferred.resolve();
156   - }, function fail(response) {
157   - deferred.reject(response.data);
158   - });
159   - return deferred.promise;
160   - }
161   -
162   - function activateRule(ruleId) {
163   - var deferred = $q.defer();
164   - var url = '/api/rule/' + ruleId + '/activate';
165   - $http.post(url, null).then(function success(response) {
166   - invalidateRulesCache();
167   - deferred.resolve(response.data);
168   - }, function fail(response) {
169   - deferred.reject(response.data);
170   - });
171   - return deferred.promise;
172   - }
173   -
174   - function suspendRule(ruleId) {
175   - var deferred = $q.defer();
176   - var url = '/api/rule/' + ruleId + '/suspend';
177   - $http.post(url, null).then(function success(response) {
178   - invalidateRulesCache();
179   - deferred.resolve(response.data);
180   - }, function fail(response) {
181   - deferred.reject(response.data);
182   - });
183   - return deferred.promise;
184   - }
185   -
186   -}
... ... @@ -74,6 +74,7 @@ import thingsboardApiAttribute from './api/attribute.service';
74 74 import thingsboardApiEntity from './api/entity.service';
75 75 import thingsboardApiAlarm from './api/alarm.service';
76 76 import thingsboardApiAuditLog from './api/audit-log.service';
  77 +import thingsboardApiComponentDescriptor from './api/component-descriptor.service';
77 78 import thingsboardApiRuleChain from './api/rule-chain.service';
78 79
79 80 import 'typeface-roboto';
... ... @@ -139,6 +140,7 @@ angular.module('thingsboard', [
139 140 thingsboardApiEntity,
140 141 thingsboardApiAlarm,
141 142 thingsboardApiAuditLog,
  143 + thingsboardApiComponentDescriptor,
142 144 thingsboardApiRuleChain,
143 145 uiRouter])
144 146 .config(AppConfig)
... ...
... ... @@ -297,16 +297,15 @@ export default angular.module('thingsboard.types', [])
297 297 }
298 298 },
299 299 componentType: {
  300 + enrichment: "ENRICHMENT",
300 301 filter: "FILTER",
301   - processor: "PROCESSOR",
  302 + transformation: "TRANSFORMATION",
302 303 action: "ACTION",
303   - plugin: "PLUGIN"
  304 + external: "EXTERNAL"
304 305 },
305 306 entityType: {
306 307 device: "DEVICE",
307 308 asset: "ASSET",
308   - rule: "RULE",
309   - plugin: "PLUGIN",
310 309 tenant: "TENANT",
311 310 customer: "CUSTOMER",
312 311 user: "USER",
... ... @@ -331,18 +330,6 @@ export default angular.module('thingsboard.types', [])
331 330 list: 'entity.list-of-assets',
332 331 nameStartsWith: 'entity.asset-name-starts-with'
333 332 },
334   - "RULE": {
335   - type: 'entity.type-rule',
336   - typePlural: 'entity.type-rules',
337   - list: 'entity.list-of-rules',
338   - nameStartsWith: 'entity.rule-name-starts-with'
339   - },
340   - "PLUGIN": {
341   - type: 'entity.type-plugin',
342   - typePlural: 'entity.type-plugins',
343   - list: 'entity.list-of-plugins',
344   - nameStartsWith: 'entity.plugin-name-starts-with'
345   - },
346 333 "TENANT": {
347 334 type: 'entity.type-tenant',
348 335 typePlural: 'entity.type-tenants',
... ...
1   -/*
2   - * Copyright © 2016-2018 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   -/*@ngInject*/
17   -export default function ComponentDialogController($mdDialog, $q, $scope, componentDescriptorService, types, utils, helpLinks, isAdd, isReadOnly, componentInfo) {
18   -
19   - var vm = this;
20   -
21   - vm.isReadOnly = isReadOnly;
22   - vm.isAdd = isAdd;
23   - vm.componentInfo = componentInfo;
24   - if (isAdd) {
25   - vm.componentInfo.component = {};
26   - }
27   -
28   - vm.componentHasSchema = false;
29   - vm.componentDescriptors = [];
30   -
31   - if (vm.componentInfo.component && !vm.componentInfo.component.configuration) {
32   - vm.componentInfo.component.configuration = {};
33   - }
34   -
35   - vm.helpLinkIdForComponent = helpLinkIdForComponent;
36   - vm.save = save;
37   - vm.cancel = cancel;
38   -
39   - $scope.$watch("vm.componentInfo.component.clazz", function (newValue, prevValue) {
40   - if (newValue != prevValue) {
41   - if (newValue && prevValue) {
42   - vm.componentInfo.component.configuration = {};
43   - }
44   - loadComponentDescriptor();
45   - }
46   - });
47   -
48   - var componentDescriptorsPromise =
49   - vm.componentInfo.type === types.componentType.action
50   - ? componentDescriptorService.getPluginActionsByPluginClazz(vm.componentInfo.pluginClazz)
51   - : componentDescriptorService.getComponentDescriptorsByType(vm.componentInfo.type);
52   -
53   - componentDescriptorsPromise.then(
54   - function success(componentDescriptors) {
55   - vm.componentDescriptors = componentDescriptors;
56   - if (vm.componentDescriptors.length === 1 && isAdd && !vm.componentInfo.component.clazz) {
57   - vm.componentInfo.component.clazz = vm.componentDescriptors[0].clazz;
58   - }
59   - },
60   - function fail() {
61   - }
62   - );
63   -
64   - loadComponentDescriptor();
65   -
66   - function loadComponentDescriptor () {
67   - if (vm.componentInfo.component.clazz) {
68   - componentDescriptorService.getComponentDescriptorByClazz(vm.componentInfo.component.clazz).then(
69   - function success(componentDescriptor) {
70   - vm.componentDescriptor = componentDescriptor;
71   - vm.componentHasSchema = utils.isDescriptorSchemaNotEmpty(vm.componentDescriptor.configurationDescriptor);
72   - },
73   - function fail() {
74   - }
75   - );
76   - } else {
77   - vm.componentHasSchema = false;
78   - }
79   - }
80   -
81   - function helpLinkIdForComponent() {
82   - switch (vm.componentInfo.type) {
83   - case types.componentType.filter: {
84   - return helpLinks.getFilterLink(vm.componentInfo.component);
85   - }
86   - case types.componentType.processor: {
87   - return helpLinks.getProcessorLink(vm.componentInfo.component);
88   - }
89   - case types.componentType.action: {
90   - return helpLinks.getPluginActionLink(vm.componentInfo.component);
91   - }
92   -
93   - }
94   - }
95   -
96   -
97   - function cancel () {
98   - $mdDialog.cancel();
99   - }
100   -
101   - function save () {
102   - $mdDialog.hide(vm.componentInfo.component);
103   - }
104   -
105   -}
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import componentDialogTemplate from './component-dialog.tpl.html';
19   -
20   -/* eslint-enable import/no-unresolved, import/default */
21   -
22   -/*@ngInject*/
23   -export default function ComponentDialogService($mdDialog, $document, $q) {
24   -
25   - var service = {
26   - openComponentDialog: openComponentDialog
27   - }
28   -
29   - return service;
30   -
31   - function openComponentDialog($event, isAdd, readOnly, title, type, pluginClazz, component) {
32   - var deferred = $q.defer();
33   - var componentInfo = {
34   - title: title,
35   - type: type,
36   - pluginClazz: pluginClazz
37   - };
38   - if (component) {
39   - componentInfo.component = angular.copy(component);
40   - }
41   - $mdDialog.show({
42   - controller: 'ComponentDialogController',
43   - controllerAs: 'vm',
44   - templateUrl: componentDialogTemplate,
45   - locals: {isAdd: isAdd,
46   - isReadOnly: readOnly,
47   - componentInfo: componentInfo},
48   - parent: angular.element($document[0].body),
49   - fullscreen: true,
50   - targetEvent: $event,
51   - skipHide: true
52   - }).then(function (component) {
53   - deferred.resolve(component);
54   - }, function () {
55   - deferred.reject();
56   - });
57   - return deferred.promise;
58   - }
59   -
60   -}
\ No newline at end of file
1   -<!--
2   -
3   - Copyright © 2016-2018 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-dialog aria-label="{{ vm.componentInfo.title | translate }}" tb-help="vm.helpLinkIdForComponent()" help-container-id="help-container">
19   - <form name="theForm" ng-submit="vm.save()">
20   - <md-toolbar>
21   - <div class="md-toolbar-tools">
22   - <h2 translate>{{ vm.componentInfo.title }}</h2>
23   - <span flex></span>
24   - <div id="help-container"></div>
25   - <md-button class="md-icon-button" ng-click="vm.cancel()">
26   - <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon>
27   - </md-button>
28   - </div>
29   - </md-toolbar>
30   - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear>
31   - <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
32   - <md-dialog-content>
33   - <div class="md-dialog-content tb-filter">
34   - <fieldset ng-disabled="$root.loading || vm.isReadOnly">
35   - <section flex layout="row">
36   - <md-input-container flex class="md-block">
37   - <label translate>rule.component-name</label>
38   - <input required name="componentName" ng-model="vm.componentInfo.component.name">
39   - <div ng-messages="theForm.componentName.$error">
40   - <div translate ng-message="required">rule.component-name-required</div>
41   - </div>
42   - </md-input-container>
43   - <md-input-container flex class="md-block">
44   - <label translate>rule.component-type</label>
45   - <md-select required name="componentType" ng-model="vm.componentInfo.component.clazz" ng-disabled="$root.loading || vm.isReadOnly">
46   - <md-option ng-repeat="componentDescriptor in vm.componentDescriptors" ng-value="componentDescriptor.clazz">
47   - {{componentDescriptor.name}}
48   - </md-option>
49   - </md-select>
50   - <div ng-messages="theForm.componentType.$error">
51   - <div translate ng-message="required">rule.component-type-required</div>
52   - </div>
53   - </md-input-container>
54   - </section>
55   - <md-card flex class="plugin-config" ng-if="vm.componentHasSchema">
56   - <md-card-content>
57   - <tb-json-form schema="vm.componentDescriptor.configurationDescriptor.schema"
58   - form="vm.componentDescriptor.configurationDescriptor.form"
59   - model="vm.componentInfo.component.configuration"
60   - readonly="$root.loading || vm.isReadOnly"
61   - form-control="theForm">
62   - </tb-json-form>
63   - </md-card-content>
64   - </md-card>
65   - </fieldset>
66   - </div>
67   - </md-dialog-content>
68   - <md-dialog-actions layout="row">
69   - <span flex></span>
70   - <md-button ng-if="!vm.isReadOnly" ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit"
71   - class="md-raised md-primary">
72   - {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }}
73   - </md-button>
74   - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' |
75   - translate }}
76   - </md-button>
77   - </md-dialog-actions>
78   - </form>
79   -</md-dialog>
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import componentTemplate from './component.tpl.html';
19   -
20   -/* eslint-enable import/no-unresolved, import/default */
21   -
22   -/*@ngInject*/
23   -export default function ComponentDirective($compile, $templateCache, $document, $mdDialog, componentDialogService, componentDescriptorService) {
24   -
25   - var linker = function (scope, element) {
26   -
27   - var template = $templateCache.get(componentTemplate);
28   -
29   - element.html(template);
30   -
31   - scope.componentTypeName = '';
32   -
33   - scope.loadComponentTypeName = function () {
34   - componentDescriptorService.getComponentDescriptorByClazz(scope.component.clazz).then(
35   - function success(component) {
36   - scope.componentTypeName = component.name;
37   - },
38   - function fail() {}
39   - );
40   - }
41   -
42   - scope.$watch('component', function(newVal) {
43   - if (newVal) {
44   - scope.loadComponentTypeName();
45   - }
46   - }
47   - );
48   -
49   - scope.openComponent = function($event) {
50   - componentDialogService.openComponentDialog($event, false,
51   - scope.readOnly, scope.title, scope.type, scope.pluginClazz,
52   - angular.copy(scope.component)).then(
53   - function success(component) {
54   - scope.component = component;
55   - },
56   - function fail() {}
57   - );
58   - }
59   -
60   - $compile(element.contents())(scope);
61   - }
62   -
63   - return {
64   - restrict: "E",
65   - link: linker,
66   - scope: {
67   - component: '=',
68   - type: '=',
69   - pluginClazz: '=',
70   - title: '@',
71   - readOnly: '=',
72   - onRemoveComponent: '&'
73   - }
74   - };
75   -}
1   -<!--
2   -
3   - Copyright © 2016-2018 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   -<div class="md-whiteframe-4dp" flex layout="row" layout-align="start center"
19   - style="padding: 0 0 0 10px; margin: 5px;">
20   - <span flex="50">
21   - {{ component.name }}
22   - </span>
23   - <span flex="50">
24   - {{ componentTypeName }}
25   - </span>
26   - <span ng-if="readOnly" style="min-width: 40px; min-height: 40px; margin: 0 6px;"></br></span>
27   - <md-button ng-disabled="$root.loading" class="md-icon-button md-primary"
28   - style="min-width: 40px;"
29   - ng-click="openComponent($event)"
30   - aria-label="{{ (readOnly ? 'action.view' : 'action.edit') | translate }}">
31   - <md-tooltip ng-if="readOnly" md-direction="top">
32   - {{ 'action.view' | translate }}
33   - </md-tooltip>
34   - <md-tooltip ng-if="!readOnly" md-direction="top">
35   - {{ 'action.edit' | translate }}
36   - </md-tooltip>
37   - <md-icon ng-if="readOnly" aria-label="{{ 'action.view' | translate }}"
38   - class="material-icons">
39   - more_horiz
40   - </md-icon>
41   - <md-icon ng-if="!readOnly" aria-label="{{ 'action.edit' | translate }}"
42   - class="material-icons">
43   - edit
44   - </md-icon>
45   - </md-button>
46   - <md-button ng-if="!readOnly" ng-disabled="$root.loading" class="md-icon-button md-primary"
47   - style="min-width: 40px;"
48   - ng-click="onRemoveComponent({event: $event})"
49   - aria-label="{{ 'action.remove' | translate }}">
50   - <md-tooltip md-direction="top">
51   - {{ 'action.remove' | translate }}
52   - </md-tooltip>
53   - <md-icon aria-label="{{ 'action.delete' | translate }}"
54   - class="material-icons">
55   - close
56   - </md-icon>
57   - </md-button>
58   -</div>
\ No newline at end of file
1   -/*
2   - * Copyright © 2016-2018 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   -import thingsboardApiComponentDescriptor from '../api/component-descriptor.service';
17   -
18   -import ComponentDialogService from './component-dialog.service';
19   -import ComponentDialogController from './component-dialog.controller';
20   -import ComponentDirective from './component.directive';
21   -
22   -export default angular.module('thingsboard.component', [
23   - thingsboardApiComponentDescriptor
24   -])
25   - .factory('componentDialogService', ComponentDialogService)
26   - .controller('ComponentDialogController', ComponentDialogController)
27   - .directive('tbComponent', ComponentDirective)
28   - .name;
1   -/*
2   - * Copyright © 2016-2018 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   -import './plugin-select.scss';
17   -
18   -import thingsboardApiPlugin from '../api/plugin.service';
19   -
20   -/* eslint-disable import/no-unresolved, import/default */
21   -
22   -import pluginSelectTemplate from './plugin-select.tpl.html';
23   -
24   -/* eslint-enable import/no-unresolved, import/default */
25   -
26   -
27   -export default angular.module('thingsboard.directives.pluginSelect', [thingsboardApiPlugin])
28   - .directive('tbPluginSelect', PluginSelect)
29   - .name;
30   -
31   -/*@ngInject*/
32   -function PluginSelect($compile, $templateCache, $q, pluginService, types) {
33   -
34   - var linker = function (scope, element, attrs, ngModelCtrl) {
35   - var template = $templateCache.get(pluginSelectTemplate);
36   - element.html(template);
37   -
38   - scope.tbRequired = angular.isDefined(scope.tbRequired) ? scope.tbRequired : false;
39   - scope.plugin = null;
40   - scope.pluginSearchText = '';
41   - scope.searchTextChanged = false;
42   -
43   - scope.pluginFetchFunction = pluginService.getAllPlugins;
44   - if (angular.isDefined(scope.pluginsScope)) {
45   - if (scope.pluginsScope === 'action') {
46   - scope.pluginFetchFunction = pluginService.getAllActionPlugins;
47   - } else if (scope.pluginsScope === 'system') {
48   - scope.pluginFetchFunction = pluginService.getSystemPlugins;
49   - } else if (scope.pluginsScope === 'tenant') {
50   - scope.pluginFetchFunction = pluginService.getTenantPlugins;
51   - }
52   - }
53   -
54   - scope.fetchPlugins = function(searchText) {
55   - var pageLink = {limit: 10, textSearch: searchText};
56   -
57   - var deferred = $q.defer();
58   -
59   - scope.pluginFetchFunction(pageLink, {ignoreLoading: true}).then(function success(result) {
60   - deferred.resolve(result.data);
61   - }, function fail() {
62   - deferred.reject();
63   - });
64   -
65   - return deferred.promise;
66   - }
67   -
68   - scope.pluginSearchTextChanged = function() {
69   - scope.searchTextChanged = true;
70   - }
71   -
72   - scope.isSystem = function(item) {
73   - return item && item.tenantId.id === types.id.nullUid;
74   - }
75   -
76   - scope.updateView = function () {
77   - ngModelCtrl.$setViewValue(scope.plugin);
78   - }
79   -
80   - ngModelCtrl.$render = function () {
81   - if (ngModelCtrl.$viewValue) {
82   - scope.plugin = ngModelCtrl.$viewValue;
83   - }
84   - }
85   -
86   - scope.$watch('plugin', function () {
87   - scope.updateView();
88   - })
89   -
90   - if (scope.selectFirstPlugin) {
91   - var pageLink = {limit: 1, textSearch: ''};
92   - scope.pluginFetchFunction(pageLink, {ignoreLoading: true}).then(function success(result) {
93   - var plugins = result.data;
94   - if (plugins.length > 0) {
95   - scope.plugin = plugins[0];
96   - }
97   - }, function fail() {
98   - });
99   - }
100   -
101   - $compile(element.contents())(scope);
102   - }
103   -
104   - return {
105   - restrict: "E",
106   - require: "^ngModel",
107   - link: linker,
108   - scope: {
109   - pluginsScope: '@',
110   - theForm: '=?',
111   - tbRequired: '=?',
112   - selectFirstPlugin: '='
113   - }
114   - };
115   -}
1   -/**
2   - * Copyright © 2016-2018 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   -@import "../../scss/mixins";
17   -
18   -.tb-plugin-autocomplete {
19   - .tb-not-found {
20   - display: block;
21   - line-height: 1.5;
22   - height: 48px;
23   - }
24   - .tb-plugin-item {
25   - display: block;
26   - height: 48px;
27   - .tb-plugin-system {
28   - font-size: 0.8rem;
29   - opacity: 0.8;
30   - float: right;
31   - }
32   - }
33   - li {
34   - height: auto !important;
35   - white-space: normal !important;
36   - }
37   -}
1   -<!--
2   -
3   - Copyright © 2016-2018 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-autocomplete ng-required="tbRequired"
19   - md-input-name="plugin"
20   - ng-model="plugin"
21   - md-selected-item="plugin"
22   - md-search-text="pluginSearchText"
23   - md-search-text-change="pluginSearchTextChanged()"
24   - md-items="item in fetchPlugins(pluginSearchText)"
25   - md-item-text="item.name"
26   - md-min-length="0"
27   - placeholder="{{ 'plugin.select-plugin' | translate }}"
28   - md-menu-class="tb-plugin-autocomplete">
29   - <md-item-template>
30   - <div class="tb-plugin-item">
31   - <span md-highlight-text="pluginSearchText" md-highlight-flags="^i">{{item.name}}</span>
32   - <span translate class="tb-plugin-system" ng-if="isSystem(item)">plugin.system</span>
33   - </div>
34   - </md-item-template>
35   - <md-not-found>
36   - <div class="tb-not-found">
37   - <span translate translate-values='{ entity: pluginSearchText }'>plugin.no-plugins-matching</span>
38   - </div>
39   - </md-not-found>
40   -</md-autocomplete>
41   -<div ng-if="searchTextChanged" class="tb-error-messages" ng-messages="theForm.plugin.$error" role="alert">
42   - <div translate ng-message="required" class="tb-error-message">plugin.plugin-required</div>
43   - <div translate ng-message="md-require-match" class="tb-error-message">plugin.plugin-require-match</div>
44   -</div>
... ... @@ -131,18 +131,6 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter
131 131 scope.noEntitiesMatchingText = 'device.no-devices-matching';
132 132 scope.entityRequiredText = 'device.device-required';
133 133 break;
134   - case types.entityType.rule:
135   - scope.selectEntityText = 'rule.select-rule';
136   - scope.entityText = 'rule.rule';
137   - scope.noEntitiesMatchingText = 'rule.no-rules-matching';
138   - scope.entityRequiredText = 'rule.rule-required';
139   - break;
140   - case types.entityType.plugin:
141   - scope.selectEntityText = 'plugin.select-plugin';
142   - scope.entityText = 'plugin.plugin';
143   - scope.noEntitiesMatchingText = 'plugin.no-plugins-matching';
144   - scope.entityRequiredText = 'plugin.plugin-required';
145   - break;
146 134 case types.entityType.rulechain:
147 135 scope.selectEntityText = 'rulechain.select-rulechain';
148 136 scope.entityText = 'rulechain.rulechain';
... ...
... ... @@ -25,8 +25,7 @@ import entityAliasesTemplate from '../entity/alias/entity-aliases.tpl.html';
25 25
26 26 /*@ngInject*/
27 27 export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types,
28   - dashboardUtils, entityService, dashboardService, pluginService, ruleService,
29   - ruleChainService, widgetService, toast, attributeService) {
  28 + dashboardUtils, entityService, dashboardService, ruleChainService, widgetService, toast, attributeService) {
30 29
31 30
32 31 var service = {
... ... @@ -34,10 +33,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
34 33 importDashboard: importDashboard,
35 34 exportWidget: exportWidget,
36 35 importWidget: importWidget,
37   - exportPlugin: exportPlugin,
38   - importPlugin: importPlugin,
39   - exportRule: exportRule,
40   - importRule: importRule,
41 36 exportRuleChain: exportRuleChain,
42 37 importRuleChain: importRuleChain,
43 38 exportWidgetType: exportWidgetType,
... ... @@ -221,62 +216,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
221 216 return true;
222 217 }
223 218
224   - // Rule functions
225   -
226   - function exportRule(ruleId) {
227   - ruleService.getRule(ruleId).then(
228   - function success(rule) {
229   - var name = rule.name;
230   - name = name.toLowerCase().replace(/\W/g,"_");
231   - exportToPc(prepareExport(rule), name + '.json');
232   - },
233   - function fail(rejection) {
234   - var message = rejection;
235   - if (!message) {
236   - message = $translate.instant('error.unknown-error');
237   - }
238   - toast.showError($translate.instant('rule.export-failed-error', {error: message}));
239   - }
240   - );
241   - }
242   -
243   - function importRule($event) {
244   - var deferred = $q.defer();
245   - openImportDialog($event, 'rule.import', 'rule.rule-file').then(
246   - function success(rule) {
247   - if (!validateImportedRule(rule)) {
248   - toast.showError($translate.instant('rule.invalid-rule-file-error'));
249   - deferred.reject();
250   - } else {
251   - rule.state = 'SUSPENDED';
252   - ruleService.saveRule(rule).then(
253   - function success() {
254   - deferred.resolve();
255   - },
256   - function fail() {
257   - deferred.reject();
258   - }
259   - );
260   - }
261   - },
262   - function fail() {
263   - deferred.reject();
264   - }
265   - );
266   - return deferred.promise;
267   - }
268   -
269   - function validateImportedRule(rule) {
270   - if (angular.isUndefined(rule.name)
271   - || angular.isUndefined(rule.pluginToken)
272   - || angular.isUndefined(rule.filters)
273   - || angular.isUndefined(rule.action))
274   - {
275   - return false;
276   - }
277   - return true;
278   - }
279   -
280 219 // Rule chain functions
281 220
282 221 function exportRuleChain(ruleChainId) {
... ... @@ -361,65 +300,6 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
361 300 return true;
362 301 }
363 302
364   - // Plugin functions
365   -
366   - function exportPlugin(pluginId) {
367   - pluginService.getPlugin(pluginId).then(
368   - function success(plugin) {
369   - if (!plugin.configuration || plugin.configuration === null) {
370   - plugin.configuration = {};
371   - }
372   - var name = plugin.name;
373   - name = name.toLowerCase().replace(/\W/g,"_");
374   - exportToPc(prepareExport(plugin), name + '.json');
375   - },
376   - function fail(rejection) {
377   - var message = rejection;
378   - if (!message) {
379   - message = $translate.instant('error.unknown-error');
380   - }
381   - toast.showError($translate.instant('plugin.export-failed-error', {error: message}));
382   - }
383   - );
384   - }
385   -
386   - function importPlugin($event) {
387   - var deferred = $q.defer();
388   - openImportDialog($event, 'plugin.import', 'plugin.plugin-file').then(
389   - function success(plugin) {
390   - if (!validateImportedPlugin(plugin)) {
391   - toast.showError($translate.instant('plugin.invalid-plugin-file-error'));
392   - deferred.reject();
393   - } else {
394   - plugin.state = 'SUSPENDED';
395   - pluginService.savePlugin(plugin).then(
396   - function success() {
397   - deferred.resolve();
398   - },
399   - function fail() {
400   - deferred.reject();
401   - }
402   - );
403   - }
404   - },
405   - function fail() {
406   - deferred.reject();
407   - }
408   - );
409   - return deferred.promise;
410   - }
411   -
412   - function validateImportedPlugin(plugin) {
413   - if (angular.isUndefined(plugin.name)
414   - || angular.isUndefined(plugin.clazz)
415   - || angular.isUndefined(plugin.apiToken)
416   - || angular.isUndefined(plugin.configuration))
417   - {
418   - return false;
419   - }
420   - return true;
421   - }
422   -
423 303 // Widget functions
424 304
425 305 function exportWidget(dashboard, sourceState, sourceLayout, widget) {
... ...
... ... @@ -50,8 +50,6 @@ import thingsboardAsset from '../asset';
50 50 import thingsboardDevice from '../device';
51 51 import thingsboardWidgetLibrary from '../widget';
52 52 import thingsboardDashboard from '../dashboard';
53   -import thingsboardPlugin from '../plugin';
54   -import thingsboardRule from '../rule';
55 53 import thingsboardRuleChain from '../rulechain';
56 54
57 55 import thingsboardJsonForm from '../jsonform';
... ... @@ -83,8 +81,6 @@ export default angular.module('thingsboard.home', [
83 81 thingsboardDevice,
84 82 thingsboardWidgetLibrary,
85 83 thingsboardDashboard,
86   - thingsboardPlugin,
87   - thingsboardRule,
88 84 thingsboardRuleChain,
89 85 thingsboardJsonForm,
90 86 thingsboardApiDevice,
... ...
1   -<!--
2   -
3   - Copyright © 2016-2018 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-dialog aria-label="{{ 'plugin.add' | translate }}" tb-help="vm.helpLinks.getPluginLink(vm.item)" help-container-id="help-container">
19   - <form name="theForm" ng-submit="vm.add()">
20   - <md-toolbar>
21   - <div class="md-toolbar-tools">
22   - <h2 translate>plugin.add</h2>
23   - <span flex></span>
24   - <div id="help-container"></div>
25   - <md-button class="md-icon-button" ng-click="vm.cancel()">
26   - <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon>
27   - </md-button>
28   - </div>
29   - </md-toolbar>
30   - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear>
31   - <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
32   - <md-dialog-content>
33   - <div class="md-dialog-content">
34   - <tb-plugin plugin="vm.item" is-edit="true" the-form="theForm"></tb-plugin>
35   - </div>
36   - </md-dialog-content>
37   - <md-dialog-actions layout="row">
38   - <span flex></span>
39   - <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit"
40   - class="md-raised md-primary">
41   - {{ 'action.add' | translate }}
42   - </md-button>
43   - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' |
44   - translate }}
45   - </md-button>
46   - </md-dialog-actions>
47   - </form>
48   -</md-dialog>
1   -/*
2   - * Copyright © 2016-2018 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   -import uiRouter from 'angular-ui-router';
17   -import thingsboardGrid from '../components/grid.directive';
18   -import thingsboardJsonForm from '../components/json-form.directive';
19   -import thingsboardApiPlugin from '../api/plugin.service';
20   -import thingsboardApiComponentDescriptor from '../api/component-descriptor.service';
21   -
22   -import PluginRoutes from './plugin.routes';
23   -import PluginController from './plugin.controller';
24   -import PluginDirective from './plugin.directive';
25   -
26   -export default angular.module('thingsboard.plugin', [
27   - uiRouter,
28   - thingsboardGrid,
29   - thingsboardJsonForm,
30   - thingsboardApiPlugin,
31   - thingsboardApiComponentDescriptor
32   -])
33   - .config(PluginRoutes)
34   - .controller('PluginController', PluginController)
35   - .directive('tbPlugin', PluginDirective)
36   - .name;
1   -<!--
2   -
3   - Copyright © 2016-2018 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   -<div class="tb-uppercase" ng-if="item && parentCtl.types.id.nullUid === item.tenantId.id" translate>plugin.system</div>
19   -<div class="tb-uppercase" translate>{{item && item.state === 'ACTIVE' ? 'plugin.active' : 'plugin.suspended'}}</div>
1   -<!--
2   -
3   - Copyright © 2016-2018 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-button ng-click="onActivatePlugin({event: $event})"
19   - ng-show="!isEdit && !isReadOnly && plugin.state === 'SUSPENDED'"
20   - class="md-raised md-primary">{{ 'plugin.activate' | translate }}</md-button>
21   -<md-button ng-click="onSuspendPlugin({event: $event})"
22   - ng-show="!isEdit && !isReadOnly && plugin.state === 'ACTIVE'"
23   - class="md-raised md-primary">{{ 'plugin.suspend' | translate }}</md-button>
24   -<md-button ng-click="onExportPlugin({event: $event})"
25   - ng-show="!isEdit"
26   - class="md-raised md-primary">{{ 'plugin.export' | translate }}</md-button>
27   -<md-button ng-click="onDeletePlugin({event: $event})"
28   - ng-show="!isEdit && !isReadOnly"
29   - class="md-raised md-primary">{{ 'plugin.delete' | translate }}</md-button>
30   -
31   -<div layout="row">
32   - <md-button ngclipboard data-clipboard-action="copy"
33   - ngclipboard-success="onPluginIdCopied(e)"
34   - data-clipboard-text="{{plugin.id.id}}" ng-show="!isEdit"
35   - class="md-raised">
36   - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
37   - <span translate>plugin.copyId</span>
38   - </md-button>
39   -</div>
40   -
41   -<md-content class="md-padding" layout="column" style="overflow-x: hidden">
42   - <fieldset ng-disabled="$root.loading || !isEdit || isReadOnly">
43   - <md-input-container class="md-block">
44   - <label translate>plugin.name</label>
45   - <input required name="name" ng-model="plugin.name">
46   - <div ng-messages="theForm.name.$error">
47   - <div translate ng-message="required">plugin.name-required</div>
48   - </div>
49   - </md-input-container>
50   - <md-input-container class="md-block">
51   - <label translate>plugin.description</label>
52   - <textarea ng-model="plugin.additionalInfo.description" rows="2"></textarea>
53   - </md-input-container>
54   - <section flex layout="row">
55   - <md-input-container flex class="md-block">
56   - <label translate>plugin.api-token</label>
57   - <input required name="apiToken" ng-model="plugin.apiToken">
58   - <div ng-messages="theForm.apiToken.$error">
59   - <div translate ng-message="required">plugin.api-token-required</div>
60   - </div>
61   - </md-input-container>
62   - <md-input-container flex class="md-block">
63   - <label translate>plugin.type</label>
64   - <md-select required name="pluginType" ng-model="plugin.clazz" ng-disabled="$root.loading || !isEdit">
65   - <md-option ng-repeat="component in pluginComponents" ng-value="component.clazz">
66   - {{component.name}}
67   - </md-option>
68   - </md-select>
69   - <div ng-messages="theForm.pluginType.$error">
70   - <div translate ng-message="required">plugin.type-required</div>
71   - </div>
72   - </md-input-container>
73   - </section>
74   - <md-card flex class="plugin-config" ng-if="showPluginConfig">
75   - <md-card-title>
76   - <md-card-title-text>
77   - <span translate class="md-headline" ng-class="{'tb-readonly-label' : ($root.loading || !isEdit || isReadOnly)}">plugin.configuration</span>
78   - </md-card-title-text>
79   - </md-card-title>
80   - <md-card-content>
81   - <tb-json-form schema="pluginComponent.configurationDescriptor.schema"
82   - form="pluginComponent.configurationDescriptor.form"
83   - model="pluginConfiguration.data"
84   - readonly="$root.loading || !isEdit || isReadOnly"
85   - form-control="theForm">
86   - </tb-json-form>
87   - </md-card-content>
88   - </md-card>
89   - </fieldset>
90   -</md-content>
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import addPluginTemplate from './add-plugin.tpl.html';
19   -import pluginCard from './plugin-card.tpl.html';
20   -
21   -/* eslint-enable import/no-unresolved, import/default */
22   -
23   -/*@ngInject*/
24   -export default function PluginController(pluginService, userService, importExport, $state, $stateParams, $filter, $translate, types, helpLinks) {
25   -
26   - var pluginActionsList = [
27   - {
28   - onAction: function ($event, item) {
29   - exportPlugin($event, item);
30   - },
31   - name: function() { $translate.instant('action.export') },
32   - details: function() { return $translate.instant('plugin.export') },
33   - icon: "file_download"
34   - },
35   - {
36   - onAction: function ($event, item) {
37   - activatePlugin($event, item);
38   - },
39   - name: function() { return $translate.instant('action.activate') },
40   - details: function() { return $translate.instant('plugin.activate') },
41   - icon: "play_arrow",
42   - isEnabled: function(plugin) {
43   - return isPluginEditable(plugin) && plugin && plugin.state === 'SUSPENDED';
44   - }
45   - },
46   - {
47   - onAction: function ($event, item) {
48   - suspendPlugin($event, item);
49   - },
50   - name: function() { return $translate.instant('action.suspend') },
51   - details: function() { return $translate.instant('plugin.suspend') },
52   - icon: "pause",
53   - isEnabled: function(plugin) {
54   - return isPluginEditable(plugin) && plugin && plugin.state === 'ACTIVE';
55   - }
56   - },
57   - {
58   - onAction: function ($event, item) {
59   - vm.grid.deleteItem($event, item);
60   - },
61   - name: function() { return $translate.instant('action.delete') },
62   - details: function() { return $translate.instant('plugin.delete') },
63   - icon: "delete",
64   - isEnabled: isPluginEditable
65   - }
66   - ];
67   -
68   - var pluginAddItemActionsList = [
69   - {
70   - onAction: function ($event) {
71   - vm.grid.addItem($event);
72   - },
73   - name: function() { return $translate.instant('action.create') },
74   - details: function() { return $translate.instant('plugin.create-new-plugin') },
75   - icon: "insert_drive_file"
76   - },
77   - {
78   - onAction: function ($event) {
79   - importExport.importPlugin($event).then(
80   - function() {
81   - vm.grid.refreshList();
82   - }
83   - );
84   - },
85   - name: function() { return $translate.instant('action.import') },
86   - details: function() { return $translate.instant('plugin.import') },
87   - icon: "file_upload"
88   - }
89   - ];
90   -
91   -
92   - var vm = this;
93   -
94   - vm.types = types;
95   -
96   - vm.helpLinkIdForPlugin = helpLinkIdForPlugin;
97   -
98   - vm.pluginGridConfig = {
99   -
100   - refreshParamsFunc: null,
101   -
102   - deleteItemTitleFunc: deletePluginTitle,
103   - deleteItemContentFunc: deletePluginText,
104   - deleteItemsTitleFunc: deletePluginsTitle,
105   - deleteItemsActionTitleFunc: deletePluginsActionTitle,
106   - deleteItemsContentFunc: deletePluginsText,
107   -
108   - fetchItemsFunc: fetchPlugins,
109   - saveItemFunc: savePlugin,
110   - deleteItemFunc: deletePlugin,
111   -
112   - getItemTitleFunc: getPluginTitle,
113   - itemCardTemplateUrl: pluginCard,
114   - parentCtl: vm,
115   -
116   - actionsList: pluginActionsList,
117   - addItemActions: pluginAddItemActionsList,
118   -
119   - onGridInited: gridInited,
120   -
121   - addItemTemplateUrl: addPluginTemplate,
122   -
123   - addItemText: function() { return $translate.instant('plugin.add-plugin-text') },
124   - noItemsText: function() { return $translate.instant('plugin.no-plugins-text') },
125   - itemDetailsText: function() { return $translate.instant('plugin.plugin-details') },
126   - isSelectionEnabled: isPluginEditable,
127   - isDetailsReadOnly: function(plugin) {
128   - return !isPluginEditable(plugin);
129   - }
130   -
131   - };
132   -
133   - if (angular.isDefined($stateParams.items) && $stateParams.items !== null) {
134   - vm.pluginGridConfig.items = $stateParams.items;
135   - }
136   -
137   - if (angular.isDefined($stateParams.topIndex) && $stateParams.topIndex > 0) {
138   - vm.pluginGridConfig.topIndex = $stateParams.topIndex;
139   - }
140   -
141   - vm.isPluginEditable = isPluginEditable;
142   -
143   - vm.activatePlugin = activatePlugin;
144   - vm.suspendPlugin = suspendPlugin;
145   - vm.exportPlugin = exportPlugin;
146   -
147   - function helpLinkIdForPlugin() {
148   - return helpLinks.getPluginLink(vm.grid.operatingItem());
149   - }
150   -
151   - function deletePluginTitle(plugin) {
152   - return $translate.instant('plugin.delete-plugin-title', {pluginName: plugin.name});
153   - }
154   -
155   - function deletePluginText() {
156   - return $translate.instant('plugin.delete-plugin-text');
157   - }
158   -
159   - function deletePluginsTitle(selectedCount) {
160   - return $translate.instant('plugin.delete-plugins-title', {count: selectedCount}, 'messageformat');
161   - }
162   -
163   - function deletePluginsActionTitle(selectedCount) {
164   - return $translate.instant('plugin.delete-plugins-action-title', {count: selectedCount}, 'messageformat');
165   - }
166   -
167   - function deletePluginsText() {
168   - return $translate.instant('plugin.delete-plugins-text');
169   - }
170   -
171   - function gridInited(grid) {
172   - vm.grid = grid;
173   - }
174   -
175   - function fetchPlugins(pageLink) {
176   - return pluginService.getAllPlugins(pageLink);
177   - }
178   -
179   - function savePlugin(plugin) {
180   - return pluginService.savePlugin(plugin);
181   - }
182   -
183   - function deletePlugin(pluginId) {
184   - return pluginService.deletePlugin(pluginId);
185   - }
186   -
187   - function getPluginTitle(plugin) {
188   - return plugin ? plugin.name : '';
189   - }
190   -
191   - function isPluginEditable(plugin) {
192   - if (userService.getAuthority() === 'TENANT_ADMIN') {
193   - return plugin && plugin.tenantId.id != types.id.nullUid;
194   - } else {
195   - return userService.getAuthority() === 'SYS_ADMIN';
196   - }
197   - }
198   -
199   - function exportPlugin($event, plugin) {
200   - $event.stopPropagation();
201   - importExport.exportPlugin(plugin.id.id);
202   - }
203   -
204   - function activatePlugin(event, plugin) {
205   - pluginService.activatePlugin(plugin.id.id).then(function () {
206   - vm.grid.refreshList();
207   - }, function () {
208   - });
209   - }
210   -
211   - function suspendPlugin(event, plugin) {
212   - pluginService.suspendPlugin(plugin.id.id).then(function () {
213   - vm.grid.refreshList();
214   - }, function () {
215   - });
216   - }
217   -
218   -}
1   -/*
2   - * Copyright © 2016-2018 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   -import './plugin.scss';
17   -
18   -/* eslint-disable import/no-unresolved, import/default */
19   -
20   -import pluginFieldsetTemplate from './plugin-fieldset.tpl.html';
21   -
22   -/* eslint-enable import/no-unresolved, import/default */
23   -
24   -/*@ngInject*/
25   -export default function PluginDirective($compile, $templateCache, $translate, types, toast, utils, userService, componentDescriptorService) {
26   - var linker = function (scope, element) {
27   - var template = $templateCache.get(pluginFieldsetTemplate);
28   - element.html(template);
29   -
30   - scope.showPluginConfig = false;
31   -
32   - scope.pluginConfiguration = {
33   - data: null
34   - };
35   -
36   - if (scope.plugin && !scope.plugin.configuration) {
37   - scope.plugin.configuration = {};
38   - }
39   -
40   - scope.$watch("plugin.clazz", function (newValue, prevValue) {
41   - if (newValue != prevValue) {
42   - scope.pluginConfiguration.data = null;
43   - if (scope.plugin) {
44   - componentDescriptorService.getComponentDescriptorByClazz(scope.plugin.clazz).then(
45   - function success(component) {
46   - scope.pluginComponent = component;
47   - scope.showPluginConfig = !(userService.getAuthority() === 'TENANT_ADMIN'
48   - && scope.plugin.tenantId
49   - && scope.plugin.tenantId.id === types.id.nullUid)
50   - && utils.isDescriptorSchemaNotEmpty(scope.pluginComponent.configurationDescriptor);
51   - scope.pluginConfiguration.data = angular.copy(scope.plugin.configuration);
52   - },
53   - function fail() {
54   - }
55   - );
56   - }
57   - }
58   - });
59   -
60   - scope.$watch("pluginConfiguration.data", function (newValue, prevValue) {
61   - if (newValue && !angular.equals(newValue, prevValue)) {
62   - scope.plugin.configuration = angular.copy(scope.pluginConfiguration.data);
63   - }
64   - }, true);
65   -
66   - scope.onPluginIdCopied = function() {
67   - toast.showSuccess($translate.instant('plugin.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left');
68   - };
69   -
70   - componentDescriptorService.getComponentDescriptorsByType(types.componentType.plugin).then(
71   - function success(components) {
72   - scope.pluginComponents = components;
73   - },
74   - function fail() {
75   - }
76   - );
77   -
78   - $compile(element.contents())(scope);
79   - }
80   - return {
81   - restrict: "E",
82   - link: linker,
83   - scope: {
84   - plugin: '=',
85   - isEdit: '=',
86   - isReadOnly: '=',
87   - theForm: '=',
88   - onActivatePlugin: '&',
89   - onSuspendPlugin: '&',
90   - onExportPlugin: '&',
91   - onDeletePlugin: '&'
92   - }
93   - };
94   -}
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import pluginsTemplate from './plugins.tpl.html';
19   -
20   -/* eslint-enable import/no-unresolved, import/default */
21   -
22   -/*@ngInject*/
23   -export default function PluginRoutes($stateProvider) {
24   -
25   - $stateProvider
26   - .state('home.plugins', {
27   - url: '/plugins',
28   - params: {'topIndex': 0},
29   - module: 'private',
30   - auth: ['SYS_ADMIN', 'TENANT_ADMIN'],
31   - views: {
32   - "content@home": {
33   - templateUrl: pluginsTemplate,
34   - controllerAs: 'vm',
35   - controller: 'PluginController'
36   - }
37   - },
38   - data: {
39   - searchEnabled: true,
40   - pageTitle: 'plugin.plugins'
41   - },
42   - ncyBreadcrumb: {
43   - label: '{"icon": "extension", "label": "plugin.plugins"}'
44   - }
45   - });
46   -}
1   -/**
2   - * Copyright © 2016-2018 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   -.plugin-config {
17   - min-width: 500px;
18   -}
\ No newline at end of file
1   -<!--
2   -
3   - Copyright © 2016-2018 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   -<tb-grid grid-configuration="vm.pluginGridConfig">
19   - <details-buttons tb-help="vm.helpLinkIdForPlugin()" help-container-id="help-container">
20   - <div id="help-container"></div>
21   - </details-buttons>
22   - <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isPluginEditable(vm.grid.operatingItem()))}"
23   - id="tabs" md-border-bottom flex class="tb-absolute-fill">
24   - <md-tab label="{{ 'plugin.details' | translate }}">
25   - <tb-plugin plugin="vm.grid.operatingItem()"
26   - is-edit="vm.grid.detailsConfig.isDetailsEditMode"
27   - is-read-only="vm.grid.isDetailsReadOnly(vm.grid.operatingItem())"
28   - the-form="vm.grid.detailsForm"
29   - on-activate-plugin="vm.activatePlugin(event, vm.grid.detailsConfig.currentItem)"
30   - on-suspend-plugin="vm.suspendPlugin(event, vm.grid.detailsConfig.currentItem)"
31   - on-export-plugin="vm.exportPlugin(event, vm.grid.detailsConfig.currentItem)"
32   - on-delete-plugin="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-plugin>
33   - </md-tab>
34   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35   - <tb-attribute-table flex
36   - entity-id="vm.grid.operatingItem().id.id"
37   - entity-type="{{vm.types.entityType.plugin}}"
38   - entity-name="vm.grid.operatingItem().name"
39   - default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40   - </tb-attribute-table>
41   - </md-tab>
42   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43   - <tb-attribute-table flex
44   - entity-id="vm.grid.operatingItem().id.id"
45   - entity-type="{{vm.types.entityType.plugin}}"
46   - entity-name="vm.grid.operatingItem().name"
47   - default-attribute-scope="{{vm.types.latestTelemetry.value}}"
48   - disable-attribute-scope-selection="true">
49   - </tb-attribute-table>
50   - </md-tab>
51   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52   - <tb-alarm-table flex entity-type="vm.types.entityType.plugin"
53   - entity-id="vm.grid.operatingItem().id.id">
54   - </tb-alarm-table>
55   - </md-tab>
56   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'plugin.events' | translate }}">
57   - <tb-event-table flex entity-type="vm.types.entityType.plugin"
58   - entity-id="vm.grid.operatingItem().id.id"
59   - tenant-id="vm.grid.operatingItem().tenantId.id"
60   - default-event-type="{{vm.types.eventType.lcEvent.value}}">
61   - </tb-event-table>
62   - </md-tab>
63   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64   - <tb-relation-table flex
65   - entity-id="vm.grid.operatingItem().id.id"
66   - entity-type="{{vm.types.entityType.plugin}}">
67   - </tb-relation-table>
68   - </md-tab>
69   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem()) && vm.grid.isTenantAdmin()"
70   - md-on-select="vm.grid.triggerResize()" label="{{ 'audit-log.audit-logs' | translate }}">
71   - <tb-audit-log-table flex entity-type="vm.types.entityType.plugin"
72   - entity-id="vm.grid.operatingItem().id.id"
73   - audit-log-mode="{{vm.types.auditLogMode.entity}}">
74   - </tb-audit-log-table>
75   - </md-tab>
76   - </md-tabs>
77   -</tb-grid>
1   -<!--
2   -
3   - Copyright © 2016-2018 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-dialog aria-label="{{ 'rule.add' | translate }}" tb-help="'rules'" help-container-id="help-container">
19   - <form name="theForm" ng-submit="vm.add()">
20   - <md-toolbar>
21   - <div class="md-toolbar-tools">
22   - <h2 translate>rule.add</h2>
23   - <span flex></span>
24   - <div id="help-container"></div>
25   - <md-button class="md-icon-button" ng-click="vm.cancel()">
26   - <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon>
27   - </md-button>
28   - </div>
29   - </md-toolbar>
30   - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear>
31   - <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
32   - <md-dialog-content>
33   - <div class="md-dialog-content">
34   - <tb-rule rule="vm.item" is-edit="true" the-form="theForm"></tb-rule>
35   - </div>
36   - </md-dialog-content>
37   - <md-dialog-actions layout="row">
38   - <span flex></span>
39   - <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit"
40   - class="md-raised md-primary">
41   - {{ 'action.add' | translate }}
42   - </md-button>
43   - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' |
44   - translate }}
45   - </md-button>
46   - </md-dialog-actions>
47   - </form>
48   -</md-dialog>
1   -/*
2   - * Copyright © 2016-2018 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   -import uiRouter from 'angular-ui-router';
17   -import thingsboardGrid from '../components/grid.directive';
18   -import thingsboardPluginSelect from '../components/plugin-select.directive';
19   -import thingsboardComponent from '../component';
20   -import thingsboardApiRule from '../api/rule.service';
21   -import thingsboardApiPlugin from '../api/plugin.service';
22   -import thingsboardApiComponentDescriptor from '../api/component-descriptor.service';
23   -
24   -import RuleRoutes from './rule.routes';
25   -import RuleController from './rule.controller';
26   -import RuleDirective from './rule.directive';
27   -
28   -export default angular.module('thingsboard.rule', [
29   - uiRouter,
30   - thingsboardGrid,
31   - thingsboardPluginSelect,
32   - thingsboardComponent,
33   - thingsboardApiRule,
34   - thingsboardApiPlugin,
35   - thingsboardApiComponentDescriptor
36   -])
37   - .config(RuleRoutes)
38   - .controller('RuleController', RuleController)
39   - .directive('tbRule', RuleDirective)
40   - .name;
1   -<!--
2   -
3   - Copyright © 2016-2018 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   -<div class="tb-uppercase" ng-if="item && parentCtl.types.id.nullUid === item.tenantId.id" translate>rule.system</div>
19   -<div class="tb-uppercase" translate>{{item && item.state === 'ACTIVE' ? 'rule.active' : 'rule.suspended'}}</div>
1   -<!--
2   -
3   - Copyright © 2016-2018 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-button ng-click="onActivateRule({event: $event})"
19   - ng-show="!isEdit && !isReadOnly && rule.state === 'SUSPENDED'"
20   - class="md-raised md-primary">{{ 'rule.activate' | translate }}</md-button>
21   -<md-button ng-click="onSuspendRule({event: $event})"
22   - ng-show="!isEdit && !isReadOnly && rule.state === 'ACTIVE'"
23   - class="md-raised md-primary">{{ 'rule.suspend' | translate }}</md-button>
24   -<md-button ng-click="onExportRule({event: $event})"
25   - ng-show="!isEdit"
26   - class="md-raised md-primary">{{ 'rule.export' | translate }}</md-button>
27   -<md-button ng-click="onDeleteRule({event: $event})"
28   - ng-show="!isEdit && !isReadOnly"
29   - class="md-raised md-primary">{{ 'rule.delete' | translate }}</md-button>
30   -
31   -<div layout="row">
32   - <md-button ngclipboard data-clipboard-action="copy"
33   - ngclipboard-success="onRuleIdCopied(e)"
34   - data-clipboard-text="{{rule.id.id}}" ng-show="!isEdit"
35   - class="md-raised">
36   - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon>
37   - <span translate>rule.copyId</span>
38   - </md-button>
39   -</div>
40   -
41   -<md-content class="md-padding tb-rule" layout="column">
42   - <fieldset ng-disabled="$root.loading || !isEdit || isReadOnly">
43   - <md-input-container class="md-block">
44   - <label translate>rule.name</label>
45   - <input required name="name" ng-model="rule.name">
46   - <div ng-messages="theForm.name.$error">
47   - <div translate ng-message="required">rule.name-required</div>
48   - </div>
49   - </md-input-container>
50   - <md-input-container class="md-block">
51   - <label translate>rule.description</label>
52   - <textarea ng-model="rule.additionalInfo.description" rows="2"></textarea>
53   - </md-input-container>
54   - </fieldset>
55   - <v-accordion id="filters-accordion" class="vAccordion--default"
56   - ng-class="{'tb-readonly-label' : (!isEdit || isReadOnly)}">
57   - <v-pane id="filters-pane" expanded="true">
58   - <v-pane-header>
59   - {{ 'rule.filters' | translate }}
60   - </v-pane-header>
61   - <v-pane-content>
62   - <div ng-if="rule.filters.length === 0">
63   - <span translate layout-align="center center"
64   - class="tb-prompt">rule.add-filter-prompt</span>
65   - </div>
66   - <div ng-if="rule.filters.length > 0">
67   - <div flex layout="row" layout-align="start center">
68   - <span ng-if="isEdit && !isReadOnly" style="min-width: 40px; margin: 0 6px;"></br></span>
69   - <span flex="5"></span>
70   - <div flex layout="row" layout-align="start center"
71   - style="padding: 0 0 0 10px; margin: 5px;">
72   - <span translate flex="50">rule.filter-name</span>
73   - <span translate flex="50">rule.filter-type</span>
74   - <span style="min-width: 80px; margin: 0 12px;"></br></span>
75   - </div>
76   - </div>
77   - <div class="tb-filters" style="max-height: 300px; overflow: auto; padding-bottom: 15px;">
78   - <ul dnd-list="filters" dnd-disable-if="!isEdit || isReadOnly">
79   - <li ng-repeat="filter in filters"
80   - dnd-draggable="filter"
81   - dnd-moved="filters.splice($index, 1)"
82   - dnd-disable-if="!isEdit || isReadOnly"
83   - dnd-effect-allowed="move">
84   - <div flex layout="row" layout-align="start center">
85   - <md-button ng-if="isEdit && !isReadOnly" dnd-handle class="md-icon-button md-primary handle"
86   - style="min-width: 40px;"
87   - aria-label="{{ 'action.drag' | translate }}">
88   - <md-tooltip md-direction="top">
89   - {{ 'action.drag' | translate }}
90   - </md-tooltip>
91   - <md-icon aria-label="{{ 'action.drag' | translate }}"
92   - class="material-icons">
93   - drag_handle
94   - </md-icon>
95   - </md-button>
96   - <dnd-nodrag flex layout="row" layout-align="start center">
97   - <span flex="5">{{$index + 1}}.</span>
98   - <tb-component flex
99   - component="filter.value"
100   - type="types.componentType.filter"
101   - title="rule.filter"
102   - read-only="!isEdit || isReadOnly"
103   - on-remove-component="removeFilter(event, filter)">
104   - </tb-component>
105   - </dnd-nodrag>
106   - </div>
107   - </li>
108   - </ul>
109   - </div>
110   - </div>
111   - <div ng-if="isEdit && !isReadOnly" flex layout="row" layout-align="start center">
112   - <md-button ng-disabled="$root.loading" class="md-primary md-raised"
113   - ng-click="addFilter($event)" aria-label="{{ 'action.add' | translate }}">
114   - <md-tooltip md-direction="top">
115   - {{ 'rule.add-filter' | translate }}
116   - </md-tooltip>
117   - <md-icon class="material-icons">add</md-icon>
118   - <span translate>action.add</span>
119   - </md-button>
120   - </div>
121   - </v-pane-content>
122   - </v-pane>
123   - </v-accordion>
124   - <v-accordion id="processor-accordion" class="vAccordion--default"
125   - ng-class="{'tb-readonly-label' : (!isEdit || isReadOnly)}">
126   - <v-pane id="processor-pane" expanded="true">
127   - <v-pane-header>
128   - {{ 'rule.processor' | translate }}
129   - </v-pane-header>
130   - <v-pane-content>
131   - <div ng-if="rule.processor && rule.processor != null">
132   - <div flex layout="row" layout-align="start center"
133   - style="padding: 0 0 0 10px; margin: 5px;">
134   - <span translate flex="50">rule.processor-name</span>
135   - <span translate flex="50">rule.processor-type</span>
136   - <span style="min-width: 80px; margin: 0 12px;"></br></span>
137   - </div>
138   - <div flex layout="row" layout-align="start center" style="padding-bottom: 15px;">
139   - <tb-component flex
140   - component="rule.processor"
141   - type="types.componentType.processor"
142   - title="rule.processor"
143   - read-only="!isEdit || isReadOnly"
144   - on-remove-component="removeProcessor(event)">
145   - </tb-component>
146   - </div>
147   - </div>
148   - <div ng-if="!rule.processor || rule.processor == null">
149   - <span ng-if="!isEdit || isReadOnly" translate layout-align="center center"
150   - class="tb-prompt">rule.no-processor-configured</span>
151   - <div ng-if="isEdit && !isReadOnly" flex layout="row" layout-align="start center">
152   - <md-button ng-disabled="$root.loading" class="md-primary md-raised"
153   - ng-click="addProcessor($event)" aria-label="{{ 'action.create' | translate }}">
154   - <md-tooltip md-direction="top">
155   - {{ 'rule.create-processor' | translate }}
156   - </md-tooltip>
157   - <md-icon class="material-icons">add</md-icon>
158   - <span translate>action.create</span>
159   - </md-button>
160   - </div>
161   - </div>
162   - </v-pane-content>
163   - </v-pane>
164   - </v-accordion>
165   - <fieldset ng-disabled="$root.loading || !isEdit || isReadOnly">
166   - <md-input-container ng-if="!isEdit || isReadOnly" flex class="md-block">
167   - <label translate>plugin.plugin</label>
168   - <input name="name" ng-model="plugin.name">
169   - </md-input-container>
170   - <tb-plugin-select ng-show="isEdit && !isReadOnly" flex
171   - ng-model="plugin"
172   - tb-required="false"
173   - the-form="theForm"
174   - plugins-scope="action">
175   - </tb-plugin-select>
176   - </fieldset>
177   - <v-accordion ng-if="plugin != null" id="plugin-action-accordion" class="vAccordion--default"
178   - ng-class="{'tb-readonly-label' : (!isEdit || isReadOnly)}">
179   - <v-pane id="plugin-action-pane" expanded="true">
180   - <v-pane-header>
181   - {{ 'rule.plugin-action' | translate }}
182   - </v-pane-header>
183   - <v-pane-content>
184   - <div ng-if="rule.action && rule.action != null">
185   - <div flex layout="row" layout-align="start center"
186   - style="padding: 0 0 0 10px; margin: 5px;">
187   - <span translate flex="50">rule.action-name</span>
188   - <span translate flex="50">rule.action-type</span>
189   - <span style="min-width: 80px; margin: 0 12px;"></br></span>
190   - </div>
191   - <div flex layout="row" layout-align="start center" style="padding-bottom: 15px;">
192   - <tb-component flex
193   - component="rule.action"
194   - type="types.componentType.action"
195   - plugin-clazz="plugin.clazz"
196   - title="rule.plugin-action"
197   - read-only="!isEdit || isReadOnly"
198   - on-remove-component="removeAction(event)">
199   - </tb-component>
200   - </div>
201   - </div>
202   - <div ng-if="!rule.action || rule.action == null">
203   - <span translate layout-align="center center"
204   - class="tb-prompt">rule.create-action-prompt</span>
205   - <div ng-if="isEdit && !isReadOnly" flex layout="row" layout-align="start center">
206   - <md-button ng-disabled="$root.loading" class="md-primary md-raised"
207   - ng-click="addAction($event)" aria-label="{{ 'action.create' | translate }}">
208   - <md-tooltip md-direction="top">
209   - {{ 'rule.create-action' | translate }}
210   - </md-tooltip>
211   - <md-icon class="material-icons">add</md-icon>
212   - <span translate>action.create</span>
213   - </md-button>
214   - </div>
215   - </div>
216   - </v-pane-content>
217   - </v-pane>
218   - </v-accordion>
219   -</md-content>
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import addRuleTemplate from './add-rule.tpl.html';
19   -import ruleCard from './rule-card.tpl.html';
20   -
21   -/* eslint-enable import/no-unresolved, import/default */
22   -
23   -/*@ngInject*/
24   -export default function RuleController(ruleService, userService, importExport, $state, $stateParams, $filter, $translate, types) {
25   -
26   - var ruleActionsList = [
27   - {
28   - onAction: function ($event, item) {
29   - exportRule($event, item);
30   - },
31   - name: function() { $translate.instant('action.export') },
32   - details: function() { return $translate.instant('rule.export') },
33   - icon: "file_download"
34   - },
35   - {
36   - onAction: function ($event, item) {
37   - activateRule($event, item);
38   - },
39   - name: function() { return $translate.instant('action.activate') },
40   - details: function() { return $translate.instant('rule.activate') },
41   - icon: "play_arrow",
42   - isEnabled: function(rule) {
43   - return isRuleEditable(rule) && rule && rule.state === 'SUSPENDED';
44   - }
45   - },
46   - {
47   - onAction: function ($event, item) {
48   - suspendRule($event, item);
49   - },
50   - name: function() { return $translate.instant('action.suspend') },
51   - details: function() { return $translate.instant('rule.suspend') },
52   - icon: "pause",
53   - isEnabled: function(rule) {
54   - return isRuleEditable(rule) && rule.state === 'ACTIVE';
55   - }
56   - },
57   - {
58   - onAction: function ($event, item) {
59   - vm.grid.deleteItem($event, item);
60   - },
61   - name: function() { return $translate.instant('action.delete') },
62   - details: function() { return $translate.instant('rule.delete') },
63   - icon: "delete",
64   - isEnabled: isRuleEditable
65   - }
66   - ];
67   -
68   - var ruleAddItemActionsList = [
69   - {
70   - onAction: function ($event) {
71   - vm.grid.addItem($event);
72   - },
73   - name: function() { return $translate.instant('action.create') },
74   - details: function() { return $translate.instant('rule.create-new-rule') },
75   - icon: "insert_drive_file"
76   - },
77   - {
78   - onAction: function ($event) {
79   - importExport.importRule($event).then(
80   - function() {
81   - vm.grid.refreshList();
82   - }
83   - );
84   - },
85   - name: function() { return $translate.instant('action.import') },
86   - details: function() { return $translate.instant('rule.import') },
87   - icon: "file_upload"
88   - }
89   - ];
90   -
91   - var vm = this;
92   -
93   - vm.types = types;
94   -
95   - vm.ruleGridConfig = {
96   -
97   - refreshParamsFunc: null,
98   -
99   - deleteItemTitleFunc: deleteRuleTitle,
100   - deleteItemContentFunc: deleteRuleText,
101   - deleteItemsTitleFunc: deleteRulesTitle,
102   - deleteItemsActionTitleFunc: deleteRulesActionTitle,
103   - deleteItemsContentFunc: deleteRulesText,
104   -
105   - fetchItemsFunc: fetchRules,
106   - saveItemFunc: saveRule,
107   - deleteItemFunc: deleteRule,
108   -
109   - getItemTitleFunc: getRuleTitle,
110   - itemCardTemplateUrl: ruleCard,
111   - parentCtl: vm,
112   -
113   - actionsList: ruleActionsList,
114   - addItemActions: ruleAddItemActionsList,
115   -
116   - onGridInited: gridInited,
117   -
118   - addItemTemplateUrl: addRuleTemplate,
119   -
120   - addItemText: function() { return $translate.instant('rule.add-rule-text') },
121   - noItemsText: function() { return $translate.instant('rule.no-rules-text') },
122   - itemDetailsText: function() { return $translate.instant('rule.rule-details') },
123   - isSelectionEnabled: isRuleEditable,
124   - isDetailsReadOnly: function(rule) {
125   - return !isRuleEditable(rule);
126   - }
127   - };
128   -
129   - if (angular.isDefined($stateParams.items) && $stateParams.items !== null) {
130   - vm.ruleGridConfig.items = $stateParams.items;
131   - }
132   -
133   - if (angular.isDefined($stateParams.topIndex) && $stateParams.topIndex > 0) {
134   - vm.ruleGridConfig.topIndex = $stateParams.topIndex;
135   - }
136   -
137   - vm.isRuleEditable = isRuleEditable;
138   -
139   - vm.activateRule = activateRule;
140   - vm.suspendRule = suspendRule;
141   - vm.exportRule = exportRule;
142   -
143   - function deleteRuleTitle(rule) {
144   - return $translate.instant('rule.delete-rule-title', {ruleName: rule.name});
145   - }
146   -
147   - function deleteRuleText() {
148   - return $translate.instant('rule.delete-rule-text');
149   - }
150   -
151   - function deleteRulesTitle(selectedCount) {
152   - return $translate.instant('rule.delete-rules-title', {count: selectedCount}, 'messageformat');
153   - }
154   -
155   - function deleteRulesActionTitle(selectedCount) {
156   - return $translate.instant('rule.delete-rules-action-title', {count: selectedCount}, 'messageformat');
157   - }
158   -
159   - function deleteRulesText() {
160   - return $translate.instant('rule.delete-rules-text');
161   - }
162   -
163   - function gridInited(grid) {
164   - vm.grid = grid;
165   - }
166   -
167   - function fetchRules(pageLink) {
168   - return ruleService.getAllRules(pageLink);
169   - }
170   -
171   - function saveRule(rule) {
172   - return ruleService.saveRule(rule);
173   - }
174   -
175   - function deleteRule(ruleId) {
176   - return ruleService.deleteRule(ruleId);
177   - }
178   -
179   - function getRuleTitle(rule) {
180   - return rule ? rule.name : '';
181   - }
182   -
183   - function isRuleEditable(rule) {
184   - if (userService.getAuthority() === 'TENANT_ADMIN') {
185   - return rule && rule.tenantId.id != types.id.nullUid;
186   - } else {
187   - return userService.getAuthority() === 'SYS_ADMIN';
188   - }
189   - }
190   -
191   - function exportRule($event, rule) {
192   - $event.stopPropagation();
193   - importExport.exportRule(rule.id.id);
194   - }
195   -
196   - function activateRule(event, rule) {
197   - ruleService.activateRule(rule.id.id).then(function () {
198   - vm.grid.refreshList();
199   - }, function () {
200   - });
201   - }
202   -
203   - function suspendRule(event, rule) {
204   - ruleService.suspendRule(rule.id.id).then(function () {
205   - vm.grid.refreshList();
206   - }, function () {
207   - });
208   - }
209   -
210   -}
1   -/*
2   - * Copyright © 2016-2018 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   -import './rule.scss';
17   -
18   -/* eslint-disable import/no-unresolved, import/default */
19   -
20   -import ruleFieldsetTemplate from './rule-fieldset.tpl.html';
21   -
22   -/* eslint-enable import/no-unresolved, import/default */
23   -
24   -/*@ngInject*/
25   -export default function RuleDirective($compile, $templateCache, $mdDialog, $document, $q, $translate, pluginService,
26   - componentDialogService, componentDescriptorService, types, toast) {
27   - var linker = function (scope, element) {
28   - var template = $templateCache.get(ruleFieldsetTemplate);
29   - element.html(template);
30   -
31   - scope.plugin = null;
32   - scope.types = types;
33   - scope.filters = [];
34   -
35   - scope.addFilter = function($event) {
36   - componentDialogService.openComponentDialog($event, true, false,
37   - 'rule.filter', types.componentType.filter).then(
38   - function success(filter) {
39   - scope.filters.push({ value: filter });
40   - },
41   - function fail() {}
42   - );
43   - }
44   -
45   - scope.removeFilter = function ($event, filter) {
46   - var index = scope.filters.indexOf(filter);
47   - if (index > -1) {
48   - scope.filters.splice(index, 1);
49   - }
50   - };
51   -
52   - scope.addProcessor = function($event) {
53   - componentDialogService.openComponentDialog($event, true, false,
54   - 'rule.processor', types.componentType.processor).then(
55   - function success(processor) {
56   - scope.rule.processor = processor;
57   - },
58   - function fail() {}
59   - );
60   - }
61   -
62   - scope.removeProcessor = function() {
63   - if (scope.rule.processor) {
64   - scope.rule.processor = null;
65   - }
66   - }
67   -
68   - scope.addAction = function($event) {
69   - componentDialogService.openComponentDialog($event, true, false,
70   - 'rule.plugin-action', types.componentType.action, scope.plugin.clazz).then(
71   - function success(action) {
72   - scope.rule.action = action;
73   - },
74   - function fail() {}
75   - );
76   - }
77   -
78   - scope.removeAction = function() {
79   - if (scope.rule.action) {
80   - scope.rule.action = null;
81   - }
82   - }
83   -
84   - scope.updateValidity = function () {
85   - if (scope.rule) {
86   - var valid = scope.rule.filters && scope.rule.filters.length > 0;
87   - scope.theForm.$setValidity('filters', valid);
88   - var processorDefined = angular.isDefined(scope.rule.processor) && scope.rule.processor != null;
89   - var pluginDefined = angular.isDefined(scope.rule.pluginToken) && scope.rule.pluginToken != null;
90   - var pluginActionDefined = angular.isDefined(scope.rule.action) && scope.rule.action != null;
91   - valid = processorDefined && !pluginDefined || (pluginDefined && pluginActionDefined);
92   - scope.theForm.$setValidity('processorOrPlugin', valid);
93   - }
94   - };
95   -
96   - scope.onRuleIdCopied = function() {
97   - toast.showSuccess($translate.instant('rule.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left');
98   - };
99   -
100   - scope.$watch('rule', function(newVal, prevVal) {
101   - if (newVal) {
102   - if (!scope.rule.filters) {
103   - scope.rule.filters = [];
104   - }
105   - if (!angular.equals(newVal, prevVal)) {
106   - if (scope.rule.pluginToken) {
107   - pluginService.getPluginByToken(scope.rule.pluginToken).then(
108   - function success(plugin) {
109   - scope.plugin = plugin;
110   - },
111   - function fail() {}
112   - );
113   - } else {
114   - scope.plugin = null;
115   - }
116   - if (scope.filters) {
117   - scope.filters.splice(0, scope.filters.length);
118   - } else {
119   - scope.filters = [];
120   - }
121   - if (scope.rule.filters) {
122   - for (var i in scope.rule.filters) {
123   - scope.filters.push({value: scope.rule.filters[i]});
124   - }
125   - }
126   - }
127   - scope.updateValidity();
128   - }
129   - }
130   - );
131   -
132   - scope.$watch('filters', function (newVal, prevVal) {
133   - if (scope.rule && scope.isEdit && !angular.equals(newVal, prevVal)) {
134   - if (scope.rule.filters) {
135   - scope.rule.filters.splice(0, scope.rule.filters.length);
136   - } else {
137   - scope.rule.filters = [];
138   - }
139   - if (scope.filters) {
140   - for (var i in scope.filters) {
141   - scope.rule.filters.push(scope.filters[i].value);
142   - }
143   - }
144   - scope.theForm.$setDirty();
145   - scope.updateValidity();
146   - }
147   - }, true);
148   -
149   - scope.$watch('plugin', function(newVal, prevVal) {
150   - if (scope.rule && scope.isEdit && !angular.equals(newVal, prevVal)) {
151   - if (newVal) {
152   - scope.rule.pluginToken = scope.plugin.apiToken;
153   - } else {
154   - scope.rule.pluginToken = null;
155   - }
156   - scope.rule.action = null;
157   - scope.updateValidity();
158   - }
159   - }, true);
160   -
161   - scope.$watch('rule.processor', function(newVal, prevVal) {
162   - if (scope.rule && scope.isEdit && !angular.equals(newVal, prevVal)) {
163   - scope.theForm.$setDirty();
164   - scope.updateValidity();
165   - }
166   - }, true);
167   -
168   - scope.$watch('rule.action', function(newVal, prevVal) {
169   - if (scope.rule && scope.isEdit && !angular.equals(newVal, prevVal)) {
170   - scope.theForm.$setDirty();
171   - scope.updateValidity();
172   - }
173   - }, true);
174   -
175   - $compile(element.contents())(scope);
176   - }
177   - return {
178   - restrict: "E",
179   - link: linker,
180   - scope: {
181   - rule: '=',
182   - isEdit: '=',
183   - isReadOnly: '=',
184   - theForm: '=',
185   - onActivateRule: '&',
186   - onSuspendRule: '&',
187   - onExportRule: '&',
188   - onDeleteRule: '&'
189   - }
190   - };
191   -}
1   -/*
2   - * Copyright © 2016-2018 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   -/* eslint-disable import/no-unresolved, import/default */
17   -
18   -import rulesTemplate from './rules.tpl.html';
19   -
20   -/* eslint-enable import/no-unresolved, import/default */
21   -
22   -/*@ngInject*/
23   -export default function RuleRoutes($stateProvider) {
24   -
25   - $stateProvider
26   - .state('home.rules', {
27   - url: '/rules',
28   - params: {'topIndex': 0},
29   - module: 'private',
30   - auth: ['SYS_ADMIN', 'TENANT_ADMIN'],
31   - views: {
32   - "content@home": {
33   - templateUrl: rulesTemplate,
34   - controllerAs: 'vm',
35   - controller: 'RuleController'
36   - }
37   - },
38   - data: {
39   - searchEnabled: true,
40   - pageTitle: 'rule.rules'
41   - },
42   - ncyBreadcrumb: {
43   - label: '{"icon": "settings_ethernet", "label": "rule.rules"}'
44   - }
45   - });
46   -}
1   -/**
2   - * Copyright © 2016-2018 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   -.tb-rule {
17   - min-width: 600px;
18   - tb-plugin-select {
19   - padding: 2px;
20   - margin: 18px 0;
21   - }
22   -}
23   -
24   -.tb-filter {
25   - min-width: 500px;
26   - min-height: 300px;
27   -}
28   -
29   -.tb-filters ul[dnd-list],
30   -.tb-filters ul[dnd-list] > li {
31   - position: relative;
32   -}
33   -
34   -.tb-filters ul[dnd-list] {
35   - min-height: 42px;
36   - padding-left: 0px;
37   -}
38   -
39   -.tb-filters ul[dnd-list] .dndDraggingSource {
40   - display: none;
41   -}
42   -
43   -.tb-filters ul[dnd-list] .dndPlaceholder {
44   - display: block;
45   - background-color: #ddd;
46   - min-height: 42px;
47   -}
48   -
49   -.tb-filters ul[dnd-list] li {
50   - display: block;
51   -}
52   -
53   -.tb-filters .handle {
54   - cursor: move;
55   -}
1   -<!--
2   -
3   - Copyright © 2016-2018 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   -<tb-grid grid-configuration="vm.ruleGridConfig">
19   - <details-buttons tb-help="'rules'" help-container-id="help-container">
20   - <div id="help-container"></div>
21   - </details-buttons>
22   - <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isRuleEditable(vm.grid.operatingItem()))}"
23   - id="tabs" md-border-bottom flex class="tb-absolute-fill">
24   - <md-tab label="{{ 'rule.details' | translate }}">
25   - <tb-rule rule="vm.grid.operatingItem()"
26   - is-edit="vm.grid.detailsConfig.isDetailsEditMode"
27   - is-read-only="vm.grid.isDetailsReadOnly(vm.grid.operatingItem())"
28   - the-form="vm.grid.detailsForm"
29   - on-activate-rule="vm.activateRule(event, vm.grid.detailsConfig.currentItem)"
30   - on-suspend-rule="vm.suspendRule(event, vm.grid.detailsConfig.currentItem)"
31   - on-export-rule="vm.exportRule(event, vm.grid.detailsConfig.currentItem)"
32   - on-delete-rule="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-rule>
33   - </md-tab>
34   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35   - <tb-attribute-table flex
36   - entity-id="vm.grid.operatingItem().id.id"
37   - entity-type="{{vm.types.entityType.rule}}"
38   - entity-name="vm.grid.operatingItem().name"
39   - default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40   - </tb-attribute-table>
41   - </md-tab>
42   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43   - <tb-attribute-table flex
44   - entity-id="vm.grid.operatingItem().id.id"
45   - entity-type="{{vm.types.entityType.rule}}"
46   - entity-name="vm.grid.operatingItem().name"
47   - default-attribute-scope="{{vm.types.latestTelemetry.value}}"
48   - disable-attribute-scope-selection="true">
49   - </tb-attribute-table>
50   - </md-tab>
51   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52   - <tb-alarm-table flex entity-type="vm.types.entityType.rule"
53   - entity-id="vm.grid.operatingItem().id.id">
54   - </tb-alarm-table>
55   - </md-tab>
56   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'rule.events' | translate }}">
57   - <tb-event-table flex entity-type="vm.types.entityType.rule"
58   - entity-id="vm.grid.operatingItem().id.id"
59   - tenant-id="vm.grid.operatingItem().tenantId.id"
60   - default-event-type="{{vm.types.eventType.lcEvent.value}}">
61   - </tb-event-table>
62   - </md-tab>
63   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64   - <tb-relation-table flex
65   - entity-id="vm.grid.operatingItem().id.id"
66   - entity-type="{{vm.types.entityType.rule}}">
67   - </tb-relation-table>
68   - </md-tab>
69   - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem()) && vm.grid.isTenantAdmin()"
70   - md-on-select="vm.grid.triggerResize()" label="{{ 'audit-log.audit-logs' | translate }}">
71   - <tb-audit-log-table flex entity-type="vm.types.entityType.rule"
72   - entity-id="vm.grid.operatingItem().id.id"
73   - audit-log-mode="{{vm.types.auditLogMode.entity}}">
74   - </tb-audit-log-table>
75   - </md-tab>
76   - </md-tabs>
77   -</tb-grid>
... ... @@ -67,24 +67,6 @@ function Menu(userService, $state, $rootScope) {
67 67 icon: 'home'
68 68 },
69 69 {
70   - name: 'plugin.plugins',
71   - type: 'link',
72   - state: 'home.plugins',
73   - icon: 'extension'
74   - },
75   - {
76   - name: 'rule.rules',
77   - type: 'link',
78   - state: 'home.rules',
79   - icon: 'settings_ethernet'
80   - },
81   - {
82   - name: 'rulechain.rulechains',
83   - type: 'link',
84   - state: 'home.ruleChains',
85   - icon: 'settings_ethernet'
86   - },
87   - {
88 70 name: 'tenant.tenants',
89 71 type: 'link',
90 72 state: 'home.tenants',
... ... @@ -119,31 +101,6 @@ function Menu(userService, $state, $rootScope) {
119 101 }];
120 102 homeSections =
121 103 [{
122   - name: 'rule-plugin.management',
123   - places: [
124   - {
125   - name: 'plugin.plugins',
126   - icon: 'extension',
127   - state: 'home.plugins'
128   - },
129   - {
130   - name: 'rule.rules',
131   - icon: 'settings_ethernet',
132   - state: 'home.rules'
133   - }
134   - ]
135   - },
136   - {
137   - name: 'rulechain.management',
138   - places: [
139   - {
140   - name: 'rulechain.rulechains',
141   - icon: 'settings_ethernet',
142   - state: 'home.ruleChains'
143   - }
144   - ]
145   - },
146   - {
147 104 name: 'tenant.management',
148 105 places: [
149 106 {
... ... @@ -187,18 +144,6 @@ function Menu(userService, $state, $rootScope) {
187 144 icon: 'home'
188 145 },
189 146 {
190   - name: 'plugin.plugins',
191   - type: 'link',
192   - state: 'home.plugins',
193   - icon: 'extension'
194   - },
195   - {
196   - name: 'rule.rules',
197   - type: 'link',
198   - state: 'home.rules',
199   - icon: 'settings_ethernet'
200   - },
201   - {
202 147 name: 'rulechain.rulechains',
203 148 type: 'link',
204 149 state: 'home.ruleChains',
... ... @@ -243,21 +188,6 @@ function Menu(userService, $state, $rootScope) {
243 188
244 189 homeSections =
245 190 [{
246   - name: 'rule-plugin.management',
247   - places: [
248   - {
249   - name: 'plugin.plugins',
250   - icon: 'extension',
251   - state: 'home.plugins'
252   - },
253   - {
254   - name: 'rule.rules',
255   - icon: 'settings_ethernet',
256   - state: 'home.rules'
257   - }
258   - ]
259   - },
260   - {
261 191 name: 'rulechain.management',
262 192 places: [
263 193 {
... ...