From 17277284395f2bc4d70f74cdfeb7685eff4d86ff Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Fri, 5 Jan 2024 11:36:01 +0200 Subject: [PATCH] UI: Added queue for rule node --- .../rule-node-details.component.html | 22 ++++-- .../rulechain/rule-node-details.component.ts | 69 ++++++++++++++++--- .../rulechain/rulechain-page.component.ts | 7 +- .../models/component-descriptor.models.ts | 1 + .../src/app/shared/models/rule-node.models.ts | 2 + .../assets/locale/locale.constant-en_US.json | 4 +- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html index cf798bf33b..03d20eaca4 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.html @@ -38,7 +38,7 @@ {{ 'rulenode.debug-mode' | translate }} - + {{ 'rulenode.singleton-mode' | translate }} @@ -52,10 +52,20 @@ (initRuleNode)="initRuleNode.emit($event)" (changeScript)="changeScript.emit($event)"> -
- - rulenode.rule-node-description - - + +
+ + +
+ + rulenode.rule-node-description + + +
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts index 5fce7f8e0b..dcd7655429 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.ts @@ -14,26 +14,38 @@ /// limitations under the License. /// -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, + SimpleChanges, + ViewChild +} from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models'; import { EntityType } from '@shared/models/entity-type.models'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; import { RuleNodeConfigComponent } from './rule-node-config.component'; import { Router } from '@angular/router'; import { RuleChainType } from '@app/shared/models/rule-chain.models'; import { ComponentClusteringMode } from '@shared/models/component-descriptor.models'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { ServiceType } from '@shared/models/queue.models'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'tb-rule-node', templateUrl: './rule-node-details.component.html', styleUrls: ['./rule-node-details.component.scss'] }) -export class RuleNodeDetailsComponent extends PageComponent implements OnInit, OnChanges { +export class RuleNodeDetailsComponent extends PageComponent implements OnInit, OnChanges, OnDestroy { @ViewChild('ruleNodeConfigComponent') ruleNodeConfigComponent: RuleNodeConfigComponent; @@ -63,9 +75,11 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O ruleNodeType = RuleNodeType; entityType = EntityType; + serviceType = ServiceType.TB_RULE_ENGINE; + ruleNodeFormGroup: UntypedFormGroup; - private ruleNodeFormSubscription: Subscription; + private destroy$ = new Subject(); constructor(protected store: Store, private fb: UntypedFormBuilder, @@ -75,10 +89,6 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } private buildForm() { - if (this.ruleNodeFormSubscription) { - this.ruleNodeFormSubscription.unsubscribe(); - this.ruleNodeFormSubscription = null; - } if (this.ruleNode) { this.ruleNodeFormGroup = this.fb.group({ name: [this.ruleNode.name, [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*'), Validators.maxLength(255)]], @@ -91,9 +101,32 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } ) }); - this.ruleNodeFormSubscription = this.ruleNodeFormGroup.valueChanges.subscribe(() => { - this.updateRuleNode(); - }); + + if (this.isAddQueue()) { + this.ruleNodeFormGroup.addControl('queueName', this.fb.control(this.ruleNode?.queueName ? this.ruleNode.queueName : null)); + if (this.isSingleton()) { + if (!this.isSingletonEditAllowed()) { + this.ruleNodeFormGroup.get('singletonMode').disable({emitEvent: false}); + } + if (!this.ruleNodeFormGroup.get('singletonMode').value) { + this.ruleNodeFormGroup.get('queueName').disable({emitEvent: false}); + } + this.ruleNodeFormGroup.get('singletonMode').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(value => { + if (value) { + this.ruleNodeFormGroup.get('queueName').enable({emitEvent: false}); + } else { + this.ruleNodeFormGroup.get('queueName').disable({emitEvent: false}); + } + }); + } + } + + this.ruleNodeFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => this.updateRuleNode()); + } else { this.ruleNodeFormGroup = this.fb.group({}); } @@ -114,6 +147,11 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } } + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + ngOnChanges(changes: SimpleChanges): void { for (const propName of Object.keys(changes)) { const change = changes[propName]; @@ -143,6 +181,15 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O } } + isAddQueue() { + return this.isSingleton() || this.ruleNode.component.hasQueueName; + } + + isSingleton() { + return this.ruleNode.component.clusteringMode === ComponentClusteringMode.SINGLETON || + this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE; + } + isSingletonEditAllowed() { return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE; } diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 6f657f26c3..bea5fdc502 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -575,6 +575,7 @@ export class RuleChainPageComponent extends PageComponent configurationVersion: isDefinedAndNotNull(ruleNode.configurationVersion) ? ruleNode.configurationVersion : 0, debugMode: ruleNode.debugMode, singletonMode: ruleNode.singletonMode, + queueName: ruleNode.queueName, x: Math.round(ruleNode.additionalInfo.layoutX), y: Math.round(ruleNode.additionalInfo.layoutY), component, @@ -934,7 +935,8 @@ export class RuleChainPageComponent extends PageComponent configuration: deepClone(node.configuration), additionalInfo: node.additionalInfo ? deepClone(node.additionalInfo) : {}, debugMode: node.debugMode, - singletonMode: node.singletonMode + singletonMode: node.singletonMode, + queueName: node.queueName }; if (minX === null) { minX = node.x; @@ -1467,7 +1469,8 @@ export class RuleChainPageComponent extends PageComponent configuration: node.configuration, additionalInfo: node.additionalInfo ? node.additionalInfo : {}, debugMode: node.debugMode, - singletonMode: node.singletonMode + singletonMode: node.singletonMode, + queueName: node.queueName }; ruleNode.additionalInfo.layoutX = Math.round(node.x); ruleNode.additionalInfo.layoutY = Math.round(node.y); diff --git a/ui-ngx/src/app/shared/models/component-descriptor.models.ts b/ui-ngx/src/app/shared/models/component-descriptor.models.ts index 3ce15d15aa..35cdee95da 100644 --- a/ui-ngx/src/app/shared/models/component-descriptor.models.ts +++ b/ui-ngx/src/app/shared/models/component-descriptor.models.ts @@ -40,6 +40,7 @@ export interface ComponentDescriptor { type: ComponentType | RuleNodeType; scope?: ComponentScope; clusteringMode: ComponentClusteringMode; + hasQueueName?: boolean; name: string; clazz: string; configurationDescriptor?: any; diff --git a/ui-ngx/src/app/shared/models/rule-node.models.ts b/ui-ngx/src/app/shared/models/rule-node.models.ts index 4a40944c67..20cb4418b9 100644 --- a/ui-ngx/src/app/shared/models/rule-node.models.ts +++ b/ui-ngx/src/app/shared/models/rule-node.models.ts @@ -39,6 +39,7 @@ export interface RuleNode extends BaseData { name: string; debugMode: boolean; singletonMode: boolean; + queueName?: string; configurationVersion?: number; configuration: RuleNodeConfiguration; additionalInfo?: any; @@ -334,6 +335,7 @@ export interface RuleNodeComponentDescriptor extends ComponentDescriptor { export interface FcRuleNodeType extends FcNode { component?: RuleNodeComponentDescriptor; singletonMode?: boolean; + queueName?: string; nodeClass?: string; icon?: string; iconUrl?: 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 1904cb796f..bf959462d2 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3841,7 +3841,9 @@ "test": "Test", "help": "Help", "reset-debug-mode": "Reset debug mode in all nodes", - "test-with-this-message": "{{test}} with this message" + "test-with-this-message": "{{test}} with this message", + "queue-hint": "Select a queue for message forwarding to another queue. 'Main' queue is used by default.", + "queue-singleton-hint": "Select a queue for message forwarding in multi-instance environments. 'Main' queue is used by default." }, "timezone": { "timezone": "Timezone",