diff --git a/ui-ngx/src/app/modules/home/components/profile/queue/tenant-profile-queues.component.html b/ui-ngx/src/app/modules/home/components/profile/queue/tenant-profile-queues.component.html index 9339438726..b755e02d8b 100644 --- a/ui-ngx/src/app/modules/home/components/profile/queue/tenant-profile-queues.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/queue/tenant-profile-queues.component.html @@ -20,12 +20,26 @@ *ngFor="let queuesControl of queuesFormArray.controls; trackBy: trackByQueue; let $index = index; last as isLast;" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}"> - - + + +
+ + {{ queuesControl.value.name }} + + + +
+
+ + + +
{ - this.updateModel(); - }); + this.valueChangeSubscription$ = this.tenantProfileQueuesFormGroup.valueChanges.subscribe(() => + this.updateModel() + ); } public trackByQueue(index: number, queueControl: AbstractControl) { @@ -183,10 +183,6 @@ export class TenantProfileQueuesComponent implements ControlValueAccessor, Valid }; } - getName(value) { - return this.utils.customTranslation(value, value); - } - private updateModel() { const queues: Array = this.tenantProfileQueuesFormGroup.get('queues').value; this.propagateChange(queues); diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.ts index ed88fe9fba..413055fede 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile.component.ts @@ -109,7 +109,9 @@ export class TenantProfileComponent extends EntityComponent { this.entityForm.patchValue({name: entity.name}, {emitEvent: false}); this.entityForm.patchValue({isolatedTbCore: entity.isolatedTbCore}, {emitEvent: false}); this.entityForm.patchValue({isolatedTbRuleEngine: entity.isolatedTbRuleEngine}, {emitEvent: false}); - this.entityForm.get('profileData').patchValue({configuration: entity.profileData?.configuration}, {emitEvent: false}); + this.entityForm.get('profileData').patchValue({ + configuration: !this.isAdd ? entity.profileData?.configuration : createTenantProfileConfiguration(TenantProfileType.DEFAULT) + }, {emitEvent: false}); this.entityForm.get('profileData').patchValue({queueConfiguration: entity.profileData?.queueConfiguration}, {emitEvent: false}); this.entityForm.patchValue({description: entity.description}, {emitEvent: false}); } diff --git a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html index 920ad2f162..5dee2afa87 100644 --- a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html +++ b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html @@ -15,182 +15,165 @@ limitations under the License. --> - - -
- - {{ queueTitle }} - - - -
-
- -
- - admin.queue-name - - - {{ 'queue.name-required' | translate }} - - - {{ 'queue.name-unique' | translate }} - - - - queue.poll-interval - - - {{ 'queue.poll-interval-required' | translate }} - - - {{ 'queue.poll-interval-min-value' | translate }} - - - - queue.partitions - - - {{ 'queue.partitions-required' | translate }} - - - {{ 'queue.partitions-min-value' | translate }} - - - -
{{ 'queue.consumer-per-partition' | translate }}
-
{{'queue.consumer-per-partition-hint' | translate}}
-
- - queue.processing-timeout - - - {{ 'queue.pack-processing-timeout-required' | translate }} - - - {{ 'queue.pack-processing-timeout-min-value' | translate }} - - - - - - - queue.submit-strategy - - - -
- - queue.submit-strategy - - - {{ strategy }} - - - - {{ 'queue.submit-strategy-type-required' | translate }} - - - - queue.batch-size - - - {{ 'queue.batch-size-required' | translate }} - - - {{ 'queue.batch-size-min-value' | translate }} - - -
-
-
- - - - queue.processing-strategy - - - -
- - queue.processing-strategy - - - {{ strategy }} - - - - {{ 'queue.processing-strategy-type-required' | translate }} - - - - queue.retries - - - {{ 'queue.retries-required' | translate }} - - - {{ 'queue.retries-min-value' | translate }} - - - - queue.failure-percentage - - - {{ 'queue.failure-percentage-required' | translate }} - - - {{ 'queue.failure-percentage-min-value' | translate }} - - - {{ 'queue.failure-percentage-max-value' | translate }} - - - - queue.pause-between-retries - - - {{ 'queue.pause-between-retries-required' | translate }} - - - {{ 'queue.pause-between-retries-min-value' | translate }} - - - - queue.max-pause-between-retries - - - {{ 'queue.max-pause-between-retries-required' | translate }} - - - {{ 'queue.max-pause-between-retries-min-value' | translate }} - - -
-
-
-
- - queue.description - - -
-
-
+ +
+ + admin.queue-name + + + {{ 'queue.name-required' | translate }} + + + {{ 'queue.name-unique' | translate }} + + + + queue.poll-interval + + + {{ 'queue.poll-interval-required' | translate }} + + + {{ 'queue.poll-interval-min-value' | translate }} + + + + queue.partitions + + + {{ 'queue.partitions-required' | translate }} + + + {{ 'queue.partitions-min-value' | translate }} + + + +
{{ 'queue.consumer-per-partition' | translate }}
+
{{'queue.consumer-per-partition-hint' | translate}}
+
+ + queue.processing-timeout + + + {{ 'queue.pack-processing-timeout-required' | translate }} + + + {{ 'queue.pack-processing-timeout-min-value' | translate }} + + + + + + + queue.submit-strategy + + + +
+ + queue.submit-strategy + + + {{ queueSubmitStrategyTypesMap.get(queueSubmitStrategyTypes[strategy]).label | translate }} + + + + {{ 'queue.submit-strategy-type-required' | translate }} + + + + queue.batch-size + + + {{ 'queue.batch-size-required' | translate }} + + + {{ 'queue.batch-size-min-value' | translate }} + + +
+
+
+ + + + queue.processing-strategy + + + +
+ + queue.processing-strategy + + + {{ queueProcessingStrategyTypesMap.get(queueProcessingStrategyTypes[strategy]).label | translate }} + + + + {{ 'queue.processing-strategy-type-required' | translate }} + + + + queue.retries + + + {{ 'queue.retries-required' | translate }} + + + {{ 'queue.retries-min-value' | translate }} + + + + queue.failure-percentage + + + {{ 'queue.failure-percentage-required' | translate }} + + + {{ 'queue.failure-percentage-min-value' | translate }} + + + {{ 'queue.failure-percentage-max-value' | translate }} + + + + queue.pause-between-retries + + + {{ 'queue.pause-between-retries-required' | translate }} + + + {{ 'queue.pause-between-retries-min-value' | translate }} + + + + queue.max-pause-between-retries + + + {{ 'queue.max-pause-between-retries-required' | translate }} + + + {{ 'queue.max-pause-between-retries-min-value' | translate }} + + +
+
+
+
+ + queue.description + + queue.description-hint + +
diff --git a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts index 6a437799b5..cb2cf06b88 100644 --- a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts +++ b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit, Output, EventEmitter, OnDestroy } from '@angular/core'; +import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; import { ControlValueAccessor, FormBuilder, @@ -25,9 +25,14 @@ import { Validator, Validators } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; import { UtilsService } from '@core/services/utils.service'; -import { QueueInfo, QueueProcessingStrategyTypes, QueueSubmitStrategyTypes } from '@shared/models/queue.models'; +import { + QueueInfo, + QueueProcessingStrategyTypes, + QueueProcessingStrategyTypesMap, + QueueSubmitStrategyTypes, + QueueSubmitStrategyTypesMap +} from '@shared/models/queue.models'; import { isDefinedAndNotNull } from '@core/utils'; import { Subscription } from 'rxjs'; @@ -56,31 +61,25 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr @Input() newQueue = false; - @Input() - mainQueue = false; - @Input() systemQueue = false; - @Input() - expanded = false; - - @Output() - removeQueue = new EventEmitter(); - queueFormGroup: FormGroup; - submitStrategies: string[] = []; - processingStrategies: string[] = []; - queueTitle = ''; hideBatchSize = false; + queueSubmitStrategyTypes = QueueSubmitStrategyTypes; + queueProcessingStrategyTypes = QueueProcessingStrategyTypes; + submitStrategies: string[] = Object.values(this.queueSubmitStrategyTypes); + processingStrategies: string[] = Object.values(this.queueProcessingStrategyTypes); + queueSubmitStrategyTypesMap = QueueSubmitStrategyTypesMap; + queueProcessingStrategyTypesMap = QueueProcessingStrategyTypesMap; + private modelValue: QueueInfo; private propagateChange = null; private propagateChangePending = false; private valueChange$: Subscription = null; - constructor(private dialog: MatDialog, - private utils: UtilsService, + constructor(private utils: UtilsService, private fb: FormBuilder) { } @@ -98,8 +97,6 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr } ngOnInit() { - this.submitStrategies = Object.values(QueueSubmitStrategyTypes); - this.processingStrategies = Object.values(QueueProcessingStrategyTypes); this.queueFormGroup = this.fb.group( { name: ['', [Validators.required]], @@ -128,7 +125,6 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr }); this.queueFormGroup.get('name').valueChanges.subscribe((value) => { this.queueFormGroup.patchValue({topic: `tb_rule_engine.${value}`}); - this.queueTitle = this.utils.customTranslation(value, value); }); this.queueFormGroup.get('submitStrategy').get('type').valueChanges.subscribe(() => { this.submitStrategyTypeChanged(); @@ -160,14 +156,13 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr writeValue(value: QueueInfo): void { this.propagateChangePending = false; this.modelValue = value; - if (!this.modelValue.name) { - this.expanded = true; - } - this.queueTitle = this.utils.customTranslation(value.name, value.name); if (isDefinedAndNotNull(this.modelValue)) { this.queueFormGroup.patchValue(this.modelValue, {emitEvent: false}); + this.submitStrategyTypeChanged(); + if (!this.modelValue.name) { + this.queueFormGroup.get('name').enable({emitEvent: false}); + } } - this.submitStrategyTypeChanged(); if (!this.disabled && !this.queueFormGroup.valid) { this.updateModel(); } @@ -209,13 +204,11 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr const type: QueueSubmitStrategyTypes = form.get('type').value; const batchSizeField = form.get('batchSize'); if (type === QueueSubmitStrategyTypes.BATCH) { - batchSizeField.enable({emitEvent: false}); batchSizeField.patchValue(1000, {emitEvent: false}); batchSizeField.setValidators([Validators.min(1), Validators.required]); this.hideBatchSize = true; } else { batchSizeField.patchValue(null, {emitEvent: false}); - batchSizeField.disable({emitEvent: false}); batchSizeField.clearValidators(); this.hideBatchSize = false; } diff --git a/ui-ngx/src/app/modules/home/pages/tenant-profile/tenant-profiles-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/tenant-profile/tenant-profiles-table-config.resolver.ts index 7484d8b403..d9f7efc602 100644 --- a/ui-ngx/src/app/modules/home/pages/tenant-profile/tenant-profiles-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/tenant-profile/tenant-profiles-table-config.resolver.ts @@ -101,12 +101,15 @@ export class TenantProfilesTableConfigResolver implements Resolve { - value.id = guid(); - queuesWithId.push(value); - }); - return queuesWithId; + if (queues) { + const queuesWithId = []; + queues.forEach(value => { + value.id = guid(); + queuesWithId.push(value); + }); + return queuesWithId; + } + return null; } resolve(): EntityTableConfig { diff --git a/ui-ngx/src/app/shared/models/queue.models.ts b/ui-ngx/src/app/shared/models/queue.models.ts index 6c67b4db1b..dc90781d30 100644 --- a/ui-ngx/src/app/shared/models/queue.models.ts +++ b/ui-ngx/src/app/shared/models/queue.models.ts @@ -14,9 +14,9 @@ /// limitations under the License. /// -import { BaseData, HasId } from '@shared/models/base-data'; +import { BaseData } from '@shared/models/base-data'; import { TenantId } from '@shared/models/id/tenant-id'; -import {QueueId} from '@shared/models/id/queue-id'; +import { QueueId } from '@shared/models/id/queue-id'; export enum ServiceType { TB_CORE = 'TB_CORE', @@ -33,6 +33,35 @@ export enum QueueSubmitStrategyTypes { BATCH = 'BATCH' } +export interface QueueStrategyData { + label: string; + hint: string; +} + +export const QueueSubmitStrategyTypesMap = new Map( + [ + [QueueSubmitStrategyTypes.SEQUENTIAL_BY_ORIGINATOR, { + label: 'queue.strategies.sequential-by-originator-label', + hint: 'queue.strategies.sequential-by-originator-hint', + }], + [QueueSubmitStrategyTypes.SEQUENTIAL_BY_TENANT, { + label: 'queue.strategies.sequential-by-tenant-label', + hint: 'queue.strategies.sequential-by-tenant-hint', + }], + [QueueSubmitStrategyTypes.SEQUENTIAL, { + label: 'queue.strategies.sequential-label', + hint: 'queue.strategies.sequential-hint', + }], + [QueueSubmitStrategyTypes.BURST, { + label: 'queue.strategies.burst-label', + hint: 'queue.strategies.burst-hint', + }], + [QueueSubmitStrategyTypes.BATCH, { + label: 'queue.strategies.batch-label', + hint: 'queue.strategies.batch-hint', + }] + ]); + export enum QueueProcessingStrategyTypes { RETRY_FAILED_AND_TIMED_OUT = 'RETRY_FAILED_AND_TIMED_OUT', SKIP_ALL_FAILURES = 'SKIP_ALL_FAILURES', @@ -42,6 +71,34 @@ export enum QueueProcessingStrategyTypes { RETRY_TIMED_OUT = 'RETRY_TIMED_OUT' } +export const QueueProcessingStrategyTypesMap = new Map( + [ + [QueueProcessingStrategyTypes.RETRY_FAILED_AND_TIMED_OUT, { + label: 'queue.strategies.retry-failed-and-timeout-label', + hint: 'queue.strategies.retry-failed-and-timout-hint', + }], + [QueueProcessingStrategyTypes.SKIP_ALL_FAILURES, { + label: 'queue.strategies.skip-all-failures-label', + hint: 'queue.strategies.skip-all-failures-hint', + }], + [QueueProcessingStrategyTypes.SKIP_ALL_FAILURES_AND_TIMED_OUT, { + label: 'queue.strategies.skip-all-failures-and-timeouts-label', + hint: 'queue.strategies.skip-all-failures-and-timeouts-hint', + }], + [QueueProcessingStrategyTypes.RETRY_ALL, { + label: 'queue.strategies.retry-all-label', + hint: 'queue.strategies.retry-all-hint', + }], + [QueueProcessingStrategyTypes.RETRY_FAILED, { + label: 'queue.strategies.retry-failed-label', + hint: 'queue.strategies.retry-failed-hint', + }], + [QueueProcessingStrategyTypes.RETRY_TIMED_OUT, { + label: 'queue.strategies.retry-timeout-label', + hint: 'queue.strategies.retry-timeout-hint', + }] + ]); + export interface QueueInfo extends BaseData { generatedId?: string; name: 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 ff1f85b1f0..12d35b6e0f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2821,7 +2821,32 @@ "copyId": "Copy queue Id", "idCopiedMessage": "Queue Id has been copied to clipboard", "description": "Description", - "alt-description": "Submit Strategy: {{submitStrategy}}, Processing Strategy: {{processingStrategy}}" + "description-hint": "This text will be displayed in the Queue description instead of the selected strategy", + "alt-description": "Submit Strategy: {{submitStrategy}}, Processing Strategy: {{processingStrategy}}", + "strategies": { + "sequential-by-originator-label": "Sequential by originator", + "sequential-by-originator-hint": "New message for e.g. device A is not submitted until previous message for device A is acknowledged", + "sequential-by-tenant-label": "Sequential by tenant", + "sequential-by-tenant-hint": "New message for e.g tenant A is not submitted until previous message for tenant A is acknowledged", + "sequential-label": "Sequential", + "sequential-hint": "New message is not submitted until previous message is acknowledged", + "burst-label": "Burst", + "burst-hint": "All messages are submitted to the rule chains in the order they arrive", + "batch-label": "Batch", + "batch-hint": "New batch is not submitted until previous batch is acknowledged", + "skip-all-failures-label": "Skip all failures", + "skip-all-failures-hint": "Ignore all failures", + "skip-all-failures-and-timeouts-label": "Skip all failures and timeouts", + "skip-all-failures-and-timeouts-hint": "Ignore all failures and timeouts", + "retry-all-label": "Retry all", + "retry-all-hint": "Retry all messages from processing pack", + "retry-failed-label": "Retry failed", + "retry-failed-hint": "Retry all failed messages from processing pack", + "retry-timeout-label": "Retry timeout", + "retry-timeout-hint": "Retry all timed-out messages from processing pack", + "retry-failed-and-timeout-label": "Retry failed and timeout", + "retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack" + } }, "tenant": { "tenant": "Tenant",