-
- 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",