UI: Added queue for rule node
This commit is contained in:
parent
f799194c44
commit
1727728439
@ -38,7 +38,7 @@
|
|||||||
<mat-slide-toggle formControlName="debugMode">
|
<mat-slide-toggle formControlName="debugMode">
|
||||||
{{ 'rulenode.debug-mode' | translate }}
|
{{ 'rulenode.debug-mode' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<mat-slide-toggle *ngIf="isSingletonEditAllowed()" formControlName="singletonMode">
|
<mat-slide-toggle *ngIf="isSingleton()" formControlName="singletonMode">
|
||||||
{{ 'rulenode.singleton-mode' | translate }}
|
{{ 'rulenode.singleton-mode' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</section>
|
</section>
|
||||||
@ -52,10 +52,20 @@
|
|||||||
(initRuleNode)="initRuleNode.emit($event)"
|
(initRuleNode)="initRuleNode.emit($event)"
|
||||||
(changeScript)="changeScript.emit($event)">
|
(changeScript)="changeScript.emit($event)">
|
||||||
</tb-rule-node-config>
|
</tb-rule-node-config>
|
||||||
<div formGroupName="additionalInfo" fxLayout="column" class="description-block">
|
|
||||||
<mat-form-field class="mat-block">
|
<div class="description-block">
|
||||||
<mat-label translate>rulenode.rule-node-description</mat-label>
|
<tb-queue-autocomplete
|
||||||
<textarea matInput formControlName="description" rows="1"></textarea>
|
*ngIf="isAddQueue()"
|
||||||
</mat-form-field>
|
[queueType]="serviceType"
|
||||||
|
subscriptSizing="dynamic"
|
||||||
|
[autocompleteHint]="isSingleton() ? 'rulenode.queue-singleton-hint' : 'rulenode.queue-hint'"
|
||||||
|
formControlName="queueName">
|
||||||
|
</tb-queue-autocomplete>
|
||||||
|
<div formGroupName="additionalInfo">
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>rulenode.rule-node-description</mat-label>
|
||||||
|
<textarea matInput formControlName="description" rows="1"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -14,26 +14,38 @@
|
|||||||
/// limitations under the License.
|
/// 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 { PageComponent } from '@shared/components/page.component';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||||
import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models';
|
import { FcRuleNode, RuleNodeType } from '@shared/models/rule-node.models';
|
||||||
import { EntityType } from '@shared/models/entity-type.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 { RuleNodeConfigComponent } from './rule-node-config.component';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { RuleChainType } from '@app/shared/models/rule-chain.models';
|
import { RuleChainType } from '@app/shared/models/rule-chain.models';
|
||||||
import { ComponentClusteringMode } from '@shared/models/component-descriptor.models';
|
import { ComponentClusteringMode } from '@shared/models/component-descriptor.models';
|
||||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||||
|
import { ServiceType } from '@shared/models/queue.models';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-rule-node',
|
selector: 'tb-rule-node',
|
||||||
templateUrl: './rule-node-details.component.html',
|
templateUrl: './rule-node-details.component.html',
|
||||||
styleUrls: ['./rule-node-details.component.scss']
|
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;
|
@ViewChild('ruleNodeConfigComponent') ruleNodeConfigComponent: RuleNodeConfigComponent;
|
||||||
|
|
||||||
@ -63,9 +75,11 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O
|
|||||||
ruleNodeType = RuleNodeType;
|
ruleNodeType = RuleNodeType;
|
||||||
entityType = EntityType;
|
entityType = EntityType;
|
||||||
|
|
||||||
|
serviceType = ServiceType.TB_RULE_ENGINE;
|
||||||
|
|
||||||
ruleNodeFormGroup: UntypedFormGroup;
|
ruleNodeFormGroup: UntypedFormGroup;
|
||||||
|
|
||||||
private ruleNodeFormSubscription: Subscription;
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
private fb: UntypedFormBuilder,
|
private fb: UntypedFormBuilder,
|
||||||
@ -75,10 +89,6 @@ export class RuleNodeDetailsComponent extends PageComponent implements OnInit, O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private buildForm() {
|
private buildForm() {
|
||||||
if (this.ruleNodeFormSubscription) {
|
|
||||||
this.ruleNodeFormSubscription.unsubscribe();
|
|
||||||
this.ruleNodeFormSubscription = null;
|
|
||||||
}
|
|
||||||
if (this.ruleNode) {
|
if (this.ruleNode) {
|
||||||
this.ruleNodeFormGroup = this.fb.group({
|
this.ruleNodeFormGroup = this.fb.group({
|
||||||
name: [this.ruleNode.name, [Validators.required, Validators.pattern('(.|\\s)*\\S(.|\\s)*'), Validators.maxLength(255)]],
|
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 {
|
} else {
|
||||||
this.ruleNodeFormGroup = this.fb.group({});
|
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 {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
for (const propName of Object.keys(changes)) {
|
for (const propName of Object.keys(changes)) {
|
||||||
const change = changes[propName];
|
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() {
|
isSingletonEditAllowed() {
|
||||||
return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE;
|
return this.ruleNode.component.clusteringMode === ComponentClusteringMode.USER_PREFERENCE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -575,6 +575,7 @@ export class RuleChainPageComponent extends PageComponent
|
|||||||
configurationVersion: isDefinedAndNotNull(ruleNode.configurationVersion) ? ruleNode.configurationVersion : 0,
|
configurationVersion: isDefinedAndNotNull(ruleNode.configurationVersion) ? ruleNode.configurationVersion : 0,
|
||||||
debugMode: ruleNode.debugMode,
|
debugMode: ruleNode.debugMode,
|
||||||
singletonMode: ruleNode.singletonMode,
|
singletonMode: ruleNode.singletonMode,
|
||||||
|
queueName: ruleNode.queueName,
|
||||||
x: Math.round(ruleNode.additionalInfo.layoutX),
|
x: Math.round(ruleNode.additionalInfo.layoutX),
|
||||||
y: Math.round(ruleNode.additionalInfo.layoutY),
|
y: Math.round(ruleNode.additionalInfo.layoutY),
|
||||||
component,
|
component,
|
||||||
@ -934,7 +935,8 @@ export class RuleChainPageComponent extends PageComponent
|
|||||||
configuration: deepClone(node.configuration),
|
configuration: deepClone(node.configuration),
|
||||||
additionalInfo: node.additionalInfo ? deepClone(node.additionalInfo) : {},
|
additionalInfo: node.additionalInfo ? deepClone(node.additionalInfo) : {},
|
||||||
debugMode: node.debugMode,
|
debugMode: node.debugMode,
|
||||||
singletonMode: node.singletonMode
|
singletonMode: node.singletonMode,
|
||||||
|
queueName: node.queueName
|
||||||
};
|
};
|
||||||
if (minX === null) {
|
if (minX === null) {
|
||||||
minX = node.x;
|
minX = node.x;
|
||||||
@ -1467,7 +1469,8 @@ export class RuleChainPageComponent extends PageComponent
|
|||||||
configuration: node.configuration,
|
configuration: node.configuration,
|
||||||
additionalInfo: node.additionalInfo ? node.additionalInfo : {},
|
additionalInfo: node.additionalInfo ? node.additionalInfo : {},
|
||||||
debugMode: node.debugMode,
|
debugMode: node.debugMode,
|
||||||
singletonMode: node.singletonMode
|
singletonMode: node.singletonMode,
|
||||||
|
queueName: node.queueName
|
||||||
};
|
};
|
||||||
ruleNode.additionalInfo.layoutX = Math.round(node.x);
|
ruleNode.additionalInfo.layoutX = Math.round(node.x);
|
||||||
ruleNode.additionalInfo.layoutY = Math.round(node.y);
|
ruleNode.additionalInfo.layoutY = Math.round(node.y);
|
||||||
|
|||||||
@ -40,6 +40,7 @@ export interface ComponentDescriptor {
|
|||||||
type: ComponentType | RuleNodeType;
|
type: ComponentType | RuleNodeType;
|
||||||
scope?: ComponentScope;
|
scope?: ComponentScope;
|
||||||
clusteringMode: ComponentClusteringMode;
|
clusteringMode: ComponentClusteringMode;
|
||||||
|
hasQueueName?: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
clazz: string;
|
clazz: string;
|
||||||
configurationDescriptor?: any;
|
configurationDescriptor?: any;
|
||||||
|
|||||||
@ -39,6 +39,7 @@ export interface RuleNode extends BaseData<RuleNodeId> {
|
|||||||
name: string;
|
name: string;
|
||||||
debugMode: boolean;
|
debugMode: boolean;
|
||||||
singletonMode: boolean;
|
singletonMode: boolean;
|
||||||
|
queueName?: string;
|
||||||
configurationVersion?: number;
|
configurationVersion?: number;
|
||||||
configuration: RuleNodeConfiguration;
|
configuration: RuleNodeConfiguration;
|
||||||
additionalInfo?: any;
|
additionalInfo?: any;
|
||||||
@ -334,6 +335,7 @@ export interface RuleNodeComponentDescriptor extends ComponentDescriptor {
|
|||||||
export interface FcRuleNodeType extends FcNode {
|
export interface FcRuleNodeType extends FcNode {
|
||||||
component?: RuleNodeComponentDescriptor;
|
component?: RuleNodeComponentDescriptor;
|
||||||
singletonMode?: boolean;
|
singletonMode?: boolean;
|
||||||
|
queueName?: string;
|
||||||
nodeClass?: string;
|
nodeClass?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
iconUrl?: string;
|
iconUrl?: string;
|
||||||
|
|||||||
@ -3841,7 +3841,9 @@
|
|||||||
"test": "Test",
|
"test": "Test",
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"reset-debug-mode": "Reset debug mode in all nodes",
|
"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": "Timezone",
|
"timezone": "Timezone",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user