2019-08-22 18:44:48 +03:00
|
|
|
///
|
2020-02-20 10:26:43 +02:00
|
|
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
2019-08-22 18:44:48 +03:00
|
|
|
///
|
|
|
|
|
/// 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 {
|
|
|
|
|
DateEntityTableColumn,
|
|
|
|
|
EntityActionTableColumn,
|
|
|
|
|
EntityTableColumn,
|
|
|
|
|
EntityTableConfig
|
|
|
|
|
} from '@home/models/entity/entities-table-config.models';
|
2020-10-23 15:18:34 +03:00
|
|
|
import {
|
|
|
|
|
DebugEventType,
|
2020-11-04 12:11:22 +02:00
|
|
|
Event,
|
|
|
|
|
EventType,
|
2020-10-23 15:18:34 +03:00
|
|
|
EdgeEventType,
|
2020-11-05 16:52:37 +02:00
|
|
|
EdgeEventStatus,
|
2020-11-04 12:11:22 +02:00
|
|
|
edgeEventStatusColor
|
2020-10-23 15:18:34 +03:00
|
|
|
} from '@shared/models/event.models';
|
2020-10-21 21:11:17 +03:00
|
|
|
import {TimePageLink} from '@shared/models/page/page-link';
|
|
|
|
|
import {TranslateService} from '@ngx-translate/core';
|
|
|
|
|
import {DatePipe} from '@angular/common';
|
|
|
|
|
import {MatDialog} from '@angular/material/dialog';
|
|
|
|
|
import {EntityId} from '@shared/models/id/entity-id';
|
|
|
|
|
import {EventService} from '@app/core/http/event.service';
|
|
|
|
|
import {EventTableHeaderComponent} from '@home/components/event/event-table-header.component';
|
2020-10-22 08:57:18 +03:00
|
|
|
import {EntityType, EntityTypeResource} from '@shared/models/entity-type.models';
|
2020-10-21 21:11:17 +03:00
|
|
|
import {Observable} from 'rxjs';
|
|
|
|
|
import {PageData} from '@shared/models/page/page-data';
|
|
|
|
|
import {Direction} from '@shared/models/page/sort-order';
|
|
|
|
|
import {DialogService} from '@core/services/dialog.service';
|
|
|
|
|
import {ContentType} from '@shared/models/constants';
|
2020-01-22 20:05:30 +02:00
|
|
|
import {
|
|
|
|
|
EventContentDialogComponent,
|
|
|
|
|
EventContentDialogData
|
|
|
|
|
} from '@home/components/event/event-content-dialog.component';
|
2020-10-21 21:11:17 +03:00
|
|
|
import {sortObjectKeys} from '@core/utils';
|
2020-10-23 11:47:21 +03:00
|
|
|
import {RuleChainService} from "@core/http/rule-chain.service";
|
2020-10-23 15:18:34 +03:00
|
|
|
import {AttributeService} from "@core/http/attribute.service";
|
|
|
|
|
import {AttributeScope} from "@shared/models/telemetry/telemetry.models";
|
2019-08-22 18:44:48 +03:00
|
|
|
|
|
|
|
|
export class EventTableConfig extends EntityTableConfig<Event, TimePageLink> {
|
|
|
|
|
|
|
|
|
|
eventTypeValue: EventType | DebugEventType;
|
|
|
|
|
|
|
|
|
|
set eventType(eventType: EventType | DebugEventType) {
|
|
|
|
|
if (this.eventTypeValue !== eventType) {
|
|
|
|
|
this.eventTypeValue = eventType;
|
|
|
|
|
this.updateColumns(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get eventType(): EventType | DebugEventType {
|
|
|
|
|
return this.eventTypeValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eventTypes: Array<EventType | DebugEventType>;
|
2020-11-04 12:11:22 +02:00
|
|
|
queueStartTs: number;
|
2019-08-22 18:44:48 +03:00
|
|
|
|
|
|
|
|
constructor(private eventService: EventService,
|
|
|
|
|
private dialogService: DialogService,
|
|
|
|
|
private translate: TranslateService,
|
2020-10-23 11:47:21 +03:00
|
|
|
private ruleChainService: RuleChainService,
|
2020-10-23 15:18:34 +03:00
|
|
|
private attributeService: AttributeService,
|
2019-08-22 18:44:48 +03:00
|
|
|
private datePipe: DatePipe,
|
|
|
|
|
private dialog: MatDialog,
|
|
|
|
|
public entityId: EntityId,
|
|
|
|
|
public tenantId: string,
|
|
|
|
|
private defaultEventType: EventType | DebugEventType,
|
|
|
|
|
private disabledEventTypes: Array<EventType | DebugEventType> = null,
|
|
|
|
|
private debugEventTypes: Array<DebugEventType> = null) {
|
|
|
|
|
super();
|
|
|
|
|
this.loadDataOnInit = false;
|
|
|
|
|
this.tableTitle = '';
|
|
|
|
|
this.useTimePageLink = true;
|
|
|
|
|
this.detailsPanelEnabled = false;
|
|
|
|
|
this.selectionEnabled = false;
|
|
|
|
|
this.searchEnabled = false;
|
|
|
|
|
this.addEnabled = false;
|
|
|
|
|
this.entitiesDeleteEnabled = false;
|
|
|
|
|
|
|
|
|
|
this.headerComponent = EventTableHeaderComponent;
|
|
|
|
|
|
|
|
|
|
this.eventTypes = Object.keys(EventType).map(type => EventType[type]);
|
|
|
|
|
|
2020-10-22 08:57:18 +03:00
|
|
|
if (this.entityId.entityType !== EntityType.EDGE) {
|
|
|
|
|
this.eventTypes.pop();
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-22 18:44:48 +03:00
|
|
|
if (disabledEventTypes && disabledEventTypes.length) {
|
|
|
|
|
this.eventTypes = this.eventTypes.filter(type => disabledEventTypes.indexOf(type) === -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (debugEventTypes && debugEventTypes.length) {
|
|
|
|
|
this.eventTypes = [...this.eventTypes, ...debugEventTypes];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.eventTypeValue = defaultEventType;
|
|
|
|
|
|
|
|
|
|
this.entityTranslations = {
|
|
|
|
|
noEntities: 'event.no-events-prompt'
|
|
|
|
|
};
|
|
|
|
|
this.entityResources = {
|
2020-04-07 17:06:04 +03:00
|
|
|
} as EntityTypeResource<Event>;
|
2019-08-22 18:44:48 +03:00
|
|
|
this.entitiesFetchFunction = pageLink => this.fetchEvents(pageLink);
|
|
|
|
|
|
|
|
|
|
this.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
|
|
|
|
|
|
|
|
|
|
this.updateColumns();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fetchEvents(pageLink: TimePageLink): Observable<PageData<Event>> {
|
2020-10-21 21:11:17 +03:00
|
|
|
if (this.eventTypeValue === EventType.EDGE_EVENT) {
|
2020-10-23 15:18:34 +03:00
|
|
|
this.loadEdgeInfo();
|
2020-10-21 21:11:17 +03:00
|
|
|
return this.eventService.getEdgeEvents(this.entityId, pageLink);
|
|
|
|
|
} else {
|
|
|
|
|
return this.eventService.getEvents(this.entityId, this.eventType, this.tenantId, pageLink);
|
|
|
|
|
}
|
2019-08-22 18:44:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateColumns(updateTableColumns: boolean = false): void {
|
|
|
|
|
this.columns = [];
|
|
|
|
|
this.columns.push(
|
2020-01-24 19:05:41 +02:00
|
|
|
new DateEntityTableColumn<Event>('createdTime', 'event.event-time', this.datePipe, '120px'),
|
2020-10-22 12:25:43 +03:00
|
|
|
);
|
2020-10-23 11:47:21 +03:00
|
|
|
if (this.eventType !== EventType.EDGE_EVENT) {
|
|
|
|
|
this.columns.push(
|
|
|
|
|
new EntityTableColumn<Event>('server', 'event.server', '100px',
|
|
|
|
|
(entity) => entity.body.server, entity => ({}), false)
|
|
|
|
|
);
|
|
|
|
|
}
|
2019-08-22 18:44:48 +03:00
|
|
|
switch (this.eventType) {
|
|
|
|
|
case EventType.ERROR:
|
|
|
|
|
this.columns.push(
|
|
|
|
|
new EntityTableColumn<Event>('method', 'event.method', '100%',
|
|
|
|
|
(entity) => entity.body.method, entity => ({}), false),
|
|
|
|
|
new EntityActionTableColumn<Event>('error', 'event.error',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
|
|
|
|
isEnabled: (entity) => entity.body.error && entity.body.error.length > 0,
|
|
|
|
|
onAction: ($event, entity) => this.showContent($event, entity.body.error, 'event.error')
|
|
|
|
|
},
|
|
|
|
|
'100px')
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case EventType.LC_EVENT:
|
|
|
|
|
this.columns.push(
|
|
|
|
|
new EntityTableColumn<Event>('method', 'event.event', '100%',
|
|
|
|
|
(entity) => entity.body.event, entity => ({}), false),
|
|
|
|
|
new EntityTableColumn<Event>('status', 'event.status', '100%',
|
|
|
|
|
(entity) =>
|
|
|
|
|
this.translate.instant(entity.body.success ? 'event.success' : 'event.failed'), entity => ({}), false),
|
|
|
|
|
new EntityActionTableColumn<Event>('error', 'event.error',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
|
|
|
|
isEnabled: (entity) => entity.body.error && entity.body.error.length > 0,
|
|
|
|
|
onAction: ($event, entity) => this.showContent($event, entity.body.error, 'event.error')
|
|
|
|
|
},
|
|
|
|
|
'100px')
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case EventType.STATS:
|
|
|
|
|
this.columns.push(
|
2020-01-24 19:05:41 +02:00
|
|
|
new EntityTableColumn<Event>('messagesProcessed', 'event.messages-processed', '50%',
|
2019-08-22 18:44:48 +03:00
|
|
|
(entity) => entity.body.messagesProcessed + '',
|
2020-01-24 19:05:41 +02:00
|
|
|
() => ({}),
|
2019-08-22 18:44:48 +03:00
|
|
|
false,
|
2020-01-24 19:05:41 +02:00
|
|
|
() => ({}), () => undefined, true),
|
|
|
|
|
new EntityTableColumn<Event>('errorsOccurred', 'event.errors-occurred', '50%',
|
2019-08-22 18:44:48 +03:00
|
|
|
(entity) => entity.body.errorsOccurred + '',
|
2020-01-24 19:05:41 +02:00
|
|
|
() => ({}),
|
2019-08-22 18:44:48 +03:00
|
|
|
false,
|
2020-01-24 19:05:41 +02:00
|
|
|
() => ({}), () => undefined, true)
|
2019-08-22 18:44:48 +03:00
|
|
|
);
|
|
|
|
|
break;
|
2020-10-21 21:11:17 +03:00
|
|
|
case EventType.EDGE_EVENT:
|
|
|
|
|
this.columns.push(
|
|
|
|
|
new EntityTableColumn<Event>('type', 'event.type', '100%',
|
|
|
|
|
(entity) => entity.type, entity => ({}), false),
|
2020-10-22 12:25:43 +03:00
|
|
|
new EntityTableColumn<Event>('action', 'event.action', '100%',
|
|
|
|
|
(entity) => entity.action, entity => ({}), false),
|
|
|
|
|
new EntityTableColumn<Event>('entityId', 'event.entityId', '100%',
|
2020-10-23 11:47:21 +03:00
|
|
|
(entity) => entity.id.id, entity => ({}), false), //TODO: replace this to entity.entityId because of conflict wiht entityId model
|
2020-10-23 15:18:34 +03:00
|
|
|
new EntityTableColumn<Event>('status', 'event.status', '100%',
|
|
|
|
|
(entity) => this.updateEdgeEventStatus(entity.createdTime),
|
|
|
|
|
entity => ({
|
2020-11-05 16:52:37 +02:00
|
|
|
color: this.isPending(entity.createdTime) ? edgeEventStatusColor.get(EdgeEventStatus.PENDING) : edgeEventStatusColor.get(EdgeEventStatus.DEPLOYED)
|
2020-10-23 15:18:34 +03:00
|
|
|
}), false),
|
2020-10-23 11:47:21 +03:00
|
|
|
new EntityActionTableColumn<Event>('data', 'event.data',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
|
|
|
|
isEnabled: (entity) => this.checkEdgeEventType(entity),
|
|
|
|
|
onAction: ($event, entity) => this.showEdgeEventContent($event, this.manageEdgeEventContent(entity),
|
|
|
|
|
'event.data')
|
|
|
|
|
},
|
|
|
|
|
'40px'),
|
2020-10-22 12:25:43 +03:00
|
|
|
);
|
2020-10-21 21:11:17 +03:00
|
|
|
break;
|
2019-08-22 18:44:48 +03:00
|
|
|
case DebugEventType.DEBUG_RULE_NODE:
|
|
|
|
|
case DebugEventType.DEBUG_RULE_CHAIN:
|
2020-01-24 19:05:41 +02:00
|
|
|
this.columns[0].width = '100px';
|
2019-08-22 18:44:48 +03:00
|
|
|
this.columns.push(
|
2020-01-22 20:05:30 +02:00
|
|
|
new EntityTableColumn<Event>('type', 'event.type', '40px',
|
|
|
|
|
(entity) => entity.body.type, entity => ({
|
|
|
|
|
padding: '0 12px 0 0',
|
|
|
|
|
}), false, key => ({
|
|
|
|
|
padding: '0 12px 0 0'
|
|
|
|
|
})),
|
|
|
|
|
new EntityTableColumn<Event>('entity', 'event.entity', '100px',
|
|
|
|
|
(entity) => entity.body.entityName, entity => ({
|
|
|
|
|
padding: '0 12px 0 0',
|
|
|
|
|
}), false, key => ({
|
|
|
|
|
padding: '0 12px 0 0'
|
|
|
|
|
})),
|
2020-01-24 19:05:41 +02:00
|
|
|
new EntityTableColumn<Event>('msgId', 'event.message-id', '100px',
|
2020-01-22 20:05:30 +02:00
|
|
|
(entity) => entity.body.msgId, entity => ({
|
|
|
|
|
whiteSpace: 'nowrap',
|
2020-01-24 19:05:41 +02:00
|
|
|
padding: '0 12px 0 0'
|
2020-01-22 20:05:30 +02:00
|
|
|
}), false, key => ({
|
|
|
|
|
padding: '0 12px 0 0'
|
|
|
|
|
}),
|
|
|
|
|
entity => entity.body.msgId),
|
2020-01-24 19:05:41 +02:00
|
|
|
new EntityTableColumn<Event>('msgType', 'event.message-type', '100px',
|
2020-01-22 20:05:30 +02:00
|
|
|
(entity) => entity.body.msgType, entity => ({
|
|
|
|
|
whiteSpace: 'nowrap',
|
2020-01-24 19:05:41 +02:00
|
|
|
padding: '0 12px 0 0'
|
2020-01-22 20:05:30 +02:00
|
|
|
}), false, key => ({
|
|
|
|
|
padding: '0 12px 0 0'
|
|
|
|
|
}),
|
|
|
|
|
entity => entity.body.msgType),
|
|
|
|
|
new EntityTableColumn<Event>('relationType', 'event.relation-type', '100px',
|
2020-02-04 15:14:17 +02:00
|
|
|
(entity) => entity.body.relationType, entity => ({padding: '0 12px 0 0', }), false, key => ({
|
2020-01-22 20:05:30 +02:00
|
|
|
padding: '0 12px 0 0'
|
|
|
|
|
})),
|
2019-08-22 18:44:48 +03:00
|
|
|
new EntityActionTableColumn<Event>('data', 'event.data',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
2020-01-22 20:05:30 +02:00
|
|
|
isEnabled: (entity) => entity.body.data ? entity.body.data.length > 0 : false,
|
2019-08-22 18:44:48 +03:00
|
|
|
onAction: ($event, entity) => this.showContent($event, entity.body.data,
|
|
|
|
|
'event.data', entity.body.dataType)
|
|
|
|
|
},
|
2020-01-22 20:05:30 +02:00
|
|
|
'40px'),
|
2019-08-22 18:44:48 +03:00
|
|
|
new EntityActionTableColumn<Event>('metadata', 'event.metadata',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
2020-01-22 20:05:30 +02:00
|
|
|
isEnabled: (entity) => entity.body.metadata ? entity.body.metadata.length > 0 : false,
|
2019-08-22 18:44:48 +03:00
|
|
|
onAction: ($event, entity) => this.showContent($event, entity.body.metadata,
|
2020-08-11 17:43:19 +03:00
|
|
|
'event.metadata', ContentType.JSON, true)
|
2019-08-22 18:44:48 +03:00
|
|
|
},
|
2020-01-22 20:05:30 +02:00
|
|
|
'40px'),
|
2019-08-22 18:44:48 +03:00
|
|
|
new EntityActionTableColumn<Event>('error', 'event.error',
|
|
|
|
|
{
|
|
|
|
|
name: this.translate.instant('action.view'),
|
|
|
|
|
icon: 'more_horiz',
|
|
|
|
|
isEnabled: (entity) => entity.body.error && entity.body.error.length > 0,
|
|
|
|
|
onAction: ($event, entity) => this.showContent($event, entity.body.error,
|
|
|
|
|
'event.error')
|
|
|
|
|
},
|
2020-01-22 20:05:30 +02:00
|
|
|
'40px')
|
2019-08-22 18:44:48 +03:00
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (updateTableColumns) {
|
|
|
|
|
this.table.columnsUpdated(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-11 17:43:19 +03:00
|
|
|
showContent($event: MouseEvent, content: string, title: string, contentType: ContentType = null, sortKeys = false): void {
|
2019-08-22 18:44:48 +03:00
|
|
|
if ($event) {
|
|
|
|
|
$event.stopPropagation();
|
|
|
|
|
}
|
2020-08-11 17:43:19 +03:00
|
|
|
if (contentType === ContentType.JSON && sortKeys) {
|
|
|
|
|
try {
|
|
|
|
|
content = JSON.stringify(sortObjectKeys(JSON.parse(content)));
|
|
|
|
|
} catch (e) {}
|
2020-08-11 13:43:37 +03:00
|
|
|
}
|
2020-01-22 20:05:30 +02:00
|
|
|
this.dialog.open<EventContentDialogComponent, EventContentDialogData>(EventContentDialogComponent, {
|
|
|
|
|
disableClose: true,
|
|
|
|
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
|
|
|
|
data: {
|
2020-08-11 17:43:19 +03:00
|
|
|
content,
|
2020-01-22 20:05:30 +02:00
|
|
|
title,
|
|
|
|
|
contentType
|
|
|
|
|
}
|
|
|
|
|
});
|
2019-08-22 18:44:48 +03:00
|
|
|
}
|
2020-10-23 11:47:21 +03:00
|
|
|
|
|
|
|
|
checkEdgeEventType(entity) {
|
|
|
|
|
return !( entity.type === EdgeEventType.WIDGET_TYPE ||
|
|
|
|
|
entity.type === EdgeEventType.ADMIN_SETTINGS ||
|
|
|
|
|
entity.type === EdgeEventType.WIDGETS_BUNDLE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
manageEdgeEventContent(entity) {
|
2020-10-23 15:18:34 +03:00
|
|
|
var content: string;
|
2020-10-23 11:47:21 +03:00
|
|
|
switch (entity.type) {
|
|
|
|
|
case EdgeEventType.RELATION:
|
|
|
|
|
content = entity.body;
|
|
|
|
|
break;
|
|
|
|
|
// case EdgeEventType.RULE_CHAIN_METADATA:
|
|
|
|
|
// this.ruleChainService.getRuleChainMetadata(entity.entityId, null).pipe(
|
|
|
|
|
// map(ruleChainMetaData => content = ruleChainMetaData.nodes)
|
|
|
|
|
// );
|
|
|
|
|
// break;
|
|
|
|
|
default:
|
|
|
|
|
content = entity;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return JSON.stringify(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showEdgeEventContent($event: MouseEvent, content: string, title: string, sortKeys = false): void {
|
|
|
|
|
if ($event) {
|
|
|
|
|
$event.stopPropagation();
|
|
|
|
|
}
|
|
|
|
|
var contentType = ContentType.JSON;
|
|
|
|
|
if (contentType === ContentType.JSON && sortKeys) {
|
|
|
|
|
try {
|
|
|
|
|
content = JSON.stringify(sortObjectKeys(JSON.parse(content)));
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
this.dialog.open<EventContentDialogComponent, EventContentDialogData>(EventContentDialogComponent, {
|
|
|
|
|
disableClose: true,
|
|
|
|
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
|
|
|
|
data: {
|
|
|
|
|
content,
|
|
|
|
|
title,
|
|
|
|
|
contentType
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-10-23 15:18:34 +03:00
|
|
|
|
|
|
|
|
updateEdgeEventStatus(createdTime) {
|
2020-11-04 12:11:22 +02:00
|
|
|
if (this.queueStartTs && createdTime < this.queueStartTs) {
|
|
|
|
|
return this.translate.instant('edge.success');
|
|
|
|
|
} else {
|
|
|
|
|
return this.translate.instant('edge.failed');
|
2020-10-23 15:18:34 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isPending(createdTime) {
|
|
|
|
|
return createdTime > this.queueStartTs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
loadEdgeInfo() {
|
2020-11-04 12:11:22 +02:00
|
|
|
this.attributeService.getEntityAttributes(this.entityId, AttributeScope.SERVER_SCOPE, ['queueStartTs'])
|
2020-10-23 15:18:34 +03:00
|
|
|
.subscribe(
|
|
|
|
|
attributes => this.onUpdate(attributes)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onUpdate(attributes) {
|
2020-11-04 12:11:22 +02:00
|
|
|
this.queueStartTs = 0;
|
2020-10-23 15:18:34 +03:00
|
|
|
let edge = attributes.reduce(function (map, attribute) {
|
|
|
|
|
map[attribute.key] = attribute;
|
|
|
|
|
return map;
|
|
|
|
|
}, {});
|
|
|
|
|
if (edge.queueStartTs) {
|
|
|
|
|
this.queueStartTs = edge.queueStartTs.lastUpdateTs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-22 18:44:48 +03:00
|
|
|
}
|
2020-10-23 15:18:34 +03:00
|
|
|
|