Browse Source

Edge Downlinks new tab final implementation

pull/3957/head
Artem Babak 6 years ago
parent
commit
501c7d1926
  1. 12
      ui/src/app/common/types.constant.js
  2. 8
      ui/src/app/edge/downlinks/downlink.scss
  3. 2
      ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js
  4. 2
      ui/src/app/edge/downlinks/edge-downlinks-content-dialog.tpl.html
  5. 27
      ui/src/app/edge/downlinks/edge-downlinks-header.directive.js
  6. 0
      ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html
  7. 66
      ui/src/app/edge/downlinks/edge-downlinks-row.directive.js
  8. 12
      ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html
  9. 66
      ui/src/app/edge/downlinks/edge-downlinks-table.directive.js
  10. 6
      ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html
  11. 37
      ui/src/app/edge/downlinks/event-row-edge-event.tpl.html
  12. 7
      ui/src/app/edge/edges.tpl.html
  13. 2
      ui/src/app/edge/index.js
  14. 234
      ui/src/app/event/edge-downlinks-table.directive.js
  15. 46
      ui/src/app/event/edge-downlinks-table.tpl.html
  16. 23
      ui/src/app/event/event-header-edge-event.tpl.html
  17. 4
      ui/src/app/event/event-header.directive.js
  18. 84
      ui/src/app/event/event-row.directive.js
  19. 4
      ui/src/app/event/event.scss
  20. 2
      ui/src/app/event/index.js

12
ui/src/app/common/types.constant.js

@ -384,7 +384,7 @@ export default angular.module('thingsboard.types', [])
entityView: "ENTITY_VIEW", entityView: "ENTITY_VIEW",
edge: "EDGE" edge: "EDGE"
}, },
edgeEventType:{ edgeDownlinksType:{
dashboard: "DASHBOARD", dashboard: "DASHBOARD",
asset: "ASSET", asset: "ASSET",
device: "DEVICE", device: "DEVICE",
@ -405,7 +405,7 @@ export default angular.module('thingsboard.types', [])
widgetType: "WIDGET_TYPE", widgetType: "WIDGET_TYPE",
adminSettings: "ADMIN_SETTINGS" adminSettings: "ADMIN_SETTINGS"
}, },
edgeEventStatus: { edgeDownlinksStatus: {
"DEPLOYED": { "DEPLOYED": {
name: "edge.deployed", name: "edge.deployed",
color: grey900 color: grey900
@ -1073,7 +1073,7 @@ export default angular.module('thingsboard.types', [])
translate: { translate: {
customTranslationsPrefix: "custom." customTranslationsPrefix: "custom."
}, },
edgeEventActionType: { edgeDownlinksActionType: {
"ADDED": { "ADDED": {
name: "audit-log.type-added" name: "audit-log.type-added"
}, },
@ -1135,7 +1135,7 @@ export default angular.module('thingsboard.types', [])
name: "audit-log.type-unassigned-from-edge" name: "audit-log.type-unassigned-from-edge"
} }
}, },
edgeEventTypeTranslations:{ edgeDownlinksTypeTranslations:{
"DASHBOARD": { "DASHBOARD": {
name: "entity.type-dashboard" name: "entity.type-dashboard"
}, },
@ -1193,10 +1193,6 @@ export default angular.module('thingsboard.types', [])
"ADMIN_SETTINGS": { "ADMIN_SETTINGS": {
name: "permission.resource.display-type.ADMIN_SETTINGS" name: "permission.resource.display-type.ADMIN_SETTINGS"
} }
},
edgeDownlinks: {
value: "EDGE_DOWNLINKS",
name: "edge.downlinks"
} }
} }
).name; ).name;

8
ui/src/app/edge/downlinks/event.scss → ui/src/app/edge/downlinks/downlink.scss

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
md-list.tb-event-table { md-list.tb-edge-downlinks-table {
padding: 0; padding: 0;
md-list-item { md-list-item {
@ -85,11 +85,7 @@ md-list.tb-event-table {
} }
} }
.tb-edge-downlinks-table-2 { #tb-edge-downlinks-content {
@extend .tb-event-table;
}
#tb-event-content {
width: 100%; width: 100%;
min-width: 400px; min-width: 400px;
height: 100%; height: 100%;

2
ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js

@ -76,7 +76,7 @@ export default function EdgeDownlinksContentDialogController($mdDialog, types, c
} }
newWidth = 8 * maxLineLength + 16; newWidth = 8 * maxLineLength + 16;
} }
$('#tb-event-content', element).height(newHeight.toString() + "px") $('#tb-edge-downlinks-content', element).height(newHeight.toString() + "px")
.width(newWidth.toString() + "px"); .width(newWidth.toString() + "px");
vm.editor.resize(); vm.editor.resize();
} }

