20 changed files with 81 additions and 563 deletions
@ -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> |
|||
|
|||
|
|||
@ -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: '=' |
|||
} |
|||
}; |
|||
} |
|||
@ -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> |
|||
@ -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> |
|||
Loading…
Reference in new issue