Commit a0e74d72054393cc28bb34cd6ecca0b896798715
1 parent
83c2758c
Edge Downlinks new tab implementation 2
Showing
13 changed files
with
784 additions
and
4 deletions
1 | +/* | |
2 | + * Copyright © 2016-2020 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 $ from 'jquery'; | |
17 | +import 'brace/ext/language_tools'; | |
18 | +import 'brace/ext/searchbox'; | |
19 | +import 'brace/mode/java'; | |
20 | +import 'brace/theme/github'; | |
21 | +import beautify from 'js-beautify'; | |
22 | + | |
23 | +/* eslint-disable angular/angularelement */ | |
24 | + | |
25 | +const js_beautify = beautify.js; | |
26 | + | |
27 | +/*@ngInject*/ | |
28 | +export default function EdgeDownlinksContentDialogController($mdDialog, types, content, contentType, title, showingCallback) { | |
29 | + | |
30 | + var vm = this; | |
31 | + | |
32 | + showingCallback.onShowing = function(scope, element) { | |
33 | + updateEditorSize(element); | |
34 | + } | |
35 | + | |
36 | + vm.content = content; | |
37 | + vm.title = title; | |
38 | + | |
39 | + var mode; | |
40 | + if (contentType) { | |
41 | + mode = types.contentType[contentType].code; | |
42 | + if (contentType == types.contentType.JSON.value && vm.content) { | |
43 | + vm.content = js_beautify(vm.content, {indent_size: 4}); | |
44 | + } | |
45 | + } else { | |
46 | + mode = 'java'; | |
47 | + } | |
48 | + | |
49 | + vm.contentOptions = { | |
50 | + useWrapMode: false, | |
51 | + mode: mode, | |
52 | + showGutter: false, | |
53 | + showPrintMargin: false, | |
54 | + theme: 'github', | |
55 | + advanced: { | |
56 | + enableSnippets: false, | |
57 | + enableBasicAutocompletion: false, | |
58 | + enableLiveAutocompletion: false | |
59 | + }, | |
60 | + onLoad: function (_ace) { | |
61 | + vm.editor = _ace; | |
62 | + } | |
63 | + }; | |
64 | + | |
65 | + function updateEditorSize(element) { | |
66 | + var newHeight = 400; | |
67 | + var newWidth = 600; | |
68 | + if (vm.content && vm.content.length > 0) { | |
69 | + var lines = vm.content.split('\n'); | |
70 | + newHeight = 16 * lines.length + 16; | |
71 | + var maxLineLength = 0; | |
72 | + for (var i = 0; i < lines.length; i++) { | |
73 | + var line = lines[i].replace(/\t/g, ' ').replace(/\n/g, ''); | |
74 | + var lineLength = line.length; | |
75 | + maxLineLength = Math.max(maxLineLength, lineLength); | |
76 | + } | |
77 | + newWidth = 8 * maxLineLength + 16; | |
78 | + } | |
79 | + $('#tb-event-content', element).height(newHeight.toString() + "px") | |
80 | + .width(newWidth.toString() + "px"); | |
81 | + vm.editor.resize(); | |
82 | + } | |
83 | + | |
84 | + vm.close = close; | |
85 | + | |
86 | + function close () { | |
87 | + $mdDialog.hide(); | |
88 | + } | |
89 | + | |
90 | +} | |
91 | + | |
92 | +/* eslint-enable angular/angularelement */ | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2020 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 edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' | |
19 | + | |
20 | +/* eslint-enable import/no-unresolved, import/default */ | |
21 | + | |
22 | +/*@ngInject*/ | |
23 | +export default function EventHeaderDirective2($compile, $templateCache, types) { | |
24 | + | |
25 | + var linker = function (scope, element, attrs) { | |
26 | + | |
27 | + var getTemplate = function(eventType) { | |
28 | + var template = ''; | |
29 | + switch(eventType) { | |
30 | + case types.edgeDownlinks.value: | |
31 | + template = edgeDownlinksHeaderTemplate; | |
32 | + break; | |
33 | + } | |
34 | + return $templateCache.get(template); | |
35 | + } | |
36 | + | |
37 | + scope.loadTemplate = function() { | |
38 | + element.html(getTemplate(attrs.eventType)); | |
39 | + $compile(element.contents())(scope); | |
40 | + } | |
41 | + | |
42 | + attrs.$observe('eventType', function() { | |
43 | + scope.loadTemplate(); | |
44 | + }); | |
45 | + | |
46 | + } | |
47 | + | |
48 | + return { | |
49 | + restrict: "A", | |
50 | + replace: false, | |
51 | + link: linker, | |
52 | + scope: false | |
53 | + }; | |
54 | +} | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2020 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 eventErrorDialogTemplate from './event-content-dialog.tpl.html'; | |
19 | + | |
20 | +import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html'; | |
21 | + | |
22 | +/* eslint-enable import/no-unresolved, import/default */ | |
23 | + | |
24 | +/*@ngInject*/ | |
25 | +export default function EventRowDirective2($compile, $templateCache, $mdDialog, $document, $translate, | |
26 | + types, utils, toast, entityService, ruleChainService) { | |
27 | + | |
28 | + var linker = function (scope, element, attrs) { | |
29 | + | |
30 | + var getTemplate = function(eventType) { | |
31 | + var template = ''; | |
32 | + switch(eventType) { | |
33 | + case types.edgeDownlinks.value: | |
34 | + template = edgeDownlinlsRowTemplate; | |
35 | + break; | |
36 | + } | |
37 | + return $templateCache.get(template); | |
38 | + } | |
39 | + | |
40 | + scope.loadTemplate = function() { | |
41 | + element.html(getTemplate(attrs.eventType)); | |
42 | + $compile(element.contents())(scope); | |
43 | + } | |
44 | + | |
45 | + attrs.$observe('eventType', function() { | |
46 | + scope.loadTemplate(); | |
47 | + }); | |
48 | + | |
49 | + scope.types = types; | |
50 | + | |
51 | + scope.event = attrs.event; | |
52 | + | |
53 | + scope.showEdgeEntityContent = function($event, title, contentType) { | |
54 | + var onShowingCallback = { | |
55 | + onShowing: function(){} | |
56 | + } | |
57 | + if (!contentType) { | |
58 | + contentType = null; | |
59 | + } | |
60 | + var content = ''; | |
61 | + switch(scope.event.type) { | |
62 | + case types.edgeEventType.relation: | |
63 | + content = angular.toJson(scope.event.body); | |
64 | + showDialog(); | |
65 | + break; | |
66 | + case types.edgeEventType.ruleChainMetaData: | |
67 | + content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( | |
68 | + function success(info) { | |
69 | + showDialog(); | |
70 | + return angular.toJson(info); | |
71 | + }, function fail() { | |
72 | + showError(); | |
73 | + }); | |
74 | + break; | |
75 | + default: | |
76 | + content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then( | |
77 | + function success(info) { | |
78 | + showDialog(); | |
79 | + return angular.toJson(info); | |
80 | + }, function fail() { | |
81 | + showError(); | |
82 | + }); | |
83 | + break; | |
84 | + } | |
85 | + function showDialog() { | |
86 | + $mdDialog.show({ | |
87 | + controller: 'EventContentDialogController2', | |
88 | + controllerAs: 'vm', | |
89 | + templateUrl: eventErrorDialogTemplate, | |
90 | + locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, | |
91 | + parent: angular.element($document[0].body), | |
92 | + fullscreen: true, | |
93 | + targetEvent: $event, | |
94 | + multiple: true, | |
95 | + onShowing: function(scope, element) { | |
96 | + onShowingCallback.onShowing(scope, element); | |
97 | + } | |
98 | + }); | |
99 | + } | |
100 | + function showError() { | |
101 | + toast.showError($translate.instant('edge.load-entity-error')); | |
102 | + } | |
103 | + } | |
104 | + | |
105 | + scope.checkEdgeEventType = function (type) { | |
106 | + return !(type === types.edgeEventType.widgetType || | |
107 | + type === types.edgeEventType.adminSettings || | |
108 | + type === types.edgeEventType.widgetsBundle ); | |
109 | + } | |
110 | + | |
111 | + scope.checkTooltip = function($event) { | |
112 | + var el = $event.target; | |
113 | + var $el = angular.element(el); | |
114 | + if(el.offsetWidth < el.scrollWidth && !$el.attr('title')){ | |
115 | + $el.attr('title', $el.text()); | |
116 | + } | |
117 | + } | |
118 | + | |
119 | + $compile(element.contents())(scope); | |
120 | + | |
121 | + scope.updateStatus = function(eventCreatedTime) { | |
122 | + var status; | |
123 | + if (eventCreatedTime < scope.queueStartTs) { | |
124 | + status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); | |
125 | + scope.statusColor = types.edgeEventStatus.DEPLOYED.color; | |
126 | + } else { | |
127 | + status = $translate.instant(types.edgeEventStatus.PENDING.name); | |
128 | + scope.statusColor = types.edgeEventStatus.PENDING.color; | |
129 | + } | |
130 | + return status; | |
131 | + } | |
132 | + } | |
133 | + | |
134 | + return { | |
135 | + restrict: "A", | |
136 | + replace: false, | |
137 | + link: linker, | |
138 | + scope: false | |
139 | + }; | |
140 | +} | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2020 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 './event.scss'; | |
17 | + | |
18 | +/* eslint-disable import/no-unresolved, import/default */ | |
19 | + | |
20 | +import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html'; | |
21 | + | |
22 | +/* eslint-enable import/no-unresolved, import/default */ | |
23 | + | |
24 | +/*@ngInject*/ | |
25 | +export default function EdgeDownlinksDirective2($compile, $templateCache, $rootScope, $translate, types, | |
26 | + eventService, edgeService, attributeService) { | |
27 | + | |
28 | + var linker = function (scope, element) { | |
29 | + | |
30 | + var template = $templateCache.get(edgeDownlinksTableTemplate); | |
31 | + | |
32 | + element.html(template); | |
33 | + | |
34 | + scope.eventType = types.edgeDownlinks.value; | |
35 | + | |
36 | + var pageSize = 20; | |
37 | + var startTime = 0; | |
38 | + var endTime = 0; | |
39 | + | |
40 | + scope.timewindow = { | |
41 | + history: { | |
42 | + timewindowMs: 24 * 60 * 60 * 1000 // 1 day | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + scope.topIndex = 0; | |
47 | + | |
48 | + scope.theEvents = { | |
49 | + getItemAtIndex: function (index) { | |
50 | + if (index > scope.events.data.length) { | |
51 | + scope.theEvents.fetchMoreItems_(index); | |
52 | + return null; | |
53 | + } | |
54 | + var item = scope.events.data[index]; | |
55 | + if (item) { | |
56 | + item.indexNumber = index + 1; | |
57 | + } | |
58 | + return item; | |
59 | + }, | |
60 | + | |
61 | + getLength: function () { | |
62 | + if (scope.events.hasNext) { | |
63 | + return scope.events.data.length + scope.events.nextPageLink.limit; | |
64 | + } else { | |
65 | + return scope.events.data.length; | |
66 | + } | |
67 | + }, | |
68 | + | |
69 | + fetchMoreItems_: function () { | |
70 | + if (scope.events.hasNext && !scope.events.pending) { | |
71 | + if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { | |
72 | + scope.loadEdgeInfo(); | |
73 | + scope.events.pending = true; | |
74 | + edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( | |
75 | + function success(events) { | |
76 | + scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); | |
77 | + scope.events.nextPageLink = events.nextPageLink; | |
78 | + scope.events.hasNext = events.hasNext; | |
79 | + if (scope.events.hasNext) { | |
80 | + scope.events.nextPageLink.limit = pageSize; | |
81 | + } | |
82 | + scope.events.pending = false; | |
83 | + }, | |
84 | + function fail() { | |
85 | + scope.events.hasNext = false; | |
86 | + scope.events.pending = false; | |
87 | + }); | |
88 | + } else { | |
89 | + scope.events.hasNext = false; | |
90 | + } | |
91 | + } | |
92 | + } | |
93 | + }; | |
94 | + | |
95 | + scope.$watch("entityId", function(newVal, prevVal) { | |
96 | + if (newVal && !angular.equals(newVal, prevVal)) { | |
97 | + scope.resetFilter(); | |
98 | + scope.reload(); | |
99 | + } | |
100 | + }); | |
101 | + | |
102 | + scope.$watch("timewindow", function(newVal, prevVal) { | |
103 | + if (newVal && !angular.equals(newVal, prevVal)) { | |
104 | + scope.reload(); | |
105 | + } | |
106 | + }, true); | |
107 | + | |
108 | + scope.resetFilter = function() { | |
109 | + scope.timewindow = { | |
110 | + history: { | |
111 | + timewindowMs: 24 * 60 * 60 * 1000 // 1 day | |
112 | + } | |
113 | + }; | |
114 | + } | |
115 | + | |
116 | + scope.updateTimeWindowRange = function() { | |
117 | + if (scope.timewindow.history.timewindowMs) { | |
118 | + var currentTime = (new Date).getTime(); | |
119 | + startTime = currentTime - scope.timewindow.history.timewindowMs; | |
120 | + endTime = currentTime; | |
121 | + } else { | |
122 | + startTime = scope.timewindow.history.fixedTimewindow.startTimeMs; | |
123 | + endTime = scope.timewindow.history.fixedTimewindow.endTimeMs; | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + scope.reload = function() { | |
128 | + scope.topIndex = 0; | |
129 | + scope.selected = []; | |
130 | + scope.updateTimeWindowRange(); | |
131 | + scope.events = { | |
132 | + data: [], | |
133 | + nextPageLink: { | |
134 | + limit: pageSize, | |
135 | + startTime: startTime, | |
136 | + endTime: endTime | |
137 | + }, | |
138 | + hasNext: true, | |
139 | + pending: false | |
140 | + }; | |
141 | + scope.theEvents.getItemAtIndex(pageSize); | |
142 | + } | |
143 | + | |
144 | + scope.noData = function() { | |
145 | + return scope.events.data.length == 0 && !scope.events.hasNext; | |
146 | + } | |
147 | + | |
148 | + scope.hasData = function() { | |
149 | + return scope.events.data.length > 0; | |
150 | + } | |
151 | + | |
152 | + scope.loading = function() { | |
153 | + return $rootScope.loading; | |
154 | + } | |
155 | + | |
156 | + scope.hasScroll = function() { | |
157 | + var repeatContainer = scope.repeatContainer[0]; | |
158 | + if (repeatContainer) { | |
159 | + var scrollElement = repeatContainer.children[0]; | |
160 | + if (scrollElement) { | |
161 | + return scrollElement.scrollHeight > scrollElement.clientHeight; | |
162 | + } | |
163 | + } | |
164 | + return false; | |
165 | + } | |
166 | + | |
167 | + scope.subscriptionId = null; | |
168 | + | |
169 | + scope.loadEdgeInfo = function() { | |
170 | + attributeService.getEntityAttributesValues( | |
171 | + scope.entityType, | |
172 | + scope.entityId, | |
173 | + types.attributesScope.server.value, | |
174 | + types.edgeAttributeKeys.queueStartTs, | |
175 | + null).then( | |
176 | + function success(attributes) { | |
177 | + attributes.length > 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0; | |
178 | + }); | |
179 | + scope.checkSubscription(); | |
180 | + } | |
181 | + | |
182 | + scope.onEdgeAttributesUpdate = function(attributes) { | |
183 | + let edgeAttributes = attributes.reduce(function (map, attribute) { | |
184 | + map[attribute.key] = attribute; | |
185 | + return map; | |
186 | + }, {}); | |
187 | + if (edgeAttributes.queueStartTs) { | |
188 | + scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs; | |
189 | + } | |
190 | + } | |
191 | + | |
192 | + scope.checkSubscription = function() { | |
193 | + var newSubscriptionId = null; | |
194 | + if (scope.entityId && scope.entityType && types.attributesScope.server.value) { | |
195 | + newSubscriptionId = | |
196 | + attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); | |
197 | + } | |
198 | + if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { | |
199 | + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); | |
200 | + } | |
201 | + scope.subscriptionId = newSubscriptionId; | |
202 | + } | |
203 | + | |
204 | + scope.$on('$destroy', function () { | |
205 | + if (scope.subscriptionId) { | |
206 | + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); | |
207 | + } | |
208 | + }); | |
209 | + | |
210 | + scope.reload(); | |
211 | + | |
212 | + $compile(element.contents())(scope); | |
213 | + } | |
214 | + function prepareEdgeEventData(data) { | |
215 | + | |
216 | + data.forEach( | |
217 | + edgeEvent => { | |
218 | + edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); | |
219 | + edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); | |
220 | + } | |
221 | + ); | |
222 | + return data; | |
223 | + } | |
224 | + | |
225 | + return { | |
226 | + restrict: "E", | |
227 | + link: linker, | |
228 | + scope: { | |
229 | + entityType: '=', | |
230 | + entityId: '=', | |
231 | + tenantId: '=' | |
232 | + } | |
233 | + }; | |
234 | +} | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2020 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 | + <tb-timewindow flex ng-model="timewindow" history-only as-button="true"></tb-timewindow> | |
21 | + <md-button ng-disabled="$root.loading" | |
22 | + class="md-icon-button" ng-click="reload()"> | |
23 | + <md-icon>refresh</md-icon> | |
24 | + <md-tooltip md-direction="top"> | |
25 | + {{ 'action.refresh' | translate }} | |
26 | + </md-tooltip> | |
27 | + </md-button> | |
28 | + </section> | |
29 | + <md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table"> | |
30 | + <md-list class="tb-row tb-header" layout="row" layout-align="start center" tb-edge-downlinks-header event-type="{{eventType}}"> | |
31 | + </md-list> | |
32 | + <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading" | |
33 | + ng-show="$root.loading"></md-progress-linear> | |
34 | + <md-divider></md-divider> | |
35 | + <span translate layout-align="center center" | |
36 | + style="margin-top: 25px;" | |
37 | + class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt</span> | |
38 | + <md-virtual-repeat-container ng-show="hasData()" flex md-top-index="topIndex" tb-scope-element="repeatContainer"> | |
39 | + <md-list-item md-virtual-repeat="event in theEvents" md-on-demand flex ng-style="hasScroll() ? {'margin-right':'-15px'} : {}"> | |
40 | + <md-list class="tb-row" flex layout="row" layout-align="start center" tb-edge-downlinks-row event-type="{{eventType}}" event="{{event}}"> | |
41 | + </md-list> | |
42 | + <md-divider flex></md-divider> | |
43 | + </md-list-item> | |
44 | + </md-virtual-repeat-container> | |
45 | + </md-list> | |
46 | +</md-content> | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2020 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.title | translate }}"> | |
19 | + <md-toolbar> | |
20 | + <div class="md-toolbar-tools"> | |
21 | + <h2 translate>{{ vm.title }}</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"> | |
30 | + <div flex id="tb-event-content" readonly | |
31 | + ui-ace="vm.contentOptions" | |
32 | + ng-model="vm.content"> | |
33 | + </div> | |
34 | + </div> | |
35 | + </md-dialog-content> | |
36 | + <md-dialog-actions layout="row"> | |
37 | + <span flex></span> | |
38 | + <md-button ng-disabled="$root.loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | | |
39 | + translate }} | |
40 | + </md-button> | |
41 | + </md-dialog-actions> | |
42 | +</md-dialog> | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2020 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 translate class="tb-cell" flex="20">event.event-time</div> | |
19 | +<div translate class="tb-cell" flex="10">event.event-type</div> | |
20 | +<div translate class="tb-cell" flex="15">edge.event-action</div> | |
21 | +<div translate class="tb-cell" flex="30">edge.entity-id</div> | |
22 | +<div translate class="tb-cell" flex="15">edge.status</div> | |
23 | +<div translate class="tb-cell" flex="10">edge.entity-info</div> | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2020 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-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div> | |
19 | +<div class="tb-cell" flex="10">{{ event.edgeEventTypeText }}</div> | |
20 | +<div class="tb-cell" flex="15">{{ event.edgeEventActionText }}</div> | |
21 | +<div class="tb-cell" flex="30">{{ event.entityId }}</div> | |
22 | +<div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(event.createdTime) }}</div> | |
23 | +<div class="tb-cell" flex="10"> | |
24 | + <md-button ng-if="checkEdgeEventType(event.type)" class="md-icon-button md-primary" | |
25 | + ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')" | |
26 | + aria-label="{{ 'action.view' | translate }}"> | |
27 | + <md-tooltip md-direction="top"> | |
28 | + {{ 'action.view' | translate }} | |
29 | + </md-tooltip> | |
30 | + <md-icon aria-label="{{ 'action.view' | translate }}" | |
31 | + class="material-icons"> | |
32 | + more_horiz | |
33 | + </md-icon> | |
34 | + </md-button> | |
35 | +</div> | |
36 | + | |
37 | + | ... | ... |
ui/src/app/edge/downlinks/event.scss
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2020 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 | +md-list.tb-event-table { | |
17 | + padding: 0; | |
18 | + | |
19 | + md-list-item { | |
20 | + padding: 0; | |
21 | + } | |
22 | + | |
23 | + .tb-row { | |
24 | + height: 48px; | |
25 | + padding: 0; | |
26 | + overflow: hidden; | |
27 | + | |
28 | + .tb-cell { | |
29 | + text-overflow: ellipsis; | |
30 | + | |
31 | + &.tb-scroll { | |
32 | + overflow-x: auto; | |
33 | + overflow-y: hidden; | |
34 | + white-space: nowrap; | |
35 | + } | |
36 | + | |
37 | + &.tb-nowrap { | |
38 | + white-space: nowrap; | |
39 | + } | |
40 | + } | |
41 | + } | |
42 | + | |
43 | + .tb-row:hover { | |
44 | + background-color: #eee; | |
45 | + } | |
46 | + | |
47 | + .tb-header:hover { | |
48 | + background: none; | |
49 | + } | |
50 | + | |
51 | + .tb-header { | |
52 | + .tb-cell { | |
53 | + font-size: 12px; | |
54 | + font-weight: 700; | |
55 | + color: rgba(0, 0, 0, .54); | |
56 | + white-space: nowrap; | |
57 | + background: none; | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + .tb-cell { | |
62 | + &:first-child { | |
63 | + padding-left: 14px; | |
64 | + } | |
65 | + | |
66 | + &:last-child { | |
67 | + padding-right: 14px; | |
68 | + } | |
69 | + padding: 0 6px; | |
70 | + margin: auto 0; | |
71 | + overflow: hidden; | |
72 | + font-size: 13px; | |
73 | + color: rgba(0, 0, 0, .87); | |
74 | + text-align: left; | |
75 | + vertical-align: middle; | |
76 | + | |
77 | + .md-button { | |
78 | + padding: 0; | |
79 | + margin: 0; | |
80 | + } | |
81 | + } | |
82 | + | |
83 | + .tb-cell.tb-number { | |
84 | + text-align: right; | |
85 | + } | |
86 | +} | |
87 | + | |
88 | +.tb-edge-downlinks-table-2 { | |
89 | + @extend .tb-event-table; | |
90 | +} | |
91 | + | |
92 | +#tb-event-content { | |
93 | + width: 100%; | |
94 | + min-width: 400px; | |
95 | + height: 100%; | |
96 | + min-height: 50px; | |
97 | +} | ... | ... |
... | ... | @@ -65,11 +65,18 @@ |
65 | 65 | default-event-type="{{vm.types.eventType.error.value}}"> |
66 | 66 | </tb-event-table> |
67 | 67 | </md-tab> |
68 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.downlinks' | translate }}"> | |
69 | - <tb-edge-downlinks-table flex entity-type="vm.types.entityType.edge" | |
68 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.edge' | translate }}"> | |
69 | + <tb-edge-downlinks-table-old flex entity-type="vm.types.entityType.edge" | |
70 | 70 | entity-id="vm.grid.operatingItem().id.id" |
71 | 71 | tenant-id="vm.grid.operatingItem().tenantId.id" |
72 | 72 | default-event-type="{{vm.types.edgeDownlinks.value}}"> |
73 | + </tb-edge-downlinks-table-old> | |
74 | + </md-tab> | |
75 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.downlinks' | translate }}"> | |
76 | + <tb-edge-downlinks-table flex entity-type="vm.types.entityType.edge" | |
77 | + entity-id="vm.grid.operatingItem().id.id" | |
78 | + tenant-id="vm.grid.operatingItem().tenantId.id" | |
79 | + default-event-type="{{vm.types.edgeDownlinks.value}}"> | |
73 | 80 | </tb-edge-downlinks-table> |
74 | 81 | </md-tab> |
75 | 82 | <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}"> | ... | ... |
... | ... | @@ -25,6 +25,10 @@ import AssignEdgeToCustomerController from './assign-to-customer.controller'; |
25 | 25 | import AddEdgesToCustomerController from './add-edges-to-customer.controller'; |
26 | 26 | import SetRootRuleChainToEdgesController from './set-root-rule-chain-to-edges.controller'; |
27 | 27 | import EdgeDirective from './edge.directive'; |
28 | +import EdgeDownlinksContentDialogController from './downlinks/edge-downlinks-content-dialog.controller'; | |
29 | +import EdgeDownlinksHeaderDirective from './downlinks/edge-downlinks-header.directive'; | |
30 | +import EdgeDownlinksRowDirective from './downlinks/edge-downlinks-row.directive'; | |
31 | +import EdgeDownlinksDirective from "./downlinks/edge-downlinks-table.directive"; | |
28 | 32 | |
29 | 33 | export default angular.module('thingsboard.edge', [ |
30 | 34 | uiRouter, |
... | ... | @@ -39,5 +43,9 @@ export default angular.module('thingsboard.edge', [ |
39 | 43 | .controller('AssignEdgeToCustomerController', AssignEdgeToCustomerController) |
40 | 44 | .controller('AddEdgesToCustomerController', AddEdgesToCustomerController) |
41 | 45 | .controller('SetRootRuleChainToEdgesController', SetRootRuleChainToEdgesController) |
46 | + .controller('EdgeDownlinksContentDialogController', EdgeDownlinksContentDialogController) | |
42 | 47 | .directive('tbEdge', EdgeDirective) |
48 | + .directive('tbEdgeDownlinksHeader', EdgeDownlinksHeaderDirective) | |
49 | + .directive('tbEdgeDownlinksRow', EdgeDownlinksRowDirective) | |
50 | + .directive('tbEdgeDownlinksTable', EdgeDownlinksDirective) | |
43 | 51 | .name; | ... | ... |
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | </md-tooltip> |
27 | 27 | </md-button> |
28 | 28 | </section> |
29 | - <md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table"> | |
29 | + <md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table-old"> | |
30 | 30 | <md-list class="tb-row tb-header" layout="row" layout-align="start center" tb-event-header event-type="{{eventType}}"> |
31 | 31 | </md-list> |
32 | 32 | <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading" | ... | ... |
... | ... | @@ -28,5 +28,5 @@ export default angular.module('thingsboard.event', [ |
28 | 28 | .directive('tbEventHeader', EventHeaderDirective) |
29 | 29 | .directive('tbEventRow', EventRowDirective) |
30 | 30 | .directive('tbEventTable', EventTableDirective) |
31 | - .directive('tbEdgeDownlinksTable', EdgeDownlinksDirective) | |
31 | + .directive('tbEdgeDownlinksTableOld', EdgeDownlinksDirective) | |
32 | 32 | .name; | ... | ... |