Commit 0726fbb546720f53ba6a265eb7b8ed9ded5ecffe
Committed by
GitHub
Merge pull request #167 from thingsboard/feature/TB-63
TB-63: Add new 'Alarms' tab in entity details.
Showing
41 changed files
with
937 additions
and
48 deletions
@@ -58,6 +58,19 @@ public class AlarmController extends BaseController { | @@ -58,6 +58,19 @@ public class AlarmController extends BaseController { | ||
58 | } | 58 | } |
59 | 59 | ||
60 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 60 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
61 | + @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) | ||
62 | + @ResponseBody | ||
63 | + public AlarmInfo getAlarmInfoById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { | ||
64 | + checkParameter("alarmId", strAlarmId); | ||
65 | + try { | ||
66 | + AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); | ||
67 | + return checkAlarmInfoId(alarmId); | ||
68 | + } catch (Exception e) { | ||
69 | + throw handleException(e); | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
61 | @RequestMapping(value = "/alarm", method = RequestMethod.POST) | 74 | @RequestMapping(value = "/alarm", method = RequestMethod.POST) |
62 | @ResponseBody | 75 | @ResponseBody |
63 | public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { | 76 | public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { |
@@ -27,6 +27,7 @@ import org.thingsboard.server.actors.service.ActorService; | @@ -27,6 +27,7 @@ import org.thingsboard.server.actors.service.ActorService; | ||
27 | import org.thingsboard.server.common.data.*; | 27 | import org.thingsboard.server.common.data.*; |
28 | import org.thingsboard.server.common.data.alarm.Alarm; | 28 | import org.thingsboard.server.common.data.alarm.Alarm; |
29 | import org.thingsboard.server.common.data.alarm.AlarmId; | 29 | import org.thingsboard.server.common.data.alarm.AlarmId; |
30 | +import org.thingsboard.server.common.data.alarm.AlarmInfo; | ||
30 | import org.thingsboard.server.common.data.asset.Asset; | 31 | import org.thingsboard.server.common.data.asset.Asset; |
31 | import org.thingsboard.server.common.data.id.*; | 32 | import org.thingsboard.server.common.data.id.*; |
32 | import org.thingsboard.server.common.data.page.TextPageLink; | 33 | import org.thingsboard.server.common.data.page.TextPageLink; |
@@ -351,6 +352,17 @@ public abstract class BaseController { | @@ -351,6 +352,17 @@ public abstract class BaseController { | ||
351 | } | 352 | } |
352 | } | 353 | } |
353 | 354 | ||
355 | + AlarmInfo checkAlarmInfoId(AlarmId alarmId) throws ThingsboardException { | ||
356 | + try { | ||
357 | + validateId(alarmId, "Incorrect alarmId " + alarmId); | ||
358 | + AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(alarmId).get(); | ||
359 | + checkAlarm(alarmInfo); | ||
360 | + return alarmInfo; | ||
361 | + } catch (Exception e) { | ||
362 | + throw handleException(e, false); | ||
363 | + } | ||
364 | + } | ||
365 | + | ||
354 | protected void checkAlarm(Alarm alarm) throws ThingsboardException { | 366 | protected void checkAlarm(Alarm alarm) throws ThingsboardException { |
355 | checkNotNull(alarm); | 367 | checkNotNull(alarm); |
356 | checkTenantId(alarm.getTenantId()); | 368 | checkTenantId(alarm.getTenantId()); |
@@ -55,6 +55,7 @@ public class Alarm extends BaseData<AlarmId> implements HasName { | @@ -55,6 +55,7 @@ public class Alarm extends BaseData<AlarmId> implements HasName { | ||
55 | 55 | ||
56 | public Alarm(Alarm alarm) { | 56 | public Alarm(Alarm alarm) { |
57 | super(alarm.getId()); | 57 | super(alarm.getId()); |
58 | + this.createdTime = alarm.getCreatedTime(); | ||
58 | this.tenantId = alarm.getTenantId(); | 59 | this.tenantId = alarm.getTenantId(); |
59 | this.type = alarm.getType(); | 60 | this.type = alarm.getType(); |
60 | this.originator = alarm.getOriginator(); | 61 | this.originator = alarm.getOriginator(); |
@@ -35,6 +35,8 @@ public interface AlarmService { | @@ -35,6 +35,8 @@ public interface AlarmService { | ||
35 | 35 | ||
36 | ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId); | 36 | ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId); |
37 | 37 | ||
38 | + ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(AlarmId alarmId); | ||
39 | + | ||
38 | ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query); | 40 | ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query); |
39 | 41 | ||
40 | } | 42 | } |
@@ -199,6 +199,23 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | @@ -199,6 +199,23 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ | ||
199 | } | 199 | } |
200 | 200 | ||
201 | @Override | 201 | @Override |
202 | + public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(AlarmId alarmId) { | ||
203 | + log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId); | ||
204 | + validateId(alarmId, "Incorrect alarmId " + alarmId); | ||
205 | + return Futures.transform(alarmDao.findAlarmByIdAsync(alarmId.getId()), | ||
206 | + (AsyncFunction<Alarm, AlarmInfo>) alarm1 -> { | ||
207 | + AlarmInfo alarmInfo = new AlarmInfo(alarm1); | ||
208 | + return Futures.transform( | ||
209 | + entityService.fetchEntityNameAsync(alarmInfo.getOriginator()), (Function<String, AlarmInfo>) | ||
210 | + originatorName -> { | ||
211 | + alarmInfo.setOriginatorName(originatorName); | ||
212 | + return alarmInfo; | ||
213 | + } | ||
214 | + ); | ||
215 | + }); | ||
216 | + } | ||
217 | + | ||
218 | + @Override | ||
202 | public ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query) { | 219 | public ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query) { |
203 | ListenableFuture<List<AlarmInfo>> alarms = alarmDao.findAlarms(query); | 220 | ListenableFuture<List<AlarmInfo>> alarms = alarmDao.findAlarms(query); |
204 | if (query.getFetchOriginator() != null && query.getFetchOriginator().booleanValue()) { | 221 | if (query.getFetchOriginator() != null && query.getFetchOriginator().booleanValue()) { |
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import 'brace/ext/language_tools'; | ||
17 | +import 'brace/mode/json'; | ||
18 | +import 'brace/theme/github'; | ||
19 | +import beautify from 'js-beautify'; | ||
20 | + | ||
21 | +import './alarm-details-dialog.scss'; | ||
22 | + | ||
23 | +const js_beautify = beautify.js; | ||
24 | + | ||
25 | +/*@ngInject*/ | ||
26 | +export default function AlarmDetailsDialogController($mdDialog, $filter, $translate, types, alarmService, alarmId, showingCallback) { | ||
27 | + | ||
28 | + var vm = this; | ||
29 | + | ||
30 | + vm.alarmId = alarmId; | ||
31 | + vm.types = types; | ||
32 | + vm.alarm = null; | ||
33 | + | ||
34 | + vm.alarmUpdated = false; | ||
35 | + | ||
36 | + showingCallback.onShowing = function(scope, element) { | ||
37 | + updateEditorSize(element); | ||
38 | + } | ||
39 | + | ||
40 | + vm.alarmDetailsOptions = { | ||
41 | + useWrapMode: false, | ||
42 | + mode: 'json', | ||
43 | + showGutter: false, | ||
44 | + showPrintMargin: false, | ||
45 | + theme: 'github', | ||
46 | + advanced: { | ||
47 | + enableSnippets: false, | ||
48 | + enableBasicAutocompletion: false, | ||
49 | + enableLiveAutocompletion: false | ||
50 | + }, | ||
51 | + onLoad: function (_ace) { | ||
52 | + vm.editor = _ace; | ||
53 | + } | ||
54 | + }; | ||
55 | + | ||
56 | + vm.close = close; | ||
57 | + vm.acknowledge = acknowledge; | ||
58 | + vm.clear = clear; | ||
59 | + | ||
60 | + loadAlarm(); | ||
61 | + | ||
62 | + function updateEditorSize(element) { | ||
63 | + var newWidth = 600; | ||
64 | + var newHeight = 200; | ||
65 | + angular.element('#tb-alarm-details', element).height(newHeight.toString() + "px") | ||
66 | + .width(newWidth.toString() + "px"); | ||
67 | + vm.editor.resize(); | ||
68 | + } | ||
69 | + | ||
70 | + function loadAlarm() { | ||
71 | + alarmService.getAlarmInfo(vm.alarmId).then( | ||
72 | + function success(alarm) { | ||
73 | + vm.alarm = alarm; | ||
74 | + loadAlarmFields(); | ||
75 | + }, | ||
76 | + function fail() { | ||
77 | + vm.alarm = null; | ||
78 | + } | ||
79 | + ); | ||
80 | + } | ||
81 | + | ||
82 | + function loadAlarmFields() { | ||
83 | + vm.createdTime = $filter('date')(vm.alarm.createdTime, 'yyyy-MM-dd HH:mm:ss'); | ||
84 | + vm.startTime = null; | ||
85 | + if (vm.alarm.startTs) { | ||
86 | + vm.startTime = $filter('date')(vm.alarm.startTs, 'yyyy-MM-dd HH:mm:ss'); | ||
87 | + } | ||
88 | + vm.endTime = null; | ||
89 | + if (vm.alarm.endTs) { | ||
90 | + vm.endTime = $filter('date')(vm.alarm.endTs, 'yyyy-MM-dd HH:mm:ss'); | ||
91 | + } | ||
92 | + vm.ackTime = null; | ||
93 | + if (vm.alarm.ackTs) { | ||
94 | + vm.ackTime = $filter('date')(vm.alarm.ackTs, 'yyyy-MM-dd HH:mm:ss') | ||
95 | + } | ||
96 | + vm.clearTime = null; | ||
97 | + if (vm.alarm.clearTs) { | ||
98 | + vm.clearTime = $filter('date')(vm.alarm.clearTs, 'yyyy-MM-dd HH:mm:ss'); | ||
99 | + } | ||
100 | + | ||
101 | + vm.alarmSeverity = $translate.instant(types.alarmSeverity[vm.alarm.severity].name); | ||
102 | + | ||
103 | + vm.alarmStatus = $translate.instant('alarm.display-status.' + vm.alarm.status); | ||
104 | + | ||
105 | + vm.alarmDetails = null; | ||
106 | + if (vm.alarm.details) { | ||
107 | + vm.alarmDetails = angular.toJson(vm.alarm.details); | ||
108 | + vm.alarmDetails = js_beautify(vm.alarmDetails, {indent_size: 4}); | ||
109 | + } | ||
110 | + } | ||
111 | + | ||
112 | + function acknowledge () { | ||
113 | + alarmService.ackAlarm(vm.alarmId).then( | ||
114 | + function success() { | ||
115 | + vm.alarmUpdated = true; | ||
116 | + loadAlarm(); | ||
117 | + } | ||
118 | + ); | ||
119 | + } | ||
120 | + | ||
121 | + function clear () { | ||
122 | + alarmService.clearAlarm(vm.alarmId).then( | ||
123 | + function success() { | ||
124 | + vm.alarmUpdated = true; | ||
125 | + loadAlarm(); | ||
126 | + } | ||
127 | + ); | ||
128 | + } | ||
129 | + | ||
130 | + function close () { | ||
131 | + $mdDialog.hide(vm.alarmUpdated ? vm.alarm : null); | ||
132 | + } | ||
133 | + | ||
134 | +} |
ui/src/app/alarm/alarm-details-dialog.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +.tb-alarm-details-panel { | ||
18 | + margin-left: 15px; | ||
19 | + border: 1px solid #C0C0C0; | ||
20 | + height: 100%; | ||
21 | + #tb-alarm-details { | ||
22 | + min-width: 600px; | ||
23 | + min-height: 200px; | ||
24 | + width: 100%; | ||
25 | + height: 100%; | ||
26 | + } | ||
27 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<md-dialog aria-label="{{ 'alarm.alarm-details' | translate }}"> | ||
19 | + <md-toolbar> | ||
20 | + <div class="md-toolbar-tools"> | ||
21 | + <h2 translate>alarm.alarm-details</h2> | ||
22 | + <span flex></span> | ||
23 | + <md-button class="md-icon-button" ng-click="vm.close()"> | ||
24 | + <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> | ||
25 | + </md-button> | ||
26 | + </div> | ||
27 | + </md-toolbar> | ||
28 | + <md-dialog-content> | ||
29 | + <div class="md-dialog-content" layout="column"> | ||
30 | + <div layout="row"> | ||
31 | + <md-input-container class="md-block"> | ||
32 | + <label translate>alarm.created-time</label> | ||
33 | + <input ng-model="vm.createdTime" readonly> | ||
34 | + </md-input-container> | ||
35 | + <md-input-container flex class="md-block"> | ||
36 | + <label translate>alarm.originator</label> | ||
37 | + <input ng-model="vm.alarm.originatorName" readonly> | ||
38 | + </md-input-container> | ||
39 | + </div> | ||
40 | + <div layout="row" ng-if="vm.startTime || vm.endTime"> | ||
41 | + <md-input-container ng-if="vm.startTime" flex class="md-block"> | ||
42 | + <label translate>alarm.start-time</label> | ||
43 | + <input ng-model="vm.startTime" readonly> | ||
44 | + </md-input-container> | ||
45 | + <md-input-container ng-if="vm.endTime" flex class="md-block"> | ||
46 | + <label translate>alarm.end-time</label> | ||
47 | + <input ng-model="vm.endTime" readonly> | ||
48 | + </md-input-container> | ||
49 | + <span flex ng-if="!vm.startTime || !vm.endTime"></span> | ||
50 | + </div> | ||
51 | + <div layout="row" ng-if="vm.ackTime || vm.clearTime"> | ||
52 | + <md-input-container ng-if="vm.ackTime" flex class="md-block"> | ||
53 | + <label translate>alarm.ack-time</label> | ||
54 | + <input ng-model="vm.ackTime" readonly> | ||
55 | + </md-input-container> | ||
56 | + <md-input-container ng-if="vm.clearTime" flex class="md-block"> | ||
57 | + <label translate>alarm.clear-time</label> | ||
58 | + <input ng-model="vm.clearTime" readonly> | ||
59 | + </md-input-container> | ||
60 | + <span flex ng-if="!vm.ackTime || !vm.clearTime"></span> | ||
61 | + </div> | ||
62 | + <div layout="row"> | ||
63 | + <md-input-container flex class="md-block"> | ||
64 | + <label translate>alarm.type</label> | ||
65 | + <input ng-model="vm.alarm.type" readonly> | ||
66 | + </md-input-container> | ||
67 | + <md-input-container flex class="md-block"> | ||
68 | + <label translate>alarm.severity</label> | ||
69 | + <input class="tb-severity" ng-class="vm.types.alarmSeverity[vm.alarm.severity].class" | ||
70 | + ng-model="vm.alarmSeverity" readonly> | ||
71 | + </md-input-container> | ||
72 | + <md-input-container flex class="md-block"> | ||
73 | + <label translate>alarm.status</label> | ||
74 | + <input ng-model="vm.alarmStatus" readonly> | ||
75 | + </md-input-container> | ||
76 | + </div> | ||
77 | + <div class="md-caption" style="padding-left: 3px; padding-bottom: 10px; color: rgba(0,0,0,0.57);" translate>alarm.details</div> | ||
78 | + <div flex class="tb-alarm-details-panel" layout="column"> | ||
79 | + <div flex id="tb-alarm-details" readonly | ||
80 | + ui-ace="vm.alarmDetailsOptions" | ||
81 | + ng-model="vm.alarmDetails"> | ||
82 | + </div> | ||
83 | + </div> | ||
84 | + </div> | ||
85 | + </md-dialog-content> | ||
86 | + <md-dialog-actions layout="row"> | ||
87 | + <md-button ng-if="vm.alarm.status==vm.types.alarmStatus.activeUnack || | ||
88 | + vm.alarm.status==vm.types.alarmStatus.clearedUnack" | ||
89 | + class="md-raised md-primary" | ||
90 | + ng-disabled="loading" | ||
91 | + ng-click="vm.acknowledge()" | ||
92 | + style="margin-right:20px;">{{ 'alarm.acknowledge' | | ||
93 | + translate }} | ||
94 | + </md-button> | ||
95 | + <md-button ng-if="vm.alarm.status==vm.types.alarmStatus.activeAck || | ||
96 | + vm.alarm.status==vm.types.alarmStatus.activeUnack" | ||
97 | + class="md-raised md-primary" | ||
98 | + ng-disabled="loading" | ||
99 | + ng-click="vm.clear()">{{ 'alarm.clear' | | ||
100 | + translate }} | ||
101 | + </md-button> | ||
102 | + <span flex></span> | ||
103 | + <md-button ng-disabled="loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | | ||
104 | + translate }} | ||
105 | + </md-button> | ||
106 | + </md-dialog-actions> | ||
107 | +</md-dialog> |
ui/src/app/alarm/alarm-header.directive.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +/* eslint-disable import/no-unresolved, import/default */ | ||
17 | + | ||
18 | +import alarmHeaderTemplate from './alarm-header.tpl.html'; | ||
19 | + | ||
20 | +/* eslint-enable import/no-unresolved, import/default */ | ||
21 | + | ||
22 | +/*@ngInject*/ | ||
23 | +export default function AlarmHeaderDirective($compile, $templateCache) { | ||
24 | + | ||
25 | + var linker = function (scope, element) { | ||
26 | + | ||
27 | + var template = $templateCache.get(alarmHeaderTemplate); | ||
28 | + element.html(template); | ||
29 | + $compile(element.contents())(scope); | ||
30 | + | ||
31 | + } | ||
32 | + | ||
33 | + return { | ||
34 | + restrict: "A", | ||
35 | + replace: false, | ||
36 | + link: linker, | ||
37 | + scope: false | ||
38 | + }; | ||
39 | +} |
ui/src/app/alarm/alarm-header.tpl.html
renamed from
ui/src/app/event/event-header-alarm.tpl.html
@@ -15,6 +15,9 @@ | @@ -15,6 +15,9 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<div translate class="tb-cell" flex="30">event.event-time</div> | ||
19 | -<div translate class="tb-cell" flex="20">event.server</div> | ||
20 | -<div translate class="tb-cell" flex="20">event.alarm</div> | 18 | +<div translate class="tb-cell" flex="30">alarm.created-time</div> |
19 | +<div translate class="tb-cell" flex="15">alarm.originator</div> | ||
20 | +<div translate class="tb-cell" flex="20">alarm.type</div> | ||
21 | +<div translate class="tb-cell" flex="15">alarm.severity</div> | ||
22 | +<div translate class="tb-cell" flex="20">alarm.status</div> | ||
23 | +<div translate class="tb-cell" flex="15">alarm.details</div> |
ui/src/app/alarm/alarm-row.directive.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +/* eslint-disable import/no-unresolved, import/default */ | ||
17 | + | ||
18 | +import alarmDetailsDialogTemplate from './alarm-details-dialog.tpl.html'; | ||
19 | + | ||
20 | +import alarmRowTemplate from './alarm-row.tpl.html'; | ||
21 | + | ||
22 | +/* eslint-enable import/no-unresolved, import/default */ | ||
23 | + | ||
24 | +/*@ngInject*/ | ||
25 | +export default function AlarmRowDirective($compile, $templateCache, types, $mdDialog, $document) { | ||
26 | + | ||
27 | + var linker = function (scope, element, attrs) { | ||
28 | + | ||
29 | + var template = $templateCache.get(alarmRowTemplate); | ||
30 | + element.html(template); | ||
31 | + | ||
32 | + scope.alarm = attrs.alarm; | ||
33 | + scope.types = types; | ||
34 | + | ||
35 | + scope.showAlarmDetails = function($event) { | ||
36 | + var onShowingCallback = { | ||
37 | + onShowing: function(){} | ||
38 | + } | ||
39 | + $mdDialog.show({ | ||
40 | + controller: 'AlarmDetailsDialogController', | ||
41 | + controllerAs: 'vm', | ||
42 | + templateUrl: alarmDetailsDialogTemplate, | ||
43 | + locals: {alarmId: scope.alarm.id.id, showingCallback: onShowingCallback}, | ||
44 | + parent: angular.element($document[0].body), | ||
45 | + targetEvent: $event, | ||
46 | + fullscreen: true, | ||
47 | + skipHide: true, | ||
48 | + onShowing: function(scope, element) { | ||
49 | + onShowingCallback.onShowing(scope, element); | ||
50 | + } | ||
51 | + }).then(function (alarm) { | ||
52 | + if (alarm) { | ||
53 | + scope.alarm = alarm; | ||
54 | + } | ||
55 | + }); | ||
56 | + } | ||
57 | + | ||
58 | + $compile(element.contents())(scope); | ||
59 | + } | ||
60 | + | ||
61 | + return { | ||
62 | + restrict: "A", | ||
63 | + replace: false, | ||
64 | + link: linker, | ||
65 | + scope: false | ||
66 | + }; | ||
67 | +} |
ui/src/app/alarm/alarm-row.tpl.html
renamed from
ui/src/app/event/event-row-alarm.tpl.html
@@ -15,14 +15,19 @@ | @@ -15,14 +15,19 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<div class="tb-cell" flex="30">{{event.createdTime | date : 'yyyy-MM-dd HH:mm:ss'}}</div> | ||
19 | -<div class="tb-cell" flex="20">{{event.body.server}}</div> | ||
20 | -<div class="tb-cell" flex="20"> | ||
21 | - <md-button ng-if="event.body.body" class="md-icon-button md-primary" | ||
22 | - ng-click="showContent($event, event.body.body, 'event.alarm')" | 18 | +<div class="tb-cell" flex="30">{{alarm.createdTime | date : 'yyyy-MM-dd HH:mm:ss'}}</div> |
19 | +<div class="tb-cell" flex="15">{{alarm.originatorName}}</div> | ||
20 | +<div class="tb-cell" flex="20">{{alarm.type}}</div> | ||
21 | +<div class="tb-cell tb-severity" flex="15" ng-class="types.alarmSeverity[alarm.severity].class"> | ||
22 | + {{ alarm ? (types.alarmSeverity[alarm.severity].name | translate) : '' }} | ||
23 | +</div> | ||
24 | +<div class="tb-cell" flex="20">{{ alarm ? (('alarm.display-status.' + alarm.status) | translate) : '' }}</div> | ||
25 | +<div class="tb-cell" flex="15"> | ||
26 | + <md-button class="md-icon-button md-primary" | ||
27 | + ng-click="showAlarmDetails($event)" | ||
23 | aria-label="{{ 'action.view' | translate }}"> | 28 | aria-label="{{ 'action.view' | translate }}"> |
24 | <md-tooltip md-direction="top"> | 29 | <md-tooltip md-direction="top"> |
25 | - {{ 'action.view' | translate }} | 30 | + {{ 'alarm.details' | translate }} |
26 | </md-tooltip> | 31 | </md-tooltip> |
27 | <md-icon aria-label="{{ 'action.view' | translate }}" | 32 | <md-icon aria-label="{{ 'action.view' | translate }}" |
28 | class="material-icons"> | 33 | class="material-icons"> |
ui/src/app/alarm/alarm-table.directive.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import './alarm.scss'; | ||
17 | + | ||
18 | +/* eslint-disable import/no-unresolved, import/default */ | ||
19 | + | ||
20 | +import alarmTableTemplate from './alarm-table.tpl.html'; | ||
21 | + | ||
22 | +/* eslint-enable import/no-unresolved, import/default */ | ||
23 | + | ||
24 | +/*@ngInject*/ | ||
25 | +export default function AlarmTableDirective($compile, $templateCache, $rootScope, types, alarmService) { | ||
26 | + | ||
27 | + var linker = function (scope, element) { | ||
28 | + | ||
29 | + var template = $templateCache.get(alarmTableTemplate); | ||
30 | + | ||
31 | + element.html(template); | ||
32 | + | ||
33 | + scope.types = types; | ||
34 | + | ||
35 | + scope.alarmSearchStatus = types.alarmSearchStatus.any; | ||
36 | + | ||
37 | + var pageSize = 20; | ||
38 | + var startTime = 0; | ||
39 | + var endTime = 0; | ||
40 | + | ||
41 | + scope.timewindow = { | ||
42 | + history: { | ||
43 | + timewindowMs: 24 * 60 * 60 * 1000 // 1 day | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + scope.topIndex = 0; | ||
48 | + | ||
49 | + scope.theAlarms = { | ||
50 | + getItemAtIndex: function (index) { | ||
51 | + if (index > scope.alarms.data.length) { | ||
52 | + scope.theAlarms.fetchMoreItems_(index); | ||
53 | + return null; | ||
54 | + } | ||
55 | + var item = scope.alarms.data[index]; | ||
56 | + if (item) { | ||
57 | + item.indexNumber = index + 1; | ||
58 | + } | ||
59 | + return item; | ||
60 | + }, | ||
61 | + | ||
62 | + getLength: function () { | ||
63 | + if (scope.alarms.hasNext) { | ||
64 | + return scope.alarms.data.length + scope.alarms.nextPageLink.limit; | ||
65 | + } else { | ||
66 | + return scope.alarms.data.length; | ||
67 | + } | ||
68 | + }, | ||
69 | + | ||
70 | + fetchMoreItems_: function () { | ||
71 | + if (scope.alarms.hasNext && !scope.alarms.pending) { | ||
72 | + if (scope.entityType && scope.entityId && scope.alarmSearchStatus) { | ||
73 | + var promise = alarmService.getAlarms(scope.entityType, scope.entityId, | ||
74 | + scope.alarms.nextPageLink, scope.alarmSearchStatus, null, true, false); | ||
75 | + if (promise) { | ||
76 | + scope.alarms.pending = true; | ||
77 | + promise.then( | ||
78 | + function success(alarms) { | ||
79 | + scope.alarms.data = scope.alarms.data.concat(alarms.data); | ||
80 | + scope.alarms.nextPageLink = alarms.nextPageLink; | ||
81 | + scope.alarms.hasNext = alarms.hasNext; | ||
82 | + if (scope.alarms.hasNext) { | ||
83 | + scope.alarms.nextPageLink.limit = pageSize; | ||
84 | + } | ||
85 | + scope.alarms.pending = false; | ||
86 | + }, | ||
87 | + function fail() { | ||
88 | + scope.alarms.hasNext = false; | ||
89 | + scope.alarms.pending = false; | ||
90 | + }); | ||
91 | + } else { | ||
92 | + scope.alarms.hasNext = false; | ||
93 | + } | ||
94 | + } else { | ||
95 | + scope.alarms.hasNext = false; | ||
96 | + } | ||
97 | + } | ||
98 | + } | ||
99 | + }; | ||
100 | + | ||
101 | + scope.$watch("entityId", function(newVal, prevVal) { | ||
102 | + if (newVal && !angular.equals(newVal, prevVal)) { | ||
103 | + resetFilter(); | ||
104 | + reload(); | ||
105 | + } | ||
106 | + }); | ||
107 | + | ||
108 | + | ||
109 | + | ||
110 | + function destroyWatchers() { | ||
111 | + if (scope.alarmSearchStatusWatchHandle) { | ||
112 | + scope.alarmSearchStatusWatchHandle(); | ||
113 | + scope.alarmSearchStatusWatchHandle = null; | ||
114 | + } | ||
115 | + if (scope.timewindowWatchHandle) { | ||
116 | + scope.timewindowWatchHandle(); | ||
117 | + scope.timewindowWatchHandle = null; | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + function initWatchers() { | ||
122 | + scope.alarmSearchStatusWatchHandle = scope.$watch("alarmSearchStatus", function(newVal, prevVal) { | ||
123 | + if (newVal && !angular.equals(newVal, prevVal)) { | ||
124 | + reload(); | ||
125 | + } | ||
126 | + }); | ||
127 | + scope.timewindowWatchHandle = scope.$watch("timewindow", function(newVal, prevVal) { | ||
128 | + if (newVal && !angular.equals(newVal, prevVal)) { | ||
129 | + reload(); | ||
130 | + } | ||
131 | + }, true); | ||
132 | + } | ||
133 | + | ||
134 | + function resetFilter() { | ||
135 | + destroyWatchers(); | ||
136 | + scope.timewindow = { | ||
137 | + history: { | ||
138 | + timewindowMs: 24 * 60 * 60 * 1000 // 1 day | ||
139 | + } | ||
140 | + }; | ||
141 | + scope.alarmSearchStatus = types.alarmSearchStatus.any; | ||
142 | + initWatchers(); | ||
143 | + } | ||
144 | + | ||
145 | + function updateTimeWindowRange () { | ||
146 | + if (scope.timewindow.history.timewindowMs) { | ||
147 | + var currentTime = (new Date).getTime(); | ||
148 | + startTime = currentTime - scope.timewindow.history.timewindowMs; | ||
149 | + endTime = currentTime; | ||
150 | + } else { | ||
151 | + startTime = scope.timewindow.history.fixedTimewindow.startTimeMs; | ||
152 | + endTime = scope.timewindow.history.fixedTimewindow.endTimeMs; | ||
153 | + } | ||
154 | + } | ||
155 | + | ||
156 | + function reload () { | ||
157 | + scope.topIndex = 0; | ||
158 | + scope.selected = []; | ||
159 | + updateTimeWindowRange(); | ||
160 | + scope.alarms = { | ||
161 | + data: [], | ||
162 | + nextPageLink: { | ||
163 | + limit: pageSize, | ||
164 | + startTime: startTime, | ||
165 | + endTime: endTime | ||
166 | + }, | ||
167 | + hasNext: true, | ||
168 | + pending: false | ||
169 | + }; | ||
170 | + scope.theAlarms.getItemAtIndex(pageSize); | ||
171 | + } | ||
172 | + | ||
173 | + scope.noData = function() { | ||
174 | + return scope.alarms.data.length == 0 && !scope.alarms.hasNext; | ||
175 | + } | ||
176 | + | ||
177 | + scope.hasData = function() { | ||
178 | + return scope.alarms.data.length > 0; | ||
179 | + } | ||
180 | + | ||
181 | + scope.loading = function() { | ||
182 | + return $rootScope.loading; | ||
183 | + } | ||
184 | + | ||
185 | + scope.hasScroll = function() { | ||
186 | + var repeatContainer = scope.repeatContainer[0]; | ||
187 | + if (repeatContainer) { | ||
188 | + var scrollElement = repeatContainer.children[0]; | ||
189 | + if (scrollElement) { | ||
190 | + return scrollElement.scrollHeight > scrollElement.clientHeight; | ||
191 | + } | ||
192 | + } | ||
193 | + return false; | ||
194 | + } | ||
195 | + | ||
196 | + reload(); | ||
197 | + | ||
198 | + initWatchers(); | ||
199 | + | ||
200 | + $compile(element.contents())(scope); | ||
201 | + } | ||
202 | + | ||
203 | + return { | ||
204 | + restrict: "E", | ||
205 | + link: linker, | ||
206 | + scope: { | ||
207 | + entityType: '=', | ||
208 | + entityId: '=' | ||
209 | + } | ||
210 | + }; | ||
211 | +} |
ui/src/app/alarm/alarm-table.tpl.html
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<md-content flex class="md-padding tb-absolute-fill" layout="column"> | ||
19 | + <section layout="row"> | ||
20 | + <md-input-container class="md-block" style="width: 200px;"> | ||
21 | + <label translate>alarm.alarm-status</label> | ||
22 | + <md-select ng-model="alarmSearchStatus" ng-disabled="loading()"> | ||
23 | + <md-option ng-repeat="searchStatus in types.alarmSearchStatus" ng-value="searchStatus"> | ||
24 | + {{ ('alarm.search-status.' + searchStatus) | translate }} | ||
25 | + </md-option> | ||
26 | + </md-select> | ||
27 | + </md-input-container> | ||
28 | + <tb-timewindow flex ng-model="timewindow" history-only as-button="true"></tb-timewindow> | ||
29 | + </section> | ||
30 | + <div flex layout="column" class="tb-alarm-container md-whiteframe-z1"> | ||
31 | + <md-list flex layout="column" class="tb-alarm-table"> | ||
32 | + <md-list class="tb-row tb-header" layout="row" tb-alarm-header> | ||
33 | + </md-list> | ||
34 | + <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!loading()" | ||
35 | + ng-show="loading()"></md-progress-linear> | ||
36 | + <md-divider></md-divider> | ||
37 | + <span translate layout-align="center center" | ||
38 | + style="margin-top: 25px;" | ||
39 | + class="tb-prompt" ng-show="noData()">alarm.no-alarms-prompt</span> | ||
40 | + <md-virtual-repeat-container ng-show="hasData()" flex md-top-index="topIndex" tb-scope-element="repeatContainer"> | ||
41 | + <md-list-item md-virtual-repeat="alarm in theAlarms" md-on-demand flex ng-style="hasScroll() ? {'margin-right':'-15px'} : {}"> | ||
42 | + <md-list class="tb-row" flex layout="row" tb-alarm-row alarm="{{alarm}}"> | ||
43 | + </md-list> | ||
44 | + <md-divider flex></md-divider> | ||
45 | + </md-list-item> | ||
46 | + </md-virtual-repeat-container> | ||
47 | + </md-list> | ||
48 | + </div> | ||
49 | +</md-content> |
ui/src/app/alarm/alarm.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +.tb-alarm-container { | ||
18 | + overflow-x: auto; | ||
19 | +} | ||
20 | + | ||
21 | +md-list.tb-alarm-table { | ||
22 | + padding: 0px; | ||
23 | + min-width: 700px; | ||
24 | + | ||
25 | + md-list-item { | ||
26 | + padding: 0px; | ||
27 | + } | ||
28 | + | ||
29 | + .tb-row { | ||
30 | + height: 48px; | ||
31 | + padding: 0px; | ||
32 | + overflow: hidden; | ||
33 | + } | ||
34 | + | ||
35 | + .tb-row:hover { | ||
36 | + background-color: #EEEEEE; | ||
37 | + } | ||
38 | + | ||
39 | + .tb-header:hover { | ||
40 | + background: none; | ||
41 | + } | ||
42 | + | ||
43 | + .tb-header { | ||
44 | + .tb-cell { | ||
45 | + color: rgba(0,0,0,.54); | ||
46 | + font-size: 12px; | ||
47 | + font-weight: 700; | ||
48 | + white-space: nowrap; | ||
49 | + background: none; | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + .tb-cell { | ||
54 | + padding: 0 24px; | ||
55 | + margin: auto 0; | ||
56 | + color: rgba(0,0,0,.87); | ||
57 | + font-size: 13px; | ||
58 | + vertical-align: middle; | ||
59 | + text-align: left; | ||
60 | + overflow: hidden; | ||
61 | + .md-button { | ||
62 | + padding: 0; | ||
63 | + margin: 0; | ||
64 | + } | ||
65 | + } | ||
66 | + | ||
67 | + .tb-cell.tb-number { | ||
68 | + text-align: right; | ||
69 | + } | ||
70 | + | ||
71 | +} | ||
72 | + | ||
73 | +#tb-alarm-content { | ||
74 | + min-width: 400px; | ||
75 | + min-height: 50px; | ||
76 | + width: 100%; | ||
77 | + height: 100%; | ||
78 | +} |
ui/src/app/alarm/index.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +import AlarmDetailsDialogController from './alarm-details-dialog.controller'; | ||
18 | +import AlarmHeaderDirective from './alarm-header.directive'; | ||
19 | +import AlarmRowDirective from './alarm-row.directive'; | ||
20 | +import AlarmTableDirective from './alarm-table.directive'; | ||
21 | + | ||
22 | +export default angular.module('thingsboard.alarm', []) | ||
23 | + .controller('AlarmDetailsDialogController', AlarmDetailsDialogController) | ||
24 | + .directive('tbAlarmHeader', AlarmHeaderDirective) | ||
25 | + .directive('tbAlarmRow', AlarmRowDirective) | ||
26 | + .directive('tbAlarmTable', AlarmTableDirective) | ||
27 | + .name; |
@@ -21,6 +21,7 @@ export default angular.module('thingsboard.api.alarm', []) | @@ -21,6 +21,7 @@ export default angular.module('thingsboard.api.alarm', []) | ||
21 | function AlarmService($http, $q, $interval, $filter) { | 21 | function AlarmService($http, $q, $interval, $filter) { |
22 | var service = { | 22 | var service = { |
23 | getAlarm: getAlarm, | 23 | getAlarm: getAlarm, |
24 | + getAlarmInfo: getAlarmInfo, | ||
24 | saveAlarm: saveAlarm, | 25 | saveAlarm: saveAlarm, |
25 | ackAlarm: ackAlarm, | 26 | ackAlarm: ackAlarm, |
26 | clearAlarm: clearAlarm, | 27 | clearAlarm: clearAlarm, |
@@ -46,6 +47,21 @@ function AlarmService($http, $q, $interval, $filter) { | @@ -46,6 +47,21 @@ function AlarmService($http, $q, $interval, $filter) { | ||
46 | return deferred.promise; | 47 | return deferred.promise; |
47 | } | 48 | } |
48 | 49 | ||
50 | + function getAlarmInfo(alarmId, ignoreErrors, config) { | ||
51 | + var deferred = $q.defer(); | ||
52 | + var url = '/api/alarm/info/' + alarmId; | ||
53 | + if (!config) { | ||
54 | + config = {}; | ||
55 | + } | ||
56 | + config = Object.assign(config, { ignoreErrors: ignoreErrors }); | ||
57 | + $http.get(url, config).then(function success(response) { | ||
58 | + deferred.resolve(response.data); | ||
59 | + }, function fail() { | ||
60 | + deferred.reject(); | ||
61 | + }); | ||
62 | + return deferred.promise; | ||
63 | + } | ||
64 | + | ||
49 | function saveAlarm(alarm, ignoreErrors, config) { | 65 | function saveAlarm(alarm, ignoreErrors, config) { |
50 | var deferred = $q.defer(); | 66 | var deferred = $q.defer(); |
51 | var url = '/api/alarm'; | 67 | var url = '/api/alarm'; |
@@ -48,11 +48,16 @@ | @@ -48,11 +48,16 @@ | ||
48 | disable-attribute-scope-selection="true"> | 48 | disable-attribute-scope-selection="true"> |
49 | </tb-attribute-table> | 49 | </tb-attribute-table> |
50 | </md-tab> | 50 | </md-tab> |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> | ||
52 | + <tb-alarm-table flex entity-type="vm.types.entityType.asset" | ||
53 | + entity-id="vm.grid.operatingItem().id.id"> | ||
54 | + </tb-alarm-table> | ||
55 | + </md-tab> | ||
51 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'asset.events' | translate }}"> | 56 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'asset.events' | translate }}"> |
52 | <tb-event-table flex entity-type="vm.types.entityType.asset" | 57 | <tb-event-table flex entity-type="vm.types.entityType.asset" |
53 | entity-id="vm.grid.operatingItem().id.id" | 58 | entity-id="vm.grid.operatingItem().id.id" |
54 | tenant-id="vm.grid.operatingItem().tenantId.id" | 59 | tenant-id="vm.grid.operatingItem().tenantId.id" |
55 | - default-event-type="{{vm.types.eventType.alarm.value}}"> | 60 | + default-event-type="{{vm.types.eventType.error.value}}"> |
56 | </tb-event-table> | 61 | </tb-event-table> |
57 | </md-tab> | 62 | </md-tab> |
58 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | 63 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | import uiRouter from 'angular-ui-router'; | 16 | import uiRouter from 'angular-ui-router'; |
17 | import thingsboardGrid from '../components/grid.directive'; | 17 | import thingsboardGrid from '../components/grid.directive'; |
18 | -import thingsboardEvent from '../event'; | ||
19 | import thingsboardApiUser from '../api/user.service'; | 18 | import thingsboardApiUser from '../api/user.service'; |
20 | import thingsboardApiAsset from '../api/asset.service'; | 19 | import thingsboardApiAsset from '../api/asset.service'; |
21 | import thingsboardApiCustomer from '../api/customer.service'; | 20 | import thingsboardApiCustomer from '../api/customer.service'; |
@@ -29,7 +28,6 @@ import AssetDirective from './asset.directive'; | @@ -29,7 +28,6 @@ import AssetDirective from './asset.directive'; | ||
29 | export default angular.module('thingsboard.asset', [ | 28 | export default angular.module('thingsboard.asset', [ |
30 | uiRouter, | 29 | uiRouter, |
31 | thingsboardGrid, | 30 | thingsboardGrid, |
32 | - thingsboardEvent, | ||
33 | thingsboardApiUser, | 31 | thingsboardApiUser, |
34 | thingsboardApiAsset, | 32 | thingsboardApiAsset, |
35 | thingsboardApiCustomer | 33 | thingsboardApiCustomer |
@@ -72,6 +72,28 @@ export default angular.module('thingsboard.types', []) | @@ -72,6 +72,28 @@ export default angular.module('thingsboard.types', []) | ||
72 | ack: "ACK", | 72 | ack: "ACK", |
73 | unack: "UNACK" | 73 | unack: "UNACK" |
74 | }, | 74 | }, |
75 | + alarmSeverity: { | ||
76 | + "CRITICAL": { | ||
77 | + name: "alarm.severity-critical", | ||
78 | + class: "tb-critical" | ||
79 | + }, | ||
80 | + "MAJOR": { | ||
81 | + name: "alarm.severity-major", | ||
82 | + class: "tb-major" | ||
83 | + }, | ||
84 | + "MINOR": { | ||
85 | + name: "alarm.severity-minor", | ||
86 | + class: "tb-minor" | ||
87 | + }, | ||
88 | + "WARNING": { | ||
89 | + name: "alarm.severity-warning", | ||
90 | + class: "tb-warning" | ||
91 | + }, | ||
92 | + "INDETERMINATE": { | ||
93 | + name: "alarm.severity-indeterminate", | ||
94 | + class: "tb-indeterminate" | ||
95 | + } | ||
96 | + }, | ||
75 | aliasFilterType: { | 97 | aliasFilterType: { |
76 | entityList: { | 98 | entityList: { |
77 | value: 'entityList', | 99 | value: 'entityList', |
@@ -215,10 +237,6 @@ export default angular.module('thingsboard.types', []) | @@ -215,10 +237,6 @@ export default angular.module('thingsboard.types', []) | ||
215 | manages: "Manages" | 237 | manages: "Manages" |
216 | }, | 238 | }, |
217 | eventType: { | 239 | eventType: { |
218 | - alarm: { | ||
219 | - value: "ALARM", | ||
220 | - name: "event.type-alarm" | ||
221 | - }, | ||
222 | error: { | 240 | error: { |
223 | value: "ERROR", | 241 | value: "ERROR", |
224 | name: "event.type-error" | 242 | name: "event.type-error" |
@@ -48,11 +48,16 @@ | @@ -48,11 +48,16 @@ | ||
48 | disable-attribute-scope-selection="true"> | 48 | disable-attribute-scope-selection="true"> |
49 | </tb-attribute-table> | 49 | </tb-attribute-table> |
50 | </md-tab> | 50 | </md-tab> |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> | ||
52 | + <tb-alarm-table flex entity-type="vm.types.entityType.customer" | ||
53 | + entity-id="vm.grid.operatingItem().id.id"> | ||
54 | + </tb-alarm-table> | ||
55 | + </md-tab> | ||
51 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'customer.events' | translate }}"> | 56 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'customer.events' | translate }}"> |
52 | <tb-event-table flex entity-type="vm.types.entityType.customer" | 57 | <tb-event-table flex entity-type="vm.types.entityType.customer" |
53 | entity-id="vm.grid.operatingItem().id.id" | 58 | entity-id="vm.grid.operatingItem().id.id" |
54 | tenant-id="vm.grid.operatingItem().tenantId.id" | 59 | tenant-id="vm.grid.operatingItem().tenantId.id" |
55 | - default-event-type="{{vm.types.eventType.alarm.value}}"> | 60 | + default-event-type="{{vm.types.eventType.error.value}}"> |
56 | </tb-event-table> | 61 | </tb-event-table> |
57 | </md-tab> | 62 | </md-tab> |
58 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | 63 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> |
@@ -49,11 +49,16 @@ | @@ -49,11 +49,16 @@ | ||
49 | disable-attribute-scope-selection="true"> | 49 | disable-attribute-scope-selection="true"> |
50 | </tb-attribute-table> | 50 | </tb-attribute-table> |
51 | </md-tab> | 51 | </md-tab> |
52 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> | ||
53 | + <tb-alarm-table flex entity-type="vm.types.entityType.device" | ||
54 | + entity-id="vm.grid.operatingItem().id.id"> | ||
55 | + </tb-alarm-table> | ||
56 | + </md-tab> | ||
52 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'device.events' | translate }}"> | 57 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'device.events' | translate }}"> |
53 | <tb-event-table flex entity-type="vm.types.entityType.device" | 58 | <tb-event-table flex entity-type="vm.types.entityType.device" |
54 | entity-id="vm.grid.operatingItem().id.id" | 59 | entity-id="vm.grid.operatingItem().id.id" |
55 | tenant-id="vm.grid.operatingItem().tenantId.id" | 60 | tenant-id="vm.grid.operatingItem().tenantId.id" |
56 | - default-event-type="{{vm.types.eventType.alarm.value}}"> | 61 | + default-event-type="{{vm.types.eventType.error.value}}"> |
57 | </tb-event-table> | 62 | </tb-event-table> |
58 | </md-tab> | 63 | </md-tab> |
59 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | 64 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> |
@@ -15,7 +15,6 @@ | @@ -15,7 +15,6 @@ | ||
15 | */ | 15 | */ |
16 | import uiRouter from 'angular-ui-router'; | 16 | import uiRouter from 'angular-ui-router'; |
17 | import thingsboardGrid from '../components/grid.directive'; | 17 | import thingsboardGrid from '../components/grid.directive'; |
18 | -import thingsboardEvent from '../event'; | ||
19 | import thingsboardApiUser from '../api/user.service'; | 18 | import thingsboardApiUser from '../api/user.service'; |
20 | import thingsboardApiDevice from '../api/device.service'; | 19 | import thingsboardApiDevice from '../api/device.service'; |
21 | import thingsboardApiCustomer from '../api/customer.service'; | 20 | import thingsboardApiCustomer from '../api/customer.service'; |
@@ -30,7 +29,6 @@ import DeviceDirective from './device.directive'; | @@ -30,7 +29,6 @@ import DeviceDirective from './device.directive'; | ||
30 | export default angular.module('thingsboard.device', [ | 29 | export default angular.module('thingsboard.device', [ |
31 | uiRouter, | 30 | uiRouter, |
32 | thingsboardGrid, | 31 | thingsboardGrid, |
33 | - thingsboardEvent, | ||
34 | thingsboardApiUser, | 32 | thingsboardApiUser, |
35 | thingsboardApiDevice, | 33 | thingsboardApiDevice, |
36 | thingsboardApiCustomer | 34 | thingsboardApiCustomer |
@@ -62,7 +62,7 @@ export default function EventContentDialogController($mdDialog, content, title, | @@ -62,7 +62,7 @@ export default function EventContentDialogController($mdDialog, content, title, | ||
62 | } | 62 | } |
63 | newWidth = 8 * maxLineLength + 16; | 63 | newWidth = 8 * maxLineLength + 16; |
64 | } | 64 | } |
65 | - $('#tb-content', element).height(newHeight.toString() + "px") | 65 | + $('#tb-event-content', element).height(newHeight.toString() + "px") |
66 | .width(newWidth.toString() + "px"); | 66 | .width(newWidth.toString() + "px"); |
67 | vm.editor.resize(); | 67 | vm.editor.resize(); |
68 | } | 68 | } |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | </md-toolbar> | 27 | </md-toolbar> |
28 | <md-dialog-content> | 28 | <md-dialog-content> |
29 | <div class="md-dialog-content"> | 29 | <div class="md-dialog-content"> |
30 | - <div flex id="tb-content" readonly | 30 | + <div flex id="tb-event-content" readonly |
31 | ui-ace="vm.contentOptions" | 31 | ui-ace="vm.contentOptions" |
32 | ng-model="vm.content"> | 32 | ng-model="vm.content"> |
33 | </div> | 33 | </div> |
@@ -18,7 +18,6 @@ | @@ -18,7 +18,6 @@ | ||
18 | import eventHeaderLcEventTemplate from './event-header-lc-event.tpl.html'; | 18 | import eventHeaderLcEventTemplate from './event-header-lc-event.tpl.html'; |
19 | import eventHeaderStatsTemplate from './event-header-stats.tpl.html'; | 19 | import eventHeaderStatsTemplate from './event-header-stats.tpl.html'; |
20 | import eventHeaderErrorTemplate from './event-header-error.tpl.html'; | 20 | import eventHeaderErrorTemplate from './event-header-error.tpl.html'; |
21 | -import eventHeaderAlarmTemplate from './event-header-alarm.tpl.html'; | ||
22 | 21 | ||
23 | /* eslint-enable import/no-unresolved, import/default */ | 22 | /* eslint-enable import/no-unresolved, import/default */ |
24 | 23 | ||
@@ -39,9 +38,6 @@ export default function EventHeaderDirective($compile, $templateCache, types) { | @@ -39,9 +38,6 @@ export default function EventHeaderDirective($compile, $templateCache, types) { | ||
39 | case types.eventType.error.value: | 38 | case types.eventType.error.value: |
40 | template = eventHeaderErrorTemplate; | 39 | template = eventHeaderErrorTemplate; |
41 | break; | 40 | break; |
42 | - case types.eventType.alarm.value: | ||
43 | - template = eventHeaderAlarmTemplate; | ||
44 | - break; | ||
45 | } | 41 | } |
46 | return $templateCache.get(template); | 42 | return $templateCache.get(template); |
47 | } | 43 | } |
@@ -20,7 +20,6 @@ import eventErrorDialogTemplate from './event-content-dialog.tpl.html'; | @@ -20,7 +20,6 @@ import eventErrorDialogTemplate from './event-content-dialog.tpl.html'; | ||
20 | import eventRowLcEventTemplate from './event-row-lc-event.tpl.html'; | 20 | import eventRowLcEventTemplate from './event-row-lc-event.tpl.html'; |
21 | import eventRowStatsTemplate from './event-row-stats.tpl.html'; | 21 | import eventRowStatsTemplate from './event-row-stats.tpl.html'; |
22 | import eventRowErrorTemplate from './event-row-error.tpl.html'; | 22 | import eventRowErrorTemplate from './event-row-error.tpl.html'; |
23 | -import eventRowAlarmTemplate from './event-row-alarm.tpl.html'; | ||
24 | 23 | ||
25 | /* eslint-enable import/no-unresolved, import/default */ | 24 | /* eslint-enable import/no-unresolved, import/default */ |
26 | 25 | ||
@@ -41,9 +40,6 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | @@ -41,9 +40,6 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ | ||
41 | case types.eventType.error.value: | 40 | case types.eventType.error.value: |
42 | template = eventRowErrorTemplate; | 41 | template = eventRowErrorTemplate; |
43 | break; | 42 | break; |
44 | - case types.eventType.alarm.value: | ||
45 | - template = eventRowAlarmTemplate; | ||
46 | - break; | ||
47 | } | 43 | } |
48 | return $templateCache.get(template); | 44 | return $templateCache.get(template); |
49 | } | 45 | } |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | </md-input-container> | 27 | </md-input-container> |
28 | <tb-timewindow flex ng-model="timewindow" history-only as-button="true"></tb-timewindow> | 28 | <tb-timewindow flex ng-model="timewindow" history-only as-button="true"></tb-timewindow> |
29 | </section> | 29 | </section> |
30 | - <md-list flex layout="column" class="md-whiteframe-z1 tb-table"> | 30 | + <md-list flex layout="column" class="md-whiteframe-z1 tb-event-table"> |
31 | <md-list class="tb-row tb-header" layout="row" tb-event-header event-type="{{eventType}}"> | 31 | <md-list class="tb-row tb-header" layout="row" tb-event-header event-type="{{eventType}}"> |
32 | </md-list> | 32 | </md-list> |
33 | <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!loading()" | 33 | <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!loading()" |
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | -md-list.tb-table { | 16 | +md-list.tb-event-table { |
17 | padding: 0px; | 17 | padding: 0px; |
18 | 18 | ||
19 | md-list-item { | 19 | md-list-item { |
@@ -64,7 +64,7 @@ md-list.tb-table { | @@ -64,7 +64,7 @@ md-list.tb-table { | ||
64 | 64 | ||
65 | } | 65 | } |
66 | 66 | ||
67 | -#tb-content { | 67 | +#tb-event-content { |
68 | min-width: 400px; | 68 | min-width: 400px; |
69 | min-height: 50px; | 69 | min-height: 50px; |
70 | width: 100%; | 70 | width: 100%; |
@@ -32,6 +32,8 @@ import thingsboardDashboardAutocomplete from '../components/dashboard-autocomple | @@ -32,6 +32,8 @@ import thingsboardDashboardAutocomplete from '../components/dashboard-autocomple | ||
32 | import thingsboardUserMenu from './user-menu.directive'; | 32 | import thingsboardUserMenu from './user-menu.directive'; |
33 | 33 | ||
34 | import thingsboardEntity from '../entity'; | 34 | import thingsboardEntity from '../entity'; |
35 | +import thingsboardEvent from '../event'; | ||
36 | +import thingsboardAlarm from '../alarm'; | ||
35 | import thingsboardTenant from '../tenant'; | 37 | import thingsboardTenant from '../tenant'; |
36 | import thingsboardCustomer from '../customer'; | 38 | import thingsboardCustomer from '../customer'; |
37 | import thingsboardUser from '../user'; | 39 | import thingsboardUser from '../user'; |
@@ -61,6 +63,8 @@ export default angular.module('thingsboard.home', [ | @@ -61,6 +63,8 @@ export default angular.module('thingsboard.home', [ | ||
61 | thingsboardHomeLinks, | 63 | thingsboardHomeLinks, |
62 | thingsboardUserMenu, | 64 | thingsboardUserMenu, |
63 | thingsboardEntity, | 65 | thingsboardEntity, |
66 | + thingsboardEvent, | ||
67 | + thingsboardAlarm, | ||
64 | thingsboardTenant, | 68 | thingsboardTenant, |
65 | thingsboardCustomer, | 69 | thingsboardCustomer, |
66 | thingsboardUser, | 70 | thingsboardUser, |
@@ -411,7 +411,6 @@ | @@ -411,7 +411,6 @@ | ||
411 | }, | 411 | }, |
412 | "event": { | 412 | "event": { |
413 | "event-type": "Tipo de evento", | 413 | "event-type": "Tipo de evento", |
414 | - "type-alarm": "Alarma", | ||
415 | "type-error": "Error", | 414 | "type-error": "Error", |
416 | "type-lc-event": "Ciclo de vida", | 415 | "type-lc-event": "Ciclo de vida", |
417 | "type-stats": "Estadísticas", | 416 | "type-stats": "Estadísticas", |
@@ -378,7 +378,6 @@ export default function addLocaleKorean(locales) { | @@ -378,7 +378,6 @@ export default function addLocaleKorean(locales) { | ||
378 | }, | 378 | }, |
379 | "event": { | 379 | "event": { |
380 | "event-type": "이벤트 타입", | 380 | "event-type": "이벤트 타입", |
381 | - "type-alarm": "알람", | ||
382 | "type-error": "에러", | 381 | "type-error": "에러", |
383 | "type-lc-event": "주기적 이벤트", | 382 | "type-lc-event": "주기적 이벤트", |
384 | "type-stats": "통계", | 383 | "type-stats": "통계", |
@@ -411,7 +411,6 @@ export default function addLocaleRussian(locales) { | @@ -411,7 +411,6 @@ export default function addLocaleRussian(locales) { | ||
411 | }, | 411 | }, |
412 | "event": { | 412 | "event": { |
413 | "event-type": "Тип события", | 413 | "event-type": "Тип события", |
414 | - "type-alarm": "Аварийное оповещение", | ||
415 | "type-error": "Ошибка", | 414 | "type-error": "Ошибка", |
416 | "type-lc-event": "Событие жизненного цикла", | 415 | "type-lc-event": "Событие жизненного цикла", |
417 | "type-stats": "Статистика", | 416 | "type-stats": "Статистика", |
@@ -411,7 +411,6 @@ export default function addLocaleChinese(locales) { | @@ -411,7 +411,6 @@ export default function addLocaleChinese(locales) { | ||
411 | }, | 411 | }, |
412 | "event" : { | 412 | "event" : { |
413 | "event-type": "事件类型", | 413 | "event-type": "事件类型", |
414 | - "type-alarm": "报警", | ||
415 | "type-error": "错误", | 414 | "type-error": "错误", |
416 | "type-lc-event": "生命周期事件", | 415 | "type-lc-event": "生命周期事件", |
417 | "type-stats": "类型统计", | 416 | "type-stats": "类型统计", |
@@ -108,9 +108,43 @@ export default angular.module('thingsboard.locale', []) | @@ -108,9 +108,43 @@ export default angular.module('thingsboard.locale', []) | ||
108 | }, | 108 | }, |
109 | "alarm": { | 109 | "alarm": { |
110 | "alarm": "Alarm", | 110 | "alarm": "Alarm", |
111 | + "alarms": "Alarms", | ||
111 | "select-alarm": "Select alarm", | 112 | "select-alarm": "Select alarm", |
112 | "no-alarms-matching": "No alarms matching '{{entity}}' were found.", | 113 | "no-alarms-matching": "No alarms matching '{{entity}}' were found.", |
113 | - "alarm-required": "Alarm is required" | 114 | + "alarm-required": "Alarm is required", |
115 | + "alarm-status": "Alarm status", | ||
116 | + "search-status": { | ||
117 | + "ANY": "Any", | ||
118 | + "ACTIVE": "Active", | ||
119 | + "CLEARED": "Cleared", | ||
120 | + "ACK": "Acknowledged", | ||
121 | + "UNACK": "Unacknowledged" | ||
122 | + }, | ||
123 | + "display-status": { | ||
124 | + "ACTIVE_UNACK": "Active Unacknowledged", | ||
125 | + "ACTIVE_ACK": "Active Acknowledged", | ||
126 | + "CLEARED_UNACK": "Cleared Unacknowledged", | ||
127 | + "CLEARED_ACK": "Cleared Acknowledged" | ||
128 | + }, | ||
129 | + "no-alarms-prompt": "No alarms found", | ||
130 | + "created-time": "Created time", | ||
131 | + "type": "Type", | ||
132 | + "severity": "Severity", | ||
133 | + "originator": "Originator", | ||
134 | + "details": "Details", | ||
135 | + "status": "Status", | ||
136 | + "alarm-details": "Alarm details", | ||
137 | + "start-time": "Start time", | ||
138 | + "end-time": "End time", | ||
139 | + "ack-time": "Acknowledged time", | ||
140 | + "clear-time": "Cleared time", | ||
141 | + "severity-critical": "Critical", | ||
142 | + "severity-major": "Major", | ||
143 | + "severity-minor": "Minor", | ||
144 | + "severity-warning": "Warning", | ||
145 | + "severity-indeterminate": "Indeterminate", | ||
146 | + "acknowledge": "Acknowledge", | ||
147 | + "clear": "Clear" | ||
114 | }, | 148 | }, |
115 | "alias": { | 149 | "alias": { |
116 | "add": "Add alias", | 150 | "add": "Add alias", |
@@ -647,7 +681,6 @@ export default angular.module('thingsboard.locale', []) | @@ -647,7 +681,6 @@ export default angular.module('thingsboard.locale', []) | ||
647 | }, | 681 | }, |
648 | "event": { | 682 | "event": { |
649 | "event-type": "Event type", | 683 | "event-type": "Event type", |
650 | - "type-alarm": "Alarm", | ||
651 | "type-error": "Error", | 684 | "type-error": "Error", |
652 | "type-lc-event": "Lifecycle event", | 685 | "type-lc-event": "Lifecycle event", |
653 | "type-stats": "Statistics", | 686 | "type-stats": "Statistics", |
@@ -16,7 +16,6 @@ | @@ -16,7 +16,6 @@ | ||
16 | import uiRouter from 'angular-ui-router'; | 16 | import uiRouter from 'angular-ui-router'; |
17 | import thingsboardGrid from '../components/grid.directive'; | 17 | import thingsboardGrid from '../components/grid.directive'; |
18 | import thingsboardJsonForm from '../components/json-form.directive'; | 18 | import thingsboardJsonForm from '../components/json-form.directive'; |
19 | -import thingsboardEvent from '../event'; | ||
20 | import thingsboardApiPlugin from '../api/plugin.service'; | 19 | import thingsboardApiPlugin from '../api/plugin.service'; |
21 | import thingsboardApiComponentDescriptor from '../api/component-descriptor.service'; | 20 | import thingsboardApiComponentDescriptor from '../api/component-descriptor.service'; |
22 | 21 | ||
@@ -28,7 +27,6 @@ export default angular.module('thingsboard.plugin', [ | @@ -28,7 +27,6 @@ export default angular.module('thingsboard.plugin', [ | ||
28 | uiRouter, | 27 | uiRouter, |
29 | thingsboardGrid, | 28 | thingsboardGrid, |
30 | thingsboardJsonForm, | 29 | thingsboardJsonForm, |
31 | - thingsboardEvent, | ||
32 | thingsboardApiPlugin, | 30 | thingsboardApiPlugin, |
33 | thingsboardApiComponentDescriptor | 31 | thingsboardApiComponentDescriptor |
34 | ]) | 32 | ]) |
@@ -48,12 +48,16 @@ | @@ -48,12 +48,16 @@ | ||
48 | disable-attribute-scope-selection="true"> | 48 | disable-attribute-scope-selection="true"> |
49 | </tb-attribute-table> | 49 | </tb-attribute-table> |
50 | </md-tab> | 50 | </md-tab> |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" 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> | ||
51 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'plugin.events' | translate }}"> | 56 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'plugin.events' | translate }}"> |
52 | <tb-event-table flex entity-type="vm.types.entityType.plugin" | 57 | <tb-event-table flex entity-type="vm.types.entityType.plugin" |
53 | entity-id="vm.grid.operatingItem().id.id" | 58 | entity-id="vm.grid.operatingItem().id.id" |
54 | tenant-id="vm.grid.operatingItem().tenantId.id" | 59 | tenant-id="vm.grid.operatingItem().tenantId.id" |
55 | - default-event-type="{{vm.types.eventType.lcEvent.value}}" | ||
56 | - disabled-event-types="{{vm.types.eventType.alarm.value}}"> | 60 | + default-event-type="{{vm.types.eventType.lcEvent.value}}"> |
57 | </tb-event-table> | 61 | </tb-event-table> |
58 | </md-tab> | 62 | </md-tab> |
59 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> | 63 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> |
@@ -17,7 +17,6 @@ import uiRouter from 'angular-ui-router'; | @@ -17,7 +17,6 @@ import uiRouter from 'angular-ui-router'; | ||
17 | import thingsboardGrid from '../components/grid.directive'; | 17 | import thingsboardGrid from '../components/grid.directive'; |
18 | import thingsboardPluginSelect from '../components/plugin-select.directive'; | 18 | import thingsboardPluginSelect from '../components/plugin-select.directive'; |
19 | import thingsboardComponent from '../component'; | 19 | import thingsboardComponent from '../component'; |
20 | -import thingsboardEvent from '../event'; | ||
21 | import thingsboardApiRule from '../api/rule.service'; | 20 | import thingsboardApiRule from '../api/rule.service'; |
22 | import thingsboardApiPlugin from '../api/plugin.service'; | 21 | import thingsboardApiPlugin from '../api/plugin.service'; |
23 | import thingsboardApiComponentDescriptor from '../api/component-descriptor.service'; | 22 | import thingsboardApiComponentDescriptor from '../api/component-descriptor.service'; |
@@ -31,7 +30,6 @@ export default angular.module('thingsboard.rule', [ | @@ -31,7 +30,6 @@ export default angular.module('thingsboard.rule', [ | ||
31 | thingsboardGrid, | 30 | thingsboardGrid, |
32 | thingsboardPluginSelect, | 31 | thingsboardPluginSelect, |
33 | thingsboardComponent, | 32 | thingsboardComponent, |
34 | - thingsboardEvent, | ||
35 | thingsboardApiRule, | 33 | thingsboardApiRule, |
36 | thingsboardApiPlugin, | 34 | thingsboardApiPlugin, |
37 | thingsboardApiComponentDescriptor | 35 | thingsboardApiComponentDescriptor |
@@ -48,12 +48,16 @@ | @@ -48,12 +48,16 @@ | ||
48 | disable-attribute-scope-selection="true"> | 48 | disable-attribute-scope-selection="true"> |
49 | </tb-attribute-table> | 49 | </tb-attribute-table> |
50 | </md-tab> | 50 | </md-tab> |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" 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> | ||
51 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'rule.events' | translate }}"> | 56 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'rule.events' | translate }}"> |
52 | <tb-event-table flex entity-type="vm.types.entityType.rule" | 57 | <tb-event-table flex entity-type="vm.types.entityType.rule" |
53 | entity-id="vm.grid.operatingItem().id.id" | 58 | entity-id="vm.grid.operatingItem().id.id" |
54 | tenant-id="vm.grid.operatingItem().tenantId.id" | 59 | tenant-id="vm.grid.operatingItem().tenantId.id" |
55 | - default-event-type="{{vm.types.eventType.lcEvent.value}}" | ||
56 | - disabled-event-types="{{vm.types.eventType.alarm.value}}"> | 60 | + default-event-type="{{vm.types.eventType.lcEvent.value}}"> |
57 | </tb-event-table> | 61 | </tb-event-table> |
58 | </md-tab> | 62 | </md-tab> |
59 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> | 63 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> |
@@ -46,11 +46,16 @@ | @@ -46,11 +46,16 @@ | ||
46 | disable-attribute-scope-selection="true"> | 46 | disable-attribute-scope-selection="true"> |
47 | </tb-attribute-table> | 47 | </tb-attribute-table> |
48 | </md-tab> | 48 | </md-tab> |
49 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> | ||
50 | + <tb-alarm-table flex entity-type="vm.types.entityType.tenant" | ||
51 | + entity-id="vm.grid.operatingItem().id.id"> | ||
52 | + </tb-alarm-table> | ||
53 | + </md-tab> | ||
49 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'tenant.events' | translate }}"> | 54 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'tenant.events' | translate }}"> |
50 | <tb-event-table flex entity-type="vm.types.entityType.tenant" | 55 | <tb-event-table flex entity-type="vm.types.entityType.tenant" |
51 | entity-id="vm.grid.operatingItem().id.id" | 56 | entity-id="vm.grid.operatingItem().id.id" |
52 | tenant-id="vm.types.id.nullUid" | 57 | tenant-id="vm.types.id.nullUid" |
53 | - default-event-type="{{vm.types.eventType.alarm.value}}"> | 58 | + default-event-type="{{vm.types.eventType.error.value}}"> |
54 | </tb-event-table> | 59 | </tb-event-table> |
55 | </md-tab> | 60 | </md-tab> |
56 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | 61 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> |
@@ -309,6 +309,24 @@ pre.tb-highlight { | @@ -309,6 +309,24 @@ pre.tb-highlight { | ||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | +.tb-severity { | ||
313 | + font-weight: bold; | ||
314 | + &.tb-critical { | ||
315 | + color: red !important; | ||
316 | + } | ||
317 | + &.tb-major { | ||
318 | + color: orange !important; | ||
319 | + } | ||
320 | + &.tb-minor { | ||
321 | + color: #ffca3d !important; | ||
322 | + } | ||
323 | + &.tb-warning { | ||
324 | + color: #abab00 !important; | ||
325 | + } | ||
326 | + &.tb-indeterminate { | ||
327 | + color: green !important; | ||
328 | + } | ||
329 | +} | ||
312 | 330 | ||
313 | /*********************** | 331 | /*********************** |
314 | * Flow | 332 | * Flow |