diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index 8777cc9780..b5b2b0e796 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -169,6 +169,8 @@ export class EntityService { case EntityType.QUEUE: observable = this.queueService.getQueueById(entityId, config); break; + case EntityType.QUEUE_STATS: + observable = this.queueService.getQueueStatisticsById(entityId, config); } return observable; } @@ -267,6 +269,9 @@ export class EntityService { case EntityType.NOTIFICATION_TARGET: observable = this.notificationService.getNotificationTargetsByIds(entityIds, config); break; + case EntityType.QUEUE_STATS: + observable = this.queueService.getQueueStatisticsByIds(entityIds, config); + break; } return observable; } @@ -444,6 +449,9 @@ export class EntityService { pageLink.sortOrder.property = 'title'; entitiesObservable = this.resourceService.getTenantResources(pageLink, config); break; + case EntityType.QUEUE_STATS: + pageLink.sortOrder.property = 'createdTime'; + entitiesObservable = this.queueService.getQueueStatistics(pageLink, config); } return entitiesObservable; } @@ -716,11 +724,12 @@ export class EntityService { entityTypes.push(EntityType.CUSTOMER); entityTypes.push(EntityType.USER); entityTypes.push(EntityType.DASHBOARD); - entityTypes.push(EntityType.QUEUE_STATS); if (authState.edgesSupportEnabled) { entityTypes.push(EntityType.EDGE); } if (useAliasEntityTypes) { + entityTypes.push(EntityType.QUEUE_STATS); + entityTypes.push(AliasEntityType.CURRENT_CUSTOMER); entityTypes.push(AliasEntityType.CURRENT_TENANT); } diff --git a/ui-ngx/src/app/core/http/queue.service.ts b/ui-ngx/src/app/core/http/queue.service.ts index b300a1c0a7..ed2a189e0d 100644 --- a/ui-ngx/src/app/core/http/queue.service.ts +++ b/ui-ngx/src/app/core/http/queue.service.ts @@ -18,9 +18,10 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils'; import { Observable } from 'rxjs'; -import { QueueInfo, ServiceType } from '@shared/models/queue.models'; +import { QueueInfo, QueueStatisticsInfo, ServiceType } from '@shared/models/queue.models'; import { PageLink } from '@shared/models/page/page-link'; import { PageData } from '@shared/models/page/page-data'; +import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -53,4 +54,31 @@ export class QueueService { public deleteQueue(queueId: string) { return this.http.delete(`/api/queues/${queueId}`); } + + private parseQueueStatName = (queueStat: QueueStatisticsInfo) => Object.defineProperty(queueStat, 'name', { + get() { return `${this.queueName} (${this.serviceId})`; } + }); + + public getQueueStatistics(pageLink: PageLink, config?: RequestConfig): Observable> { + return this.http.get>(`/api/queueStats${pageLink.toQuery()}`, + defaultHttpOptionsFromConfig(config)).pipe( + map(queueData => { + queueData.data.map(queueStat => this.parseQueueStatName(queueStat)); + return queueData; + }) + ); + } + + public getQueueStatisticsById(queueStatId: string, config?: RequestConfig): Observable { + return this.http.get(`/api/queueStats/${queueStatId}`, defaultHttpOptionsFromConfig(config)).pipe( + map(queueStat => this.parseQueueStatName(queueStat))); + } + + public getQueueStatisticsByIds(queueStatIds: Array, config?: RequestConfig): Observable> { + return this.http.get>(`/api/queueStats?QueueStatsIds=${queueStatIds.join(',')}`, + defaultHttpOptionsFromConfig(config)).pipe( + map(queueStats => queueStats.map(queueStat => this.parseQueueStatName(queueStat)) + ) + ); + } } diff --git a/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html b/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html index 61d22dcff4..d1b39a8748 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.html @@ -37,7 +37,8 @@ @@ -65,7 +67,8 @@ diff --git a/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.ts b/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.ts index 0bc19aff01..31b31960f8 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.ts +++ b/ui-ngx/src/app/modules/home/components/entity/entity-filter.component.ts @@ -50,6 +50,8 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit, OnDe aliasFilterTypes: Array; + listEntityTypes: Array; + aliasFilterType = AliasFilterType; aliasFilterTypeTranslations = aliasFilterTypeTranslationMap; entityType = EntityType; @@ -71,6 +73,11 @@ export class EntityFilterComponent implements ControlValueAccessor, OnInit, OnDe this.aliasFilterTypes = this.entityService.getAliasFilterTypesByEntityTypes(this.allowedEntityTypes); + this.listEntityTypes = this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, false); + if (!this.allowedEntityTypes?.length || this.allowedEntityTypes.includes(EntityType.QUEUE_STATS)) { + this.listEntityTypes.push(EntityType.QUEUE_STATS); + } + this.entityFilterFormGroup = this.fb.group({ type: [null, [Validators.required]] }); diff --git a/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts b/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts index 9792d9f1e9..8703e0a10b 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts +++ b/ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts @@ -249,6 +249,11 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit this.noEntitiesMatchingText = 'alarm.no-alarms-matching'; this.entityRequiredText = 'alarm.alarm-required'; break; + case EntityType.QUEUE_STATS: + this.entityText = 'queue-statistics.queue-statistics'; + this.noEntitiesMatchingText = 'queue-statistics.no-queue-statistics-matching'; + this.entityRequiredText = 'queue-statistics.queue-statistics-required'; + break; case AliasEntityType.CURRENT_CUSTOMER: this.entityText = 'customer.default-customer'; this.noEntitiesMatchingText = 'customer.no-customers-matching'; diff --git a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts index 1bd2861b70..04754e4a20 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts +++ b/ui-ngx/src/app/shared/components/entity/entity-type-select.component.ts @@ -90,8 +90,9 @@ export class EntityTypeSelectComponent implements ControlValueAccessor, OnInit, } ngOnInit() { - this.entityTypes = this.filterAllowedEntityTypes ? - this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, this.useAliasEntityTypes) : this.allowedEntityTypes; + this.entityTypes = this.filterAllowedEntityTypes + ? this.entityService.prepareAllowedEntityTypesList(this.allowedEntityTypes, this.useAliasEntityTypes) + : this.allowedEntityTypes; this.entityTypeFormGroup.get('entityType').valueChanges.subscribe( (value) => { let modelValue; diff --git a/ui-ngx/src/app/shared/models/entity-type.models.ts b/ui-ngx/src/app/shared/models/entity-type.models.ts index 885ea90929..045e95983c 100644 --- a/ui-ngx/src/app/shared/models/entity-type.models.ts +++ b/ui-ngx/src/app/shared/models/entity-type.models.ts @@ -367,7 +367,11 @@ export const entityTypeTranslations = new Map, HasTenantId { duplicateMsgToAllPartitions?: boolean; }; } + +export interface QueueStatisticsInfo extends Omit, 'label'>, HasTenantId { + queueName: string; + serviceId: string; +} diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index f1b22dedc6..05256211f8 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4328,6 +4328,15 @@ "retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack" } }, + "queue-statistics": { + "queue-statistics": "Queue statistics", + "no-queue-statistics-matching": "No queue statistics matching '{{entity}}' were found.", + "queue-statistics-required": "Queue statistics is required.", + "list-of-queue-statistics": "{ count, plural, =1 {One queue statistic} other {List of # queue statistics} }", + "selected-queue-statistics": "{ count, plural, =1 {1 queue statistic} other {# queue statistics} } selected", + "no-queue-statistics-text": "No queue statistics found", + "queue-statistics-starts-with": "Queue statistics whose names start with '{{prefix}}'" + }, "server-error": { "general": "General server error", "authentication": "Authentication error",