2
ui/src/app/edge/downlinks/event-content-dialog.tpl.html → ui/src/app/edge/downlinks/edge-downlinks-content-dialog.tpl.html

@ -27,7 +27,7 @@
</md-toolbar> </md-toolbar>
<md-dialog-content> <md-dialog-content>
<div class="md-dialog-content"> <div class="md-dialog-content">
<div flex id="tb-event-content" readonly <div flex id="tb-edge-downlinks-content" readonly
ui-ace="vm.contentOptions" ui-ace="vm.contentOptions"
ng-model="vm.content"> ng-model="vm.content">
</div> </div>

27
ui/src/app/edge/downlinks/edge-downlinks-header.directive.js

@ -15,34 +15,19 @@
*/ */
/* eslint-disable import/no-unresolved, import/default */ /* eslint-disable import/no-unresolved, import/default */
import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' import edgeDownlinksHeaderTemplate from './edge-downlinks-header.tpl.html'
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/ /*@ngInject*/
export default function EventHeaderDirective2($compile, $templateCache, types) { export default function EdgeDownlinksHeaderDirective($compile, $templateCache) {
var linker = function (scope, element, attrs) { var linker = function (scope, element) {
var getTemplate = function(eventType) { var template = edgeDownlinksHeaderTemplate;
var template = '';
switch(eventType) {
case types.edgeDownlinks.value:
template = edgeDownlinksHeaderTemplate;
break;
}
return $templateCache.get(template);
}
scope.loadTemplate = function() {
element.html(getTemplate(attrs.eventType));
$compile(element.contents())(scope);
}
attrs.$observe('eventType', function() {
scope.loadTemplate();
});
element.html($templateCache.get(template));
$compile(element.contents())(scope);
} }
return { return {

0
ui/src/app/edge/downlinks/event-header-edge-event.tpl.html → ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html

66
ui/src/app/edge/downlinks/edge-downlinks-row.directive.js

@ -15,40 +15,24 @@
*/ */
/* eslint-disable import/no-unresolved, import/default */ /* eslint-disable import/no-unresolved, import/default */
import eventErrorDialogTemplate from './event-content-dialog.tpl.html'; import edgeDownlinksContentTemplate from './edge-downlinks-content-dialog.tpl.html';
import edgeDownlinlsRowTemplate from './edge-downlinks-row.tpl.html';
import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html';
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/ /*@ngInject*/
export default function EventRowDirective2($compile, $templateCache, $mdDialog, $document, $translate, export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdDialog, $document, $translate,
types, utils, toast, entityService, ruleChainService) { types, utils, toast, entityService, ruleChainService) {
var linker = function (scope, element, attrs) { var linker = function (scope, element, attrs) {
var getTemplate = function(eventType) { var template = edgeDownlinlsRowTemplate;
var template = '';
switch(eventType) {
case types.edgeDownlinks.value:
template = edgeDownlinlsRowTemplate;
break;
}
return $templateCache.get(template);
}
scope.loadTemplate = function() {
element.html(getTemplate(attrs.eventType));
$compile(element.contents())(scope);
}
attrs.$observe('eventType', function() { element.html($templateCache.get(template));
scope.loadTemplate(); $compile(element.contents())(scope);
});
scope.types = types; scope.types = types;
scope.downlink = attrs.downlink;
scope.event = attrs.event;
scope.showEdgeEntityContent = function($event, title, contentType) { scope.showEdgeEntityContent = function($event, title, contentType) {
var onShowingCallback = { var onShowingCallback = {
@ -58,13 +42,13 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog,
contentType = null; contentType = null;
} }
var content = ''; var content = '';
switch(scope.event.type) { switch(scope.downlink.type) {
case types.edgeEventType.relation: case types.edgeDownlinksType.relation:
content = angular.toJson(scope.event.body); content = angular.toJson(scope.downlink.body);
showDialog(); showDialog();
break; break;
case types.edgeEventType.ruleChainMetaData: case types.edgeDownlinksType.ruleChainMetaData:
content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( content = ruleChainService.getRuleChainMetaData(scope.downlink.entityId, {ignoreErrors: true}).then(
function success(info) { function success(info) {
showDialog(); showDialog();
return angular.toJson(info); return angular.toJson(info);
@ -73,7 +57,7 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog,
}); });
break; break;
default: default:
content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then( content = entityService.getEntity(scope.downlink.type, scope.downlink.entityId, {ignoreErrors: true}).then(
function success(info) { function success(info) {
showDialog(); showDialog();
return angular.toJson(info); return angular.toJson(info);
@ -84,9 +68,9 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog,
} }
function showDialog() { function showDialog() {
$mdDialog.show({ $mdDialog.show({
controller: 'EventContentDialogController2', controller: 'EdgeDownlinksContentDialogController',
controllerAs: 'vm', controllerAs: 'vm',
templateUrl: eventErrorDialogTemplate, templateUrl: edgeDownlinksContentTemplate,
locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback},
parent: angular.element($document[0].body), parent: angular.element($document[0].body),
fullscreen: true, fullscreen: true,
@ -102,10 +86,10 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog,
} }
} }
scope.checkEdgeEventType = function (type) { scope.checkEdgeDownlinksType = function (type) {
return !(type === types.edgeEventType.widgetType || return !(type === types.edgeDownlinksType.widgetType ||
type === types.edgeEventType.adminSettings || type === types.edgeDownlinksType.adminSettings ||
type === types.edgeEventType.widgetsBundle ); type === types.edgeDownlinksType.widgetsBundle );
} }
scope.checkTooltip = function($event) { scope.checkTooltip = function($event) {
@ -118,14 +102,14 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog,
$compile(element.contents())(scope); $compile(element.contents())(scope);
scope.updateStatus = function(eventCreatedTime) { scope.updateStatus = function(downlinkCreatedTime) {
var status; var status;
if (eventCreatedTime < scope.queueStartTs) { if (downlinkCreatedTime < scope.queueStartTs) {
status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); status = $translate.instant(types.edgeDownlinksStatus.DEPLOYED.name);
scope.statusColor = types.edgeEventStatus.DEPLOYED.color; scope.statusColor = types.edgeDownlinksStatus.DEPLOYED.color;
} else { } else {
status = $translate.instant(types.edgeEventStatus.PENDING.name); status = $translate.instant(types.edgeDownlinksStatus.PENDING.name);
scope.statusColor = types.edgeEventStatus.PENDING.color; scope.statusColor = types.edgeDownlinksStatus.PENDING.color;
} }
return status; return status;
} }

12
ui/src/app/event/event-row-edge-event.tpl.html → ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html

@ -15,13 +15,13 @@
limitations under the License. limitations under the License.
--> -->
<div class="tb-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div> <div class="tb-cell" flex="20">{{ downlink.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div>
<div class="tb-cell" flex="10">{{ event.edgeEventTypeText }}</div> <div class="tb-cell" flex="10">{{ downlink.edgeDownlinksTypeText }}</div>
<div class="tb-cell" flex="15">{{ event.edgeEventActionText }}</div> <div class="tb-cell" flex="15">{{ downlink.edgeDownlinksActionText }}</div>
<div class="tb-cell" flex="30">{{ event.entityId }}</div> <div class="tb-cell" flex="30">{{ downlink.entityId }}</div>
<div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(event.createdTime) }}</div> <div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(downlink.createdTime) }}</div>
<div class="tb-cell" flex="10"> <div class="tb-cell" flex="10">
<md-button ng-if="checkEdgeEventType(event.type)" class="md-icon-button md-primary" <md-button ng-if="checkEdgeDownlinksType(downlink.type)" class="md-icon-button md-primary"
ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')" ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')"
aria-label="{{ 'action.view' | translate }}"> aria-label="{{ 'action.view' | translate }}">
<md-tooltip md-direction="top"> <md-tooltip md-direction="top">

66
ui/src/app/edge/downlinks/edge-downlinks-table.directive.js

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import './event.scss'; import './downlink.scss';
/* eslint-disable import/no-unresolved, import/default */ /* eslint-disable import/no-unresolved, import/default */
@ -22,17 +22,13 @@ import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html';
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/ /*@ngInject*/
export default function EdgeDownlinksDirective2($compile, $templateCache, $rootScope, $translate, types, export default function EdgeDownlinksDirective($compile, $templateCache, $rootScope, $translate, types, edgeService, attributeService) {
eventService, edgeService, attributeService) {
var linker = function (scope, element) { var linker = function (scope, element) {
var template = $templateCache.get(edgeDownlinksTableTemplate); var template = $templateCache.get(edgeDownlinksTableTemplate);
element.html(template); element.html(template);
scope.eventType = types.edgeDownlinks.value;
var pageSize = 20; var pageSize = 20;
var startTime = 0; var startTime = 0;
var endTime = 0; var endTime = 0;
@ -45,13 +41,13 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS
scope.topIndex = 0; scope.topIndex = 0;
scope.theEvents = { scope.theDownlinks = {
getItemAtIndex: function (index) { getItemAtIndex: function (index) {
if (index > scope.events.data.length) { if (index > scope.downlinks.data.length) {
scope.theEvents.fetchMoreItems_(index); scope.theDownlinks.fetchMoreItems_(index);
return null; return null;
} }
var item = scope.events.data[index]; var item = scope.downlinks.data[index];
if (item) { if (item) {
item.indexNumber = index + 1; item.indexNumber = index + 1;
} }
@ -59,34 +55,34 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS
}, },
getLength: function () { getLength: function () {
if (scope.events.hasNext) { if (scope.downlinks.hasNext) {
return scope.events.data.length + scope.events.nextPageLink.limit; return scope.downlinks.data.length + scope.downlinks.nextPageLink.limit;
} else { } else {
return scope.events.data.length; return scope.downlinks.data.length;
} }
}, },
fetchMoreItems_: function () { fetchMoreItems_: function () {
if (scope.events.hasNext && !scope.events.pending) { if (scope.downlinks.hasNext && !scope.downlinks.pending) {
if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { if (scope.entityType && scope.entityId && scope.tenantId) {
scope.loadEdgeInfo(); scope.loadEdgeInfo();
scope.events.pending = true; scope.downlinks.pending = true;
edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( edgeService.getEdgeDownlinks(scope.entityId, scope.downlinks.nextPageLink).then(
function success(events) { function success(downlinks) {
scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); scope.downlinks.data = scope.downlinks.data.concat(prepareEdgeDownlinksData(downlinks.data));
scope.events.nextPageLink = events.nextPageLink; scope.downlinks.nextPageLink = downlinks.nextPageLink;
scope.events.hasNext = events.hasNext; scope.downlinks.hasNext = downlinks.hasNext;
if (scope.events.hasNext) { if (scope.downlinks.hasNext) {
scope.events.nextPageLink.limit = pageSize; scope.downlinks.nextPageLink.limit = pageSize;
} }
scope.events.pending = false; scope.downlinks.pending = false;
}, },
function fail() { function fail() {
scope.events.hasNext = false; scope.downlinks.hasNext = false;
scope.events.pending = false; scope.downlinks.pending = false;
}); });
} else { } else {
scope.events.hasNext = false; scope.downlinks.hasNext = false;
} }
} }
} }
@ -128,7 +124,7 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS
scope.topIndex = 0; scope.topIndex = 0;
scope.selected = []; scope.selected = [];
scope.updateTimeWindowRange(); scope.updateTimeWindowRange();
scope.events = { scope.downlinks = {
data: [], data: [],
nextPageLink: { nextPageLink: {
limit: pageSize, limit: pageSize,
@ -138,15 +134,15 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS
hasNext: true, hasNext: true,
pending: false pending: false
}; };
scope.theEvents.getItemAtIndex(pageSize); scope.theDownlinks.getItemAtIndex(pageSize);
} }
scope.noData = function() { scope.noData = function() {
return scope.events.data.length == 0 && !scope.events.hasNext; return scope.downlinks.data.length == 0 && !scope.downlinks.hasNext;
} }
scope.hasData = function() { scope.hasData = function() {
return scope.events.data.length > 0; return scope.downlinks.data.length > 0;
} }
scope.loading = function() { scope.loading = function() {
@ -211,12 +207,12 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS
$compile(element.contents())(scope); $compile(element.contents())(scope);
} }
function prepareEdgeEventData(data) { function prepareEdgeDownlinksData(data) {
data.forEach( data.forEach(
edgeEvent => { edgeDownlink => {
edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); edgeDownlink.edgeDownlinksActionText = $translate.instant(types.edgeDownlinksActionType[edgeDownlink.action].name);
edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); edgeDownlink.edgeDownlinksTypeText = $translate.instant(types.edgeDownlinksTypeTranslations[edgeDownlink.edgeId.entityType].name);
} }
); );
return data; return data;

6
ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html

@ -27,7 +27,7 @@
</md-button> </md-button>
</section> </section>
<md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table"> <md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table">
<md-list class="tb-row tb-header" layout="row" layout-align="start center" tb-edge-downlinks-header event-type="{{eventType}}"> <md-list class="tb-row tb-header" layout="row" layout-align="start center" tb-edge-downlinks-header>
</md-list> </md-list>
<md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading" <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading"
ng-show="$root.loading"></md-progress-linear> ng-show="$root.loading"></md-progress-linear>
@ -36,8 +36,8 @@
style="margin-top: 25px;" style="margin-top: 25px;"
class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt</span> class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt</span>
<md-virtual-repeat-container ng-show="hasData()" flex md-top-index="topIndex" tb-scope-element="repeatContainer"> <md-virtual-repeat-container ng-show="hasData()" flex md-top-index="topIndex" tb-scope-element="repeatContainer">
<md-list-item md-virtual-repeat="event in theEvents" md-on-demand flex ng-style="hasScroll() ? {'margin-right':'-15px'} : {}"> <md-list-item md-virtual-repeat="downlink in theDownlinks" md-on-demand flex ng-style="hasScroll() ? {'margin-right':'-15px'} : {}">
<md-list class="tb-row" flex layout="row" layout-align="start center" tb-edge-downlinks-row event-type="{{eventType}}" event="{{event}}"> <md-list class="tb-row" flex layout="row" layout-align="start center" tb-edge-downlinks-row downlink="{{downlink}}">
</md-list> </md-list>
<md-divider flex></md-divider> <md-divider flex></md-divider>
</md-list-item> </md-list-item>

37
ui/src/app/edge/downlinks/event-row-edge-event.tpl.html

@ -1,37 +0,0 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div class="tb-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div>
<div class="tb-cell" flex="10">{{ event.edgeEventTypeText }}</div>
<div class="tb-cell" flex="15">{{ event.edgeEventActionText }}</div>
<div class="tb-cell" flex="30">{{ event.entityId }}</div>
<div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(event.createdTime) }}</div>
<div class="tb-cell" flex="10">
<md-button ng-if="checkEdgeEventType(event.type)" class="md-icon-button md-primary"
ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')"
aria-label="{{ 'action.view' | translate }}">
<md-tooltip md-direction="top">
{{ 'action.view' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'action.view' | translate }}"
class="material-icons">
more_horiz
</md-icon>
</md-button>
</div>

7
ui/src/app/edge/edges.tpl.html

@ -65,13 +65,6 @@
default-event-type="{{vm.types.eventType.error.value}}"> default-event-type="{{vm.types.eventType.error.value}}">
</tb-event-table> </tb-event-table>
</md-tab> </md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.edge' | translate }}">
<tb-edge-downlinks-table-old flex entity-type="vm.types.entityType.edge"
entity-id="vm.grid.operatingItem().id.id"
tenant-id="vm.grid.operatingItem().tenantId.id"
default-event-type="{{vm.types.edgeDownlinks.value}}">
</tb-edge-downlinks-table-old>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.downlinks' | translate }}"> <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.downlinks' | translate }}">
<tb-edge-downlinks-table flex entity-type="vm.types.entityType.edge" <tb-edge-downlinks-table flex entity-type="vm.types.entityType.edge"
entity-id="vm.grid.operatingItem().id.id" entity-id="vm.grid.operatingItem().id.id"

2
ui/src/app/edge/index.js

@ -45,7 +45,7 @@ export default angular.module('thingsboard.edge', [
.controller('SetRootRuleChainToEdgesController', SetRootRuleChainToEdgesController) .controller('SetRootRuleChainToEdgesController', SetRootRuleChainToEdgesController)
.controller('EdgeDownlinksContentDialogController', EdgeDownlinksContentDialogController) .controller('EdgeDownlinksContentDialogController', EdgeDownlinksContentDialogController)
.directive('tbEdge', EdgeDirective) .directive('tbEdge', EdgeDirective)
.directive('tbEdgeDownlinksTable', EdgeDownlinksDirective)
.directive('tbEdgeDownlinksHeader', EdgeDownlinksHeaderDirective) .directive('tbEdgeDownlinksHeader', EdgeDownlinksHeaderDirective)
.directive('tbEdgeDownlinksRow', EdgeDownlinksRowDirective) .directive('tbEdgeDownlinksRow', EdgeDownlinksRowDirective)
.directive('tbEdgeDownlinksTable', EdgeDownlinksDirective)
.name; .name;

234
ui/src/app/event/edge-downlinks-table.directive.js

@ -1,234 +0,0 @@
/*
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import './event.scss';
/* eslint-disable import/no-unresolved, import/default */
import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function EdgeDownlinksDirective($compile, $templateCache, $rootScope, $translate, types,
eventService, edgeService, attributeService) {
var linker = function (scope, element) {
var template = $templateCache.get(edgeDownlinksTableTemplate);
element.html(template);
scope.eventType = types.edgeDownlinks.value;
var pageSize = 20;
var startTime = 0;
var endTime = 0;
scope.timewindow = {
history: {
timewindowMs: 24 * 60 * 60 * 1000 // 1 day
}
}
scope.topIndex = 0;
scope.theEvents = {
getItemAtIndex: function (index) {
if (index > scope.events.data.length) {
scope.theEvents.fetchMoreItems_(index);
return null;
}
var item = scope.events.data[index];
if (item) {
item.indexNumber = index + 1;
}
return item;
},
getLength: function () {
if (scope.events.hasNext) {
return scope.events.data.length + scope.events.nextPageLink.limit;
} else {
return scope.events.data.length;
}
},
fetchMoreItems_: function () {
if (scope.events.hasNext && !scope.events.pending) {
if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) {
scope.loadEdgeInfo();
scope.events.pending = true;
edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then(
function success(events) {
scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data));
scope.events.nextPageLink = events.nextPageLink;
scope.events.hasNext = events.hasNext;
if (scope.events.hasNext) {
scope.events.nextPageLink.limit = pageSize;
}
scope.events.pending = false;
},
function fail() {
scope.events.hasNext = false;
scope.events.pending = false;
});
} else {
scope.events.hasNext = false;
}
}
}
};
scope.$watch("entityId", function(newVal, prevVal) {
if (newVal && !angular.equals(newVal, prevVal)) {
scope.resetFilter();
scope.reload();
}
});
scope.$watch("timewindow", function(newVal, prevVal) {
if (newVal && !angular.equals(newVal, prevVal)) {
scope.reload();
}
}, true);
scope.resetFilter = function() {
scope.timewindow = {
history: {
timewindowMs: 24 * 60 * 60 * 1000 // 1 day
}
};
}
scope.updateTimeWindowRange = function() {
if (scope.timewindow.history.timewindowMs) {
var currentTime = (new Date).getTime();
startTime = currentTime - scope.timewindow.history.timewindowMs;
endTime = currentTime;
} else {
startTime = scope.timewindow.history.fixedTimewindow.startTimeMs;
endTime = scope.timewindow.history.fixedTimewindow.endTimeMs;
}
}
scope.reload = function() {
scope.topIndex = 0;
scope.selected = [];
scope.updateTimeWindowRange();
scope.events = {
data: [],
nextPageLink: {
limit: pageSize,
startTime: startTime,
endTime: endTime
},
hasNext: true,
pending: false
};
scope.theEvents.getItemAtIndex(pageSize);
}
scope.noData = function() {
return scope.events.data.length == 0 && !scope.events.hasNext;
}
scope.hasData = function() {
return scope.events.data.length > 0;
}
scope.loading = function() {
return $rootScope.loading;
}
scope.hasScroll = function() {
var repeatContainer = scope.repeatContainer[0];
if (repeatContainer) {
var scrollElement = repeatContainer.children[0];
if (scrollElement) {
return scrollElement.scrollHeight > scrollElement.clientHeight;
}
}
return false;
}
scope.subscriptionId = null;
scope.loadEdgeInfo = function() {
attributeService.getEntityAttributesValues(
scope.entityType,
scope.entityId,
types.attributesScope.server.value,
types.edgeAttributeKeys.queueStartTs,
null).then(
function success(attributes) {
attributes.length > 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0;
});
scope.checkSubscription();
}
scope.onEdgeAttributesUpdate = function(attributes) {
let edgeAttributes = attributes.reduce(function (map, attribute) {
map[attribute.key] = attribute;
return map;
}, {});
if (edgeAttributes.queueStartTs) {
scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs;
}
}
scope.checkSubscription = function() {
var newSubscriptionId = null;
if (scope.entityId && scope.entityType && types.attributesScope.server.value) {
newSubscriptionId =
attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value);
}
if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) {
attributeService.unsubscribeForEntityAttributes(scope.subscriptionId);
}
scope.subscriptionId = newSubscriptionId;
}
scope.$on('$destroy', function () {
if (scope.subscriptionId) {
attributeService.unsubscribeForEntityAttributes(scope.subscriptionId);
}
});
scope.reload();
$compile(element.contents())(scope);
}
function prepareEdgeEventData(data) {
data.forEach(
edgeEvent => {
edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name);
edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name);
}
);
return data;
}
return {
restrict: "E",
link: linker,
scope: {
entityType: '=',
entityId: '=',
tenantId: '='
}
};
}

46
ui/src/app/event/edge-downlinks-table.tpl.html

@ -1,46 +0,0 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-content flex class="md-padding tb-absolute-fill" layout="column">
<section layout="row">
<tb-timewindow flex ng-model="timewindow" history-only as-button="true"></tb-timewindow>
<md-button ng-disabled="$root.loading"
class="md-icon-button" ng-click="reload()">
<md-icon>refresh</md-icon>
<md-tooltip md-direction="top">
{{ 'action.refresh' | translate }}
</md-tooltip>
</md-button>
</section>
<md-list flex layout="column" class="md-whiteframe-z1 tb-edge-downlinks-table-old">
<md-list class="tb-row tb-header" layout="row" layout-align="start center" tb-event-header event-type="{{eventType}}">
</md-list>
<md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading"
ng-show="$root.loading"></md-progress-linear>
<md-divider></md-divider>
<span translate layout-align="center center"
style="margin-top: 25px;"
class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt</span>
<md-virtual-repeat-container ng-show="hasData()" flex md-top-index="topIndex" tb-scope-element="repeatContainer">
<md-list-item md-virtual-repeat="event in theEvents" md-on-demand flex ng-style="hasScroll() ? {'margin-right':'-15px'} : {}">
<md-list class="tb-row" flex layout="row" layout-align="start center" tb-event-row event-type="{{eventType}}" event="{{event}}">
</md-list>
<md-divider flex></md-divider>
</md-list-item>
</md-virtual-repeat-container>
</md-list>
</md-content>

23
ui/src/app/event/event-header-edge-event.tpl.html

@ -1,23 +0,0 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div translate class="tb-cell" flex="20">event.event-time</div>
<div translate class="tb-cell" flex="10">event.event-type</div>
<div translate class="tb-cell" flex="15">edge.event-action</div>
<div translate class="tb-cell" flex="30">edge.entity-id</div>
<div translate class="tb-cell" flex="15">edge.status</div>
<div translate class="tb-cell" flex="10">edge.entity-info</div>

4
ui/src/app/event/event-header.directive.js

@ -19,7 +19,6 @@ import eventHeaderLcEventTemplate from './event-header-lc-event.tpl.html';
import eventHeaderStatsTemplate from './event-header-stats.tpl.html'; import eventHeaderStatsTemplate from './event-header-stats.tpl.html';
import eventHeaderErrorTemplate from './event-header-error.tpl.html'; import eventHeaderErrorTemplate from './event-header-error.tpl.html';
import eventHeaderDebugRuleNodeTemplate from './event-header-debug-rulenode.tpl.html'; import eventHeaderDebugRuleNodeTemplate from './event-header-debug-rulenode.tpl.html';
import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html'
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
@ -46,9 +45,6 @@ export default function EventHeaderDirective($compile, $templateCache, types) {
case types.debugEventType.debugRuleChain.value: case types.debugEventType.debugRuleChain.value:
template = eventHeaderDebugRuleNodeTemplate; template = eventHeaderDebugRuleNodeTemplate;
break; break;
case types.edgeDownlinks.value:
template = edgeDownlinksHeaderTemplate;
break;
} }
return $templateCache.get(template); return $templateCache.get(template);
} }

84
ui/src/app/event/event-row.directive.js

@ -21,13 +21,12 @@ import eventRowLcEventTemplate from './event-row-lc-event.tpl.html';
import eventRowStatsTemplate from './event-row-stats.tpl.html'; import eventRowStatsTemplate from './event-row-stats.tpl.html';
import eventRowErrorTemplate from './event-row-error.tpl.html'; import eventRowErrorTemplate from './event-row-error.tpl.html';
import eventRowDebugRuleNodeTemplate from './event-row-debug-rulenode.tpl.html'; import eventRowDebugRuleNodeTemplate from './event-row-debug-rulenode.tpl.html';
import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html';
/* eslint-enable import/no-unresolved, import/default */ /* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/ /*@ngInject*/
export default function EventRowDirective($compile, $templateCache, $mdDialog, $document, $translate, export default function EventRowDirective($compile, $templateCache, $mdDialog, $document, $translate,
types, utils, toast, entityService, ruleChainService) { types, utils) {
var linker = function (scope, element, attrs) { var linker = function (scope, element, attrs) {
@ -49,9 +48,6 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $
case types.debugEventType.debugRuleChain.value: case types.debugEventType.debugRuleChain.value:
template = eventRowDebugRuleNodeTemplate; template = eventRowDebugRuleNodeTemplate;
break; break;
case types.edgeDownlinks.value:
template = edgeDownlinlsRowTemplate;
break;
} }
return $templateCache.get(template); return $templateCache.get(template);
} }
@ -98,85 +94,7 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $
}); });
} }
scope.showEdgeEntityContent = function($event, title, contentType) {
var onShowingCallback = {
onShowing: function(){}
}
if (!contentType) {
contentType = null;
}
var content = '';
switch(scope.event.type) {
case types.edgeEventType.relation:
content = angular.toJson(scope.event.body);
showDialog();
break;
case types.edgeEventType.ruleChainMetaData:
content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then(
function success(info) {
showDialog();
return angular.toJson(info);
}, function fail() {
showError();
});
break;
default:
content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then(
function success(info) {
showDialog();
return angular.toJson(info);
}, function fail() {
showError();
});
break;
}
function showDialog() {
$mdDialog.show({
controller: 'EventContentDialogController',
controllerAs: 'vm',
templateUrl: eventErrorDialogTemplate,
locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback},
parent: angular.element($document[0].body),
fullscreen: true,
targetEvent: $event,
multiple: true,
onShowing: function(scope, element) {
onShowingCallback.onShowing(scope, element);
}
});
}
function showError() {
toast.showError($translate.instant('edge.load-entity-error'));
}
}
scope.checkEdgeEventType = function (type) {
return !(type === types.edgeEventType.widgetType ||
type === types.edgeEventType.adminSettings ||
type === types.edgeEventType.widgetsBundle );
}
scope.checkTooltip = function($event) {
var el = $event.target;
var $el = angular.element(el);
if(el.offsetWidth < el.scrollWidth && !$el.attr('title')){
$el.attr('title', $el.text());
}
}
$compile(element.contents())(scope); $compile(element.contents())(scope);
scope.updateStatus = function(eventCreatedTime) {
var status;
if (eventCreatedTime < scope.queueStartTs) {
status = $translate.instant(types.edgeEventStatus.DEPLOYED.name);
scope.statusColor = types.edgeEventStatus.DEPLOYED.color;
} else {
status = $translate.instant(types.edgeEventStatus.PENDING.name);
scope.statusColor = types.edgeEventStatus.PENDING.color;
}
return status;
}
} }
return { return {

4
ui/src/app/event/event.scss

@ -85,10 +85,6 @@ md-list.tb-event-table {
} }
} }
.tb-edge-downlinks-table {
@extend .tb-event-table;
}
#tb-event-content { #tb-event-content {
width: 100%; width: 100%;
min-width: 400px; min-width: 400px;

2
ui/src/app/event/index.js

@ -19,7 +19,6 @@ import EventContentDialogController from './event-content-dialog.controller';
import EventHeaderDirective from './event-header.directive'; import EventHeaderDirective from './event-header.directive';
import EventRowDirective from './event-row.directive'; import EventRowDirective from './event-row.directive';
import EventTableDirective from './event-table.directive'; import EventTableDirective from './event-table.directive';
import EdgeDownlinksDirective from "./edge-downlinks-table.directive";
export default angular.module('thingsboard.event', [ export default angular.module('thingsboard.event', [
thingsboardApiEvent thingsboardApiEvent
@ -28,5 +27,4 @@ export default angular.module('thingsboard.event', [
.directive('tbEventHeader', EventHeaderDirective) .directive('tbEventHeader', EventHeaderDirective)
.directive('tbEventRow', EventRowDirective) .directive('tbEventRow', EventRowDirective)
.directive('tbEventTable', EventTableDirective) .directive('tbEventTable', EventTableDirective)
.directive('tbEdgeDownlinksTableOld', EdgeDownlinksDirective)
.name; .name;

Loading…
Cancel
Save