diff --git a/ui-ngx/src/app/core/http/calculated-fields.service.ts b/ui-ngx/src/app/core/http/calculated-fields.service.ts index ed8f431434..9c77f8007f 100644 --- a/ui-ngx/src/app/core/http/calculated-fields.service.ts +++ b/ui-ngx/src/app/core/http/calculated-fields.service.ts @@ -15,7 +15,7 @@ /// import { Injectable } from '@angular/core'; -import { defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; +import { createDefaultHttpOptions, defaultHttpOptionsFromConfig, RequestConfig } from './http-utils'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { PageData } from '@shared/models/page/page-data'; @@ -52,10 +52,7 @@ export class CalculatedFieldsService { public getCalculatedFields({ entityType, id }: EntityId, pageLink: PageLink, type?: CalculatedFieldType, config?: RequestConfig): Observable> { let url = `/api/${entityType}/${id}/calculatedFields${pageLink.toQuery()}`; - if (type) { - url += `&type=${type}`; - } - return this.http.get>(url, defaultHttpOptionsFromConfig(config)); + return this.http.get>(url, createDefaultHttpOptions(type ? {type} : null, config)); } public testScript(inputParams: CalculatedFieldTestScriptInputParams, config?: RequestConfig): Observable { diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.html index 1caa4121c8..9e5036f6ff 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.html @@ -15,40 +15,35 @@ limitations under the License. --> -
- + +

{{ 'alarm-rule.edit-alarm-rule-additional-info' | translate }}

- -
- -
-
-
- - - - -
-
+
+ + + + +
-
+
- + @if (!data.readonly) { + + }
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.ts index c413f0c1df..8a55f52678 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-details-dialog.component.ts @@ -14,15 +14,13 @@ /// limitations under the License. /// -import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; -import { ErrorStateMatcher } from '@angular/material/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { FormGroupDirective, NgForm, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; +import { FormBuilder, FormControl } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; -import { TranslateService } from '@ngx-translate/core'; export interface AlarmRuleDetailsDialogData { alarmDetails: string; @@ -32,51 +30,31 @@ export interface AlarmRuleDetailsDialogData { @Component({ selector: 'tb-edit-alarm-details-dialog', templateUrl: './alarm-rule-details-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: AlarmRuleDetailsDialogComponent}], - styleUrls: [] + providers: [], + styleUrls: ['./cf-alarm-rules-dialog.component.scss'], }) -export class AlarmRuleDetailsDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { +export class AlarmRuleDetailsDialogComponent extends DialogComponent { - alarmDetails = this.data.alarmDetails; - - editDetailsFormGroup: UntypedFormGroup; - - submitted = false; + alarmDetailsControl: FormControl; constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: AlarmRuleDetailsDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, - private fb: UntypedFormBuilder, - public translate: TranslateService) { + private fb: FormBuilder) { super(store, router, dialogRef); - this.editDetailsFormGroup = this.fb.group({ - alarmDetails: [this.alarmDetails] - }); + this.alarmDetailsControl = this.fb.control(this.data.alarmDetails); if (this.data.readonly) { - this.editDetailsFormGroup.disable(); + this.alarmDetailsControl.disable(); } } - ngOnInit(): void { - } - - isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = !!(control && control.invalid && this.submitted); - return originalErrorState || customErrorState; - } - cancel(): void { this.dialogRef.close(null); } save(): void { - this.submitted = true; - this.alarmDetails = this.editDetailsFormGroup.get('alarmDetails').value; - this.dialogRef.close(this.alarmDetails); + this.dialogRef.close(this.alarmDetailsControl.value); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html index 93c0f02861..04423edea6 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html @@ -54,7 +54,7 @@ />
- +
{{ 'calculated-fields.arguments' | translate }}
= 0) { keys.splice(index, 1); - this.configFormGroup.get('propagateRelationTypes').setValue(keys, {emitEvent: true}); + this.configFormGroup.get('propagateRelationTypes').setValue(keys); } } addRelationType(event: MatChipInputEvent): void { const input = event.chipInput.inputElement; - let value = event.value; - if ((value || '').trim()) { - value = value.trim(); - let keys: string[] = this.configFormGroup.get('propagateRelationTypes').value; - if (!keys || keys.indexOf(value) === -1) { - if (!keys) { - keys = []; - } + let value = (event.value ?? '').trim(); + if (value) { + let keys: string[] = this.configFormGroup.get('propagateRelationTypes').value ?? []; + if (keys.indexOf(value) === -1) { keys.push(value); - this.configFormGroup.get('propagateRelationTypes').setValue(keys, {emitEvent: true}); + this.configFormGroup.get('propagateRelationTypes').setValue(keys); } } if (input) { @@ -164,8 +159,8 @@ export class AlarmRuleDialogComponent extends DialogComponent { name: this.translate.instant('action.export'), icon: 'file_download', isEnabled: () => true, - onAction: (event$, entity) => this.exportCalculatedField(event$, entity), + onAction: (event$, entity) => this.exportAlarmRule(event$, entity), }, { name: this.translate.instant('entity-view.events'), @@ -177,6 +176,7 @@ export class AlarmRulesTableConfig extends EntityTableConfig { debugSettings, debugConfig: { entityType: EntityType.CALCULATED_FIELD, + isAlarmRule: true, additionalActionConfig, }, onSettingsAppliedFn: settings => this.onDebugConfigChanged(id.id, settings) @@ -226,7 +226,7 @@ export class AlarmRulesTableConfig extends EntityTableConfig { .subscribe(); } - private exportCalculatedField($event: Event, calculatedField: CalculatedField): void { + private exportAlarmRule($event: Event, calculatedField: CalculatedField): void { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.html index df433bc70e..e9eebb226c 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.html @@ -15,6 +15,6 @@ limitations under the License. --> -@if (calculatedFieldsTableConfig) { - +@if (alarmRulesTableConfig) { + } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.scss b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.scss index 3feb1e7429..0e0dacc392 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.scss +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.scss @@ -15,8 +15,6 @@ */ :host ::ng-deep { tb-entities-table { - .mat-drawer-container { - background-color: white; - } + --mat-sidenav-content-background-color: white; } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.ts index 1cf2feaa8d..9a553c1ffa 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rules-table.component.ts @@ -52,7 +52,7 @@ export class AlarmRulesTableComponent { entityName = input(); ownerId = input(); - calculatedFieldsTableConfig: AlarmRulesTableConfig; + alarmRulesTableConfig: AlarmRulesTableConfig; constructor(private calculatedFieldsService: CalculatedFieldsService, private translate: TranslateService, @@ -67,7 +67,7 @@ export class AlarmRulesTableComponent { effect(() => { if (this.active()) { - this.calculatedFieldsTableConfig = new AlarmRulesTableConfig( + this.alarmRulesTableConfig = new AlarmRulesTableConfig( this.calculatedFieldsService, this.translate, this.dialog, diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html index 05305e7f50..d2f98ecd85 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html @@ -31,131 +31,123 @@ close - -
-
-
-
- @if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) { -
-
-
{{ 'alarm-rule.argument-filters' | translate }}
- - {{ complexOperationTranslationMap.get(ComplexOperation.AND) | translate }} - {{ complexOperationTranslationMap.get(ComplexOperation.OR) | translate }} - -
- - +
+
+ @if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) { +
+
+
{{ 'alarm-rule.argument-filters' | translate }}
+ + {{ complexOperationTranslationMap.get(ComplexOperation.AND) | translate }} + {{ complexOperationTranslationMap.get(ComplexOperation.OR) | translate }} + +
+ + +
+ } @else { +
+
+ {{ 'alarm-rule.script' | translate }}
- } @else { -
-
- {{ 'alarm-rule.script' | translate }} + +
{{ 'alarm-rule.expression-type.tbel' | translate }}
- -
{{ 'alarm-rule.expression-type.tbel' | translate }} -
-
+
+
+ } +
+
+
{{ 'alarm-rule.condition-settings' | translate }}
+ + alarm-rule.condition-type + + + {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} + + + + @if (conditionFormGroup.get('type').value == AlarmConditionType.DURATION) { +
+
+
{{ 'alarm-rule.value' | translate }}
+ + {{ 'alarm-rule.static' | translate }} + {{ 'alarm-rule.dynamic' | translate }} +
- } -
-
-
{{ 'alarm-rule.condition-settings' | translate }}
- - alarm-rule.condition-type - - - {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} - - - - @if (conditionFormGroup.get('type').value == AlarmConditionType.DURATION) { -
-
-
{{ 'alarm-rule.value' | translate }}
- - {{ 'alarm-rule.static' | translate }} - {{ 'alarm-rule.dynamic' | translate }} - +
+
+ +
+
+
-
-
- -
-
- -
-
- - - - {{ timeUnitTranslations.get(timeUnit) | translate }} - - - - {{ 'alarm-rule.condition-duration-time-unit-required' | translate }} - - -
+
+ + + + {{ timeUnitTranslations.get(timeUnit) | translate }} + + + + {{ 'alarm-rule.condition-duration-time-unit-required' | translate }} + +
- } @else if (conditionFormGroup.get('type').value == AlarmConditionType.REPEATING) { -
-
-
{{ 'alarm-rule.value' | translate }}
- - {{ 'alarm-rule.static' | translate }} - {{ 'alarm-rule.dynamic' | translate }} - +
+ } @else if (conditionFormGroup.get('type').value == AlarmConditionType.REPEATING) { +
+
+
{{ 'alarm-rule.value' | translate }}
+ + {{ 'alarm-rule.static' | translate }} + {{ 'alarm-rule.dynamic' | translate }} + +
+
+
+
-
-
- -
-
- -
+
+
- } -
-
-
+
+ } + +
- + @if (!readonly) { + + }
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.ts index 1b0b3ec07f..99ccd8ea21 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.ts @@ -14,22 +14,13 @@ /// limitations under the License. /// -import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; -import { ErrorStateMatcher } from '@angular/material/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { - FormGroup, - FormGroupDirective, - NgForm, - UntypedFormBuilder, - UntypedFormControl, - Validators -} from '@angular/forms'; +import { FormBuilder, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; -import { TranslateService } from '@ngx-translate/core'; import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ScriptLanguage } from "@shared/models/rule-node.models"; @@ -47,7 +38,6 @@ import { import { TbEditorCompleter } from "@shared/models/ace/completion.models"; import { AceHighlightRules } from "@shared/models/ace/ace.models"; import { ComplexOperation, complexOperationTranslationMap } from "@shared/models/query/query.models"; -import { FormControlsFrom } from "@shared/models/tenant.model"; export interface CfAlarmRuleConditionDialogData { readonly: boolean; @@ -58,11 +48,10 @@ export interface CfAlarmRuleConditionDialogData { @Component({ selector: 'tb-cf-alarm-rule-condition-dialog', templateUrl: './cf-alarm-rule-condition-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: CfAlarmRuleConditionDialogComponent}], + providers: [], styleUrls: ['./cf-alarm-rules-dialog.component.scss'], }) -export class CfAlarmRuleConditionDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { +export class CfAlarmRuleConditionDialogComponent extends DialogComponent { AlarmRuleExpressionType = AlarmRuleExpressionType; @@ -74,9 +63,24 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent>; - - submitted = false; + conditionFormGroup = this.fb.group({ + expression: this.fb.group({ + type: [AlarmRuleExpressionType.SIMPLE], + expression: ['', [Validators.required]], + operation: [ComplexOperation.AND], + filters: [null], + }), + type: this.fb.control(AlarmRuleConditionType.SIMPLE, Validators.required), + unit: this.fb.control(TimeUnit.SECONDS, Validators.required), + value: this.fb.group({ + staticValue: this.fb.control(null, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]), + dynamicValueArgument: this.fb.control(null, Validators.required), + }), + count: this.fb.group({ + staticValue: this.fb.control(null, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]), + dynamicValueArgument: this.fb.control(null, Validators.required), + }), + }); readonly scriptLanguage = ScriptLanguage; @@ -85,8 +89,8 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent(false); + repeatingDynamicModeControl = this.fb.control(false); ComplexOperation = ComplexOperation; complexOperationTranslationMap = complexOperationTranslationMap; @@ -96,38 +100,41 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent; constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: CfAlarmRuleConditionDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, - private fb: UntypedFormBuilder, - public translate: TranslateService) { + private fb: FormBuilder) { super(store, router, dialogRef); this.functionArgs = ['ctx', ...Object.keys(this.data.arguments)]; this.argumentsEditorCompleter = getCalculatedFieldArgumentsEditorCompleter(this.data.arguments); this.argumentsHighlightRules = getCalculatedFieldArgumentsHighlights(this.data.arguments); - - this.conditionFormGroup = this.fb.group({ - expression: this.fb.group({ - type: [this.condition?.expression?.type ?? AlarmRuleExpressionType.SIMPLE], - expression: [this.condition?.expression?.expression ?? null, [Validators.required]], - operation: [this.condition?.expression?.operation ?? ComplexOperation.AND], - filters: [this.condition?.expression?.filters], - }), - type: [this.condition?.type ?? AlarmRuleConditionType.SIMPLE, Validators.required], - unit: [this.condition?.unit ?? TimeUnit.SECONDS, Validators.required], - value: this.fb.group({ - staticValue: [this.condition?.value?.staticValue ?? null, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]], - dynamicValueArgument: [this.condition?.value?.dynamicValueArgument ?? null, Validators.required], - }), - count: this.fb.group({ - staticValue: [this.condition?.count?.staticValue ?? null, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]], - dynamicValueArgument: [this.condition?.count?.dynamicValueArgument ?? null, Validators.required], - }), - }); + this.argumentsList = this.arguments ? Object.keys(this.arguments): []; + + this.conditionFormGroup.patchValue({ + expression: { + type: this.condition?.expression?.type ?? AlarmRuleExpressionType.SIMPLE, + expression: this.condition?.expression?.expression ?? null, + filters: this.condition?.expression?.filters ?? [], + operation: this.condition?.expression?.operation ?? ComplexOperation.AND + }, + type: this.condition?.type ?? AlarmRuleConditionType.SIMPLE, + unit: this.condition?.unit ?? TimeUnit.SECONDS, + value: { + staticValue: this.condition?.value?.staticValue, + dynamicValueArgument: this.condition?.value?.dynamicValueArgument, + }, + count: { + staticValue: this.condition?.count?.staticValue ?? null, + dynamicValueArgument: this.condition?.count?.dynamicValueArgument + } + }, {emitEvent: false}); + + this.durationDynamicModeControl.patchValue(!!this.condition?.value?.dynamicValueArgument, {emitEvent: false}); + this.repeatingDynamicModeControl.patchValue(!!this.condition?.count?.dynamicValueArgument, {emitEvent: false}); this.conditionFormGroup.get('type').valueChanges.pipe( takeUntilDestroyed() @@ -142,93 +149,70 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent { + this.updateStaticValueValidator(AlarmRuleConditionType.DURATION, mode); + }); + this.repeatingDynamicModeControl.valueChanges.pipe( + takeUntilDestroyed() + ).subscribe((mode) => { + this.updateStaticValueValidator(AlarmRuleConditionType.REPEATING, mode); + }); + this.updateValidators(this.conditionFormGroup.get('type').value ?? AlarmRuleConditionType.SIMPLE); this.updateExpressionTypeValidator(this.condition?.expression?.type ?? 'SIMPLE'); } - ngOnInit(): void { - } - - toggleDynamicMode(type: AlarmRuleConditionType): void { - if (type === AlarmRuleConditionType.DURATION) { - this.durationDynamicMode = !this.durationDynamicMode; - this.updateStaticValueValidator(type, this.durationDynamicMode); - } else { - this.repeatingDynamicMode = !this.repeatingDynamicMode; - this.updateStaticValueValidator(type, this.repeatingDynamicMode); - } - } - updateStaticValueValidator(type: AlarmRuleConditionType, dynamicValue: boolean) { - const control = type === AlarmRuleConditionType.DURATION ? 'value' : 'count'; + const control = this.conditionFormGroup.get(type === AlarmRuleConditionType.DURATION ? 'value' : 'count'); if (dynamicValue) { - this.conditionFormGroup.get(`${control}.staticValue`).disable({emitEvent: false}); - this.conditionFormGroup.get(`${control}.dynamicValueArgument`).enable({emitEvent: false}); + control.get('staticValue').disable({emitEvent: false}); + control.get('dynamicValueArgument').enable({emitEvent: false}); } else { - this.conditionFormGroup.get(`${control}.staticValue`).enable({emitEvent: false}); - this.conditionFormGroup.get(`${control}.dynamicValueArgument`).disable({emitEvent: false}); + control.get('staticValue').enable({emitEvent: false}); + control.get('dynamicValueArgument').disable({emitEvent: false}); } - this.conditionFormGroup.get(`${control}.staticValue`).updateValueAndValidity({emitEvent: false}) - this.conditionFormGroup.get(`${control}.dynamicValueArgument`).updateValueAndValidity({emitEvent: false}) } updateExpressionTypeValidator(type: 'SIMPLE' | 'TBEL') { if (type === 'SIMPLE') { - this.conditionFormGroup.get(`expression.expression`).disable(); - this.conditionFormGroup.get(`expression.filters`).enable(); + this.conditionFormGroup.get(`expression.expression`).disable({emitEvent: false}); + this.conditionFormGroup.get(`expression.filters`).enable({emitEvent: false}); } else { - this.conditionFormGroup.get(`expression.expression`).enable(); - this.conditionFormGroup.get(`expression.filters`).disable(); + this.conditionFormGroup.get(`expression.expression`).enable({emitEvent: false}); + this.conditionFormGroup.get(`expression.filters`).disable({emitEvent: false}); } - this.conditionFormGroup.get(`expression.expression`).updateValueAndValidity({emitEvent: false}); - this.conditionFormGroup.get(`expression.filters`).updateValueAndValidity({emitEvent: false}); - } - - isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = !!(control && control.invalid && this.submitted); - return originalErrorState || customErrorState; } private updateValidators(type: AlarmRuleConditionType, emitEvent = false) { switch (type) { case AlarmRuleConditionType.DURATION: - this.conditionFormGroup.get('unit').enable(); - this.conditionFormGroup.get('value').enable(); - this.conditionFormGroup.get('count').disable(); - - this.updateStaticValueValidator(type, this.durationDynamicMode); - + this.conditionFormGroup.get('unit').enable({emitEvent: false}); + this.conditionFormGroup.get('value').enable({emitEvent: false}); + this.conditionFormGroup.get('count').disable({emitEvent: false}); + this.updateStaticValueValidator(type, this.durationDynamicModeControl.value); this.defaultValuePlaceholder = 'alarm-rule.condition-duration-value'; this.defaultValueRequiredError = 'alarm-rule.condition-duration-value-required'; this.defaultValueRangeError = 'alarm-rule.condition-duration-value-range'; this.defaultValuePatternError = 'alarm-rule.condition-duration-value-pattern'; break; case AlarmRuleConditionType.REPEATING: - this.conditionFormGroup.get('count').enable(); - this.conditionFormGroup.get('value').disable(); - this.conditionFormGroup.get('unit').disable(); - - this.updateStaticValueValidator(type, this.repeatingDynamicMode); - + this.conditionFormGroup.get('count').enable({emitEvent: false}); + this.conditionFormGroup.get('value').disable({emitEvent: false}); + this.conditionFormGroup.get('unit').disable({emitEvent: false}); + this.updateStaticValueValidator(type, this.repeatingDynamicModeControl.value); this.defaultValuePlaceholder = 'alarm-rule.condition-repeating-value'; this.defaultValueRequiredError = 'alarm-rule.condition-repeating-value-required'; this.defaultValueRangeError = 'alarm-rule.condition-repeating-value-range'; this.defaultValuePatternError = 'alarm-rule.condition-repeating-value-pattern'; break; case AlarmRuleConditionType.SIMPLE: - this.conditionFormGroup.get('value').disable(); - this.conditionFormGroup.get('count').disable(); - this.conditionFormGroup.get('unit').disable(); + this.conditionFormGroup.get('value').disable({emitEvent: false}); + this.conditionFormGroup.get('count').disable({emitEvent: false}); + this.conditionFormGroup.get('unit').disable({emitEvent: false}); break; } - this.conditionFormGroup.get('value').updateValueAndValidity({emitEvent}); - this.conditionFormGroup.get('count').updateValueAndValidity({emitEvent}); - this.conditionFormGroup.get('unit').updateValueAndValidity({emitEvent}); - } - - get argumentsList(): Array { - return this.arguments ? Object.keys(this.arguments): []; } cancel(): void { @@ -236,9 +220,7 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent { }; constructor(private dialog: MatDialog, - private fb: UntypedFormBuilder, + private fb: FormBuilder, private cd: ChangeDetectorRef, private translate: TranslateService) { } @@ -101,9 +104,6 @@ export class CfAlarmRuleConditionComponent implements ControlValueAccessor, OnIn registerOnTouched(fn: any): void { } - ngOnInit() { - } - setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; if (this.disabled) { @@ -119,7 +119,7 @@ export class CfAlarmRuleConditionComponent implements ControlValueAccessor, OnIn } public conditionSet() { - return this.modelValue && (this.modelValue.expression.expression || this.modelValue.expression.filters); + return this.modelValue && (this.modelValue.expression?.expression || this.modelValue.expression?.filters); } public validate(c: UntypedFormControl) { @@ -147,7 +147,6 @@ export class CfAlarmRuleConditionComponent implements ControlValueAccessor, OnIn if (result) { this.modelValue = {...this.modelValue, ...result}; this.updateModel(); - this.updateSpecText(); this.cd.detectChanges(); } }); @@ -233,8 +232,7 @@ export class CfAlarmRuleConditionComponent implements ControlValueAccessor, OnIn }).afterClosed().subscribe((result) => { if (result) { this.modelValue.schedule = result; - this.propagateChange(this.modelValue); - this.updateScheduleText(); + this.updateModel(); this.cd.detectChanges(); } }); diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.scss b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.scss index c4e7087261..21b8a67c24 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.scss +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.scss @@ -14,10 +14,6 @@ * limitations under the License. */ :host { - min-width: 0; - .row { - margin-top: 1em; - } .tb-alarm-rule-details, .tb-alarm-rule-dashboard { padding: 4px; &.title { diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.ts index e652aa8f19..88ae1dd79d 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule.component.ts @@ -17,15 +17,14 @@ import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, + FormBuilder, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormBuilder, UntypedFormControl, Validator, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; -import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { isDefinedAndNotNull } from '@core/utils'; import { DashboardId } from '@shared/models/id/dashboard-id'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -35,6 +34,7 @@ import { AlarmRuleDetailsDialogComponent, AlarmRuleDetailsDialogData } from "@home/components/alarm-rules/alarm-rule-details-dialog.component"; +import { coerceBoolean } from "@shared/decorators/coercion"; @Component({ selector: 'tb-cf-alarm-rule', @@ -56,24 +56,20 @@ import { export class CfAlarmRuleComponent implements ControlValueAccessor, OnInit, Validator { @Input() + @coerceBoolean() disabled: boolean; - private requiredValue: boolean; - get required(): boolean { - return this.requiredValue; - } @Input() - set required(value: boolean) { - this.requiredValue = coerceBooleanProperty(value); - } + @coerceBoolean() + required: boolean; @Input() arguments: Record; private modelValue: AlarmRule; - alarmRuleFormGroup= this.fb.group({ - condition: [null, [Validators.required]], + alarmRuleFormGroup = this.fb.group({ + condition: this.fb.control({}, Validators.required), alarmDetails: [null], dashboardId: [null] }); @@ -81,7 +77,7 @@ export class CfAlarmRuleComponent implements ControlValueAccessor, OnInit, Valid private propagateChange = (v: any) => { }; constructor(private dialog: MatDialog, - private fb: UntypedFormBuilder, + private fb: FormBuilder, private destroyRef: DestroyRef) { } @@ -147,7 +143,7 @@ export class CfAlarmRuleComponent implements ControlValueAccessor, OnInit, Valid private updateModel() { const value = this.alarmRuleFormGroup.value; - this.modelValue = {...this.modelValue, ...value, dashboardId: value.dashboardId ? new DashboardId(value.dashboardId) : null}; + this.modelValue = {...value, dashboardId: value.dashboardId ? new DashboardId(value.dashboardId) : null} as AlarmRule; this.propagateChange(this.modelValue); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rules-dialog.component.scss b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rules-dialog.component.scss index 9fa5b01723..14df9a3972 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rules-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rules-dialog.component.scss @@ -20,5 +20,41 @@ display: grid; grid-template-rows: min-content minmax(auto, 1fr) min-content; } + + .tbel-script-lang-chip { + line-height: 20px; + font-size: 14px; + font-weight: 500; + color: white; + border-radius: 100px; + width: 70px; + min-width: 70px; + display: flex; + justify-content: center; + margin-top: 2px; + margin-right: 4px; + } + + .tb-js-func { + .ace_tb { + &.ace_calculated-field { + &-ctx { + color: #C52F00; + } + &-args { + color: #185F2A; + } + &-key { + color: #c24c1a; + } + &-time-window, &-values, &-func, &-value, &-ts, &-latestTs { + color: #7214D0; + } + &-start-ts, &-end-ts { + color: #2CAA00; + } + } + } + } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html index 5cb97ea1cb..2d12355f48 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html @@ -15,13 +15,13 @@ limitations under the License. --> -
+

{{ (readonly ? 'alarm-rule.schedule-title' : 'alarm-rule.edit-schedule') | translate }}

- - {{ 'alarm-rule.static-schedule' | translate }} - {{ 'alarm-rule.dynamic-schedule' | translate }} + + {{ 'alarm-rule.static-schedule' | translate }} + {{ 'alarm-rule.dynamic-schedule' | translate }}
- -
+ [dynamicMode]="dynamicModeControl.value" + [formControl]="alarmScheduleControl">
-
+
- + @if (!readonly) { + + }
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.ts index 8298e4467a..e132dd499e 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.ts @@ -14,16 +14,13 @@ /// limitations under the License. /// -import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; -import { ErrorStateMatcher } from '@angular/material/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { FormGroupDirective, NgForm, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; +import { FormBuilder } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; -import { UtilsService } from '@core/services/utils.service'; -import { TranslateService } from '@ngx-translate/core'; import { AlarmRuleSchedule } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; @@ -36,57 +33,38 @@ export interface AlarmRuleScheduleDialogData { @Component({ selector: 'tb-cf-alarm-schedule-dialog', templateUrl: './cf-alarm-schedule-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: CfAlarmScheduleDialogComponent}], + providers: [], styleUrls: ['./cf-alarm-rules-dialog.component.scss'], }) -export class CfAlarmScheduleDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { +export class CfAlarmScheduleDialogComponent extends DialogComponent{ readonly = this.data.readonly; alarmSchedule = this.data.alarmSchedule; arguments = this.data.arguments; - alarmScheduleFormGroup: UntypedFormGroup; + alarmScheduleControl = this.fb.control(null); - submitted = false; - - settingsMode: 'static' | 'dynamic' = 'static'; + dynamicModeControl = this.fb.control(false); constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: AlarmRuleScheduleDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, - private fb: UntypedFormBuilder, - private utils: UtilsService, - public translate: TranslateService) { + private fb: FormBuilder) { super(store, router, dialogRef); - - this.alarmScheduleFormGroup = this.fb.group({ - alarmSchedule: [this.alarmSchedule] - }); - this.settingsMode = this.alarmSchedule?.dynamicValueArgument ? 'dynamic' : 'static'; + this.alarmScheduleControl.patchValue(this.alarmSchedule, {emitEvent: false}); + this.dynamicModeControl.patchValue(!!this.alarmSchedule?.dynamicValueArgument, {emitEvent: false}); if (this.readonly) { - this.alarmScheduleFormGroup.disable({emitEvent: false}); + this.alarmScheduleControl.disable({emitEvent: false}); + this.dynamicModeControl.disable({emitEvent: false}); } } - ngOnInit(): void { - } - - isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = !!(control && control.invalid && this.submitted); - return originalErrorState || customErrorState; - } - cancel(): void { this.dialogRef.close(null); } save(): void { - this.submitted = true; - this.alarmSchedule = this.alarmScheduleFormGroup.get('alarmSchedule').value; - this.dialogRef.close(this.alarmSchedule); + this.dialogRef.close(this.alarmScheduleControl.value); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.html index 6824201178..13c158e67d 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.html @@ -16,17 +16,17 @@ -->
- @if (settingsMode === 'static') { + @if (!dynamicMode) { - - {{ alarmScheduleTypeTranslate.get(alarmScheduleType) | translate }} - + @for (scheduleType of alarmScheduleTypes; track scheduleType) { + {{ alarmScheduleTypeTranslate.get(scheduleType) | translate }} + } - - {{ 'alarm-rule.schedule-type-required' | translate }} - + @if (alarmScheduleForm.get('staticValue.type').hasError('required')) { + {{ 'alarm-rule.schedule-type-required' | translate }} + } @if (alarmScheduleForm.get('staticValue.type').value !== alarmScheduleType.ANY_TIME) { @@ -38,66 +38,67 @@ required formControlName="timezone"> -
- - - {{ dayOfWeekTranslationsArray[day] | translate }} - - - -
-
- - alarm-rule.schedule-time-from - - - - - - alarm-rule.schedule-time-to - - - - -
-
-
-
-
-
-
-
-
-
- - {{ dayOfWeekTranslationsArray[day] | translate }} - -
- + @if (alarmScheduleForm.get('staticValue.type').value === alarmScheduleType.SPECIFIC_TIME) { +
+ + + {{ dayOfWeekTranslationsArray[day] | translate }} + + + +
+
+ alarm-rule.schedule-time-from - + alarm-rule.schedule-time-to
-
+
+
-
- -
+
+ } + @if (alarmScheduleForm.get('staticValue.type').value === alarmScheduleType.CUSTOM) { +
+
+
+ + {{ dayOfWeekTranslationsArray[day] | translate }} + +
+ + alarm-rule.schedule-time-from + + + + + + alarm-rule.schedule-time-to + + + + +
+
+
+
+
+ +
+ }
} @@ -110,11 +111,11 @@ {{ argument }} } - - {{ 'calculated-fields.hint.argument-name-required' | translate }} - + @if (alarmScheduleForm.get('dynamicValueArgument').hasError('required')) { + {{ 'calculated-fields.hint.argument-name-required' | translate }} + } -
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.ts index e7bc30be6e..b1c7a4da7f 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule.component.ts @@ -14,20 +14,21 @@ /// limitations under the License. /// -import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, DestroyRef, forwardRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { AbstractControl, ControlValueAccessor, + FormArray, + FormBuilder, + FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormArray, - UntypedFormBuilder, - UntypedFormGroup, ValidationErrors, Validator, Validators } from '@angular/forms'; import { + CustomTimeSchedulerItem, dayOfWeekTranslations, getAlarmScheduleRangeText, timeOfDayToUTCTimestamp, @@ -43,6 +44,7 @@ import { } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; import { MatChipSelectionChange } from "@angular/material/chips"; +import { coerceBoolean } from "@shared/decorators/coercion"; @Component({ selector: 'tb-cf-alarm-schedule', @@ -58,43 +60,38 @@ import { MatChipSelectionChange } from "@angular/material/chips"; multi: true }] }) -export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator, OnInit { +export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator, OnInit, OnChanges { + @Input() + @coerceBoolean() disabled: boolean; @Input() arguments: Record; - private settingsModeValue: 'static' | 'dynamic'; - get settingsMode(): 'static' | 'dynamic' { - return this.settingsModeValue; - } @Input() - set settingsMode(value: 'static' | 'dynamic') { - if (value !== this.settingsModeValue && this.alarmScheduleForm) { - this.settingsModeValue = value; - this.updateModeValidators(value); - this.updateModel(); - } - } + @coerceBoolean() + dynamicMode: boolean; alarmScheduleForm = this.fb.group({ staticValue: this.fb.group({ type: [AlarmRuleScheduleType.ANY_TIME, Validators.required], - timezone: [null, Validators.required], - daysOfWeek: [null, Validators.required], - startsOn: [0, Validators.required], - endsOn: [0, Validators.required], + timezone: ['', Validators.required], + daysOfWeek: this.fb.control(null, Validators.required), + startsOn: this.fb.control(0, Validators.required), + endsOn: this.fb.control(0, Validators.required), items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)), this.validateItems), }), - dynamicValueArgument: [null, Validators.required] + dynamicValueArgument: ['', Validators.required] }); - alarmScheduleTypes = Object.keys(AlarmRuleScheduleType); + alarmScheduleTypes = Object.keys(AlarmRuleScheduleType) as Array; alarmScheduleType = AlarmRuleScheduleType; alarmScheduleTypeTranslate = AlarmRuleScheduleTypeTranslationMap; dayOfWeekTranslationsArray = dayOfWeekTranslations; + argumentsList: Array; + allDays = Array(7).fill(0).map((x, i) => i); private modelValue: AlarmRuleSchedule; @@ -102,23 +99,24 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator private defaultItems = Array.from({length: 7}, (value, i) => ({ enabled: true, dayOfWeek: i + 1 - })); + })) as CustomTimeSchedulerItem[]; private propagateChange = (v: any) => { }; - constructor(private fb: UntypedFormBuilder, + constructor(private fb: FormBuilder, private destroyRef: DestroyRef) { } ngOnInit(): void { + this.argumentsList = this.arguments ? Object.keys(this.arguments): []; this.alarmScheduleForm.get('staticValue.type').valueChanges.pipe( takeUntilDestroyed(this.destroyRef) ).subscribe((type) => { const defaultTimezone = getDefaultTimezone(); - this.alarmScheduleForm.get('staticValue').patchValue({type, items: this.defaultItems, timezone: defaultTimezone}, {emitEvent: false}); + const staticValue = {...this.alarmScheduleForm.get('staticValue').value, type, items: this.defaultItems, timezone: defaultTimezone}; + this.alarmScheduleForm.get('staticValue').patchValue(staticValue, {emitEvent: false}); this.alarmScheduleForm.get('dynamicValueArgument').patchValue(null, {emitEvent: false}); this.updateValidators(type); - this.alarmScheduleForm.updateValueAndValidity(); }); this.alarmScheduleForm.valueChanges.pipe( takeUntilDestroyed(this.destroyRef) @@ -133,6 +131,16 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator }); } + ngOnChanges(changes: SimpleChanges) { + if (changes.dynamicMode) { + const dynamicModeChanges = changes.dynamicMode; + if (!dynamicModeChanges.firstChange && dynamicModeChanges.currentValue !== dynamicModeChanges.previousValue) { + this.updateModeValidators(dynamicModeChanges.currentValue); + this.updateModel(); + } + } + } + validateItems(control: AbstractControl): ValidationErrors | null { const items: any[] = control.value; if (!items || !items.length || !items.find(v => v.enabled === true)) { @@ -155,7 +163,7 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator if (this.disabled) { this.alarmScheduleForm.disable({emitEvent: false}); } else { - this.updateModeValidators(this.settingsMode); + this.updateModeValidators(this.dynamicMode); } } @@ -163,10 +171,8 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator if (value) { this.modelValue = value; if (this.modelValue.dynamicValueArgument) { - this.settingsModeValue = 'dynamic'; this.alarmScheduleForm.get('dynamicValueArgument').patchValue(this.modelValue.dynamicValueArgument, {emitEvent: false}); } else { - this.settingsModeValue = 'static'; switch (this.modelValue.staticValue.type) { case AlarmRuleScheduleType.SPECIFIC_TIME: this.alarmScheduleForm.patchValue({ @@ -212,11 +218,11 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator } this.updateValidators(this.modelValue.staticValue.type); } - this.updateModeValidators(this.settingsMode); + this.updateModeValidators(this.dynamicMode); } } - validate(control: UntypedFormGroup): ValidationErrors | null { + validate(control: FormGroup): ValidationErrors | null { return this.alarmScheduleForm.valid ? null : { alarmScheduler: { valid: false @@ -224,14 +230,14 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator }; } - private updateModeValidators(mode: 'static' | 'dynamic') { - if (mode === 'static') { + private updateModeValidators(mode: boolean) { + if (mode) { + this.alarmScheduleForm.get('staticValue').disable({emitEvent: false}); + this.alarmScheduleForm.get('dynamicValueArgument').enable({emitEvent: false}); + } else { this.alarmScheduleForm.get('staticValue').enable({emitEvent: false}); this.alarmScheduleForm.get('dynamicValueArgument').disable({emitEvent: false}); this.updateValidators(this.alarmScheduleForm.get('staticValue.type').value); - } else { - this.alarmScheduleForm.get('staticValue').disable({emitEvent: false}); - this.alarmScheduleForm.get('dynamicValueArgument').enable({emitEvent: false}); } } @@ -256,14 +262,14 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator this.alarmScheduleForm.get('staticValue.daysOfWeek').disable({emitEvent: false}); this.alarmScheduleForm.get('staticValue.startsOn').disable({emitEvent: false}); this.alarmScheduleForm.get('staticValue.endsOn').disable({emitEvent: false}); - this.alarmScheduleForm.get('staticValue.items').enable({emitEvent: true}); + this.alarmScheduleForm.get('staticValue.items').enable({emitEvent: false}); break; } } private updateModel() { const value = this.alarmScheduleForm.value as AlarmRuleSchedule; - if (this.settingsMode === 'static') { + if (!this.dynamicMode) { if (isDefined(value.staticValue.startsOn) && value.staticValue.startsOn !== 0) { value.staticValue.startsOn = timeOfDayToUTCTimestamp(value.staticValue.startsOn); } @@ -271,22 +277,18 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator value.staticValue.endsOn = timeOfDayToUTCTimestamp(value.staticValue.endsOn); } if (isDefined(value.staticValue.items)){ - value.staticValue.items = this.alarmScheduleForm.getRawValue().staticValue.items; + value.staticValue.items = this.alarmScheduleForm.getRawValue().staticValue.items as CustomTimeSchedulerItem[]; value.staticValue.items = value.staticValue.items.map((item) => { return { ...item, startsOn: timeOfDayToUTCTimestamp(item.startsOn), endsOn: timeOfDayToUTCTimestamp(item.endsOn)}; }); } } this.modelValue = value; - if (this.alarmScheduleForm.valid) { - this.propagateChange(this.modelValue); - } else { - this.propagateChange(null); - } + this.propagateChange(this.modelValue); } - private defaultItemsScheduler(index): UntypedFormGroup { + private defaultItemsScheduler(index: number): FormGroup { return this.fb.group({ enabled: [true], dayOfWeek: [index + 1], @@ -310,16 +312,11 @@ export class CfAlarmScheduleComponent implements ControlValueAccessor, Validator } } - getSchedulerRangeText(control: UntypedFormGroup | AbstractControl): string { + getSchedulerRangeText(control: FormGroup | AbstractControl): string { return getAlarmScheduleRangeText(control.get('startsOn').value, control.get('endsOn').value); } - get itemsSchedulerForm(): UntypedFormArray { - return this.alarmScheduleForm.get('staticValue.items') as UntypedFormArray; + get itemsSchedulerForm(): FormArray { + return this.alarmScheduleForm.get('staticValue.items') as FormArray; } - - get argumentsList(): Array { - return this.arguments ? Object.keys(this.arguments): []; - } - } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html index 2b93030ce3..820418a6b0 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html @@ -15,27 +15,12 @@ limitations under the License. --> -
@for (createAlarmRuleControl of createAlarmRulesFormArray().controls; track createAlarmRuleControl; let index = $index) {
-
+
alarm.severity
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.ts index 5be6d651df..1ffc52bb34 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.ts @@ -14,25 +14,25 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, DestroyRef, forwardRef, Input } from '@angular/core'; import { AbstractControl, ControlValueAccessor, + FormArray, + FormBuilder, NG_VALIDATORS, NG_VALUE_ACCESSOR, UntypedFormArray, - UntypedFormBuilder, UntypedFormControl, - UntypedFormGroup, Validator, Validators } from '@angular/forms'; -import { Subject } from 'rxjs'; import { AlarmSeverity, alarmSeverityTranslations } from '@shared/models/alarm.models'; -import { takeUntil } from 'rxjs/operators'; import { AlarmRule } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; import { AlarmSeverityNotificationColors } from "@shared/models/notification.models"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { coerceBoolean } from "@shared/decorators/coercion"; @Component({ selector: 'tb-create-cf-alarm-rules', @@ -51,28 +51,35 @@ import { AlarmSeverityNotificationColors } from "@shared/models/notification.mod } ] }) -export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit, Validator, OnDestroy { - - alarmSeverities = Object.keys(AlarmSeverity); - alarmSeverityEnum = AlarmSeverity; - alarmSeverityTranslationMap = alarmSeverityTranslations; - - AlarmSeverityNotificationColors = AlarmSeverityNotificationColors; +export class CreateCfAlarmRulesComponent implements ControlValueAccessor, Validator { @Input() + @coerceBoolean() disabled: boolean; @Input() arguments: Record; - createAlarmRulesFormGroup: UntypedFormGroup; + + alarmSeverities = Object.keys(AlarmSeverity); + alarmSeverityEnum = AlarmSeverity; + alarmSeverityTranslationMap = alarmSeverityTranslations; + + AlarmSeverityNotificationColors = AlarmSeverityNotificationColors; + + createAlarmRulesFormGroup = this.fb.group({ + createAlarmRules: this.fb.array<{severity: AlarmSeverity, alarmRule: AlarmRule}>([]) + }); private usedSeverities: AlarmSeverity[] = []; - private destroy$ = new Subject(); private propagateChange = (v: any) => { }; - constructor(private fb: UntypedFormBuilder) { + constructor(private fb: FormBuilder, + private destroyRef: DestroyRef) { + this.createAlarmRulesFormGroup.valueChanges.pipe( + takeUntilDestroyed(this.destroyRef) + ).subscribe(() => this.updateModel()); } registerOnChange(fn: any): void { @@ -82,20 +89,6 @@ export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit registerOnTouched(fn: any): void { } - ngOnInit() { - this.createAlarmRulesFormGroup = this.fb.group({ - createAlarmRules: this.fb.array([]) - }); - this.createAlarmRulesFormGroup.valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe(() => this.updateModel()); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } - createAlarmRulesFormArray(): UntypedFormArray { return this.createAlarmRulesFormGroup.get('createAlarmRules') as UntypedFormArray; } @@ -109,7 +102,7 @@ export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit } } - writeValue(createAlarmRules: {[severity: string]: AlarmRule}): void { + writeValue(createAlarmRules: Record): void { const createAlarmRulesControls: Array = []; if (createAlarmRules) { Object.keys(createAlarmRules).forEach((severity) => { @@ -123,7 +116,9 @@ export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit })); }); } - this.createAlarmRulesFormGroup.setControl('createAlarmRules', this.fb.array(createAlarmRulesControls), {emitEvent: false}); + const formArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; + formArray.clear(); + createAlarmRulesControls.forEach(c => formArray.push(c)); if (this.disabled) { this.createAlarmRulesFormGroup.disable({emitEvent: false}); } else { @@ -136,11 +131,11 @@ export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit } public removeCreateAlarmRule(index: number) { - (this.createAlarmRulesFormGroup.get('createAlarmRules') as UntypedFormArray).removeAt(index); + (this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray).removeAt(index); } public addCreateAlarmRule() { - const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as UntypedFormArray; + const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; createAlarmRulesArray.push(this.fb.group({ severity: [this.getFirstUnusedSeverity(), Validators.required], alarmRule: [null, Validators.required] @@ -176,15 +171,15 @@ export class CreateCfAlarmRulesComponent implements ControlValueAccessor, OnInit private updateUsedSeverities() { this.usedSeverities = []; - const value: {severity: string, alarmRule: AlarmRule}[] = this.createAlarmRulesFormGroup.get('createAlarmRules').value; + const value = this.createAlarmRulesFormGroup.get('createAlarmRules').value; value.forEach((rule, index) => { this.usedSeverities[index] = AlarmSeverity[rule.severity]; }); } private updateModel() { - const value: {severity: string, alarmRule: AlarmRule}[] = this.createAlarmRulesFormGroup.get('createAlarmRules').value; - const createAlarmRules: {[severity: string]: AlarmRule} = {}; + const value = this.createAlarmRulesFormGroup.get('createAlarmRules').value; + const createAlarmRules = {} as Record; value.forEach(v => createAlarmRules[v.severity] = v.alarmRule); this.updateUsedSeverities(); this.propagateChange(createAlarmRules); diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.html index c5b30ca6c4..ed5dc4b9cd 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.html @@ -16,9 +16,8 @@ -->
- +

filter.complex-filter

-
-
- - filter.operation.operation - - - {{complexOperationTranslations.get(complexOperationEnum[operation]) | translate}} - - - - - -
+ + filter.operation.operation + + + {{complexOperationTranslations.get(complexOperationEnum[operation]) | translate}} + + + + +
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.ts index 3327ed6d35..245d866403 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component.ts @@ -14,19 +14,12 @@ /// limitations under the License. /// -import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { - FormGroup, - FormGroupDirective, - NgForm, - UntypedFormBuilder, - UntypedFormControl, - Validators -} from '@angular/forms'; +import { FormBuilder, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { @@ -35,8 +28,7 @@ import { EntityKeyValueType, FilterPredicateType } from '@shared/models/query/query.models'; -import { ComplexAlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; -import { FormControlsFrom } from "@shared/models/tenant.model"; +import { AlarmRuleFilterPredicate, ComplexAlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; export interface AlarmRuleComplexFilterPredicateDialogData { @@ -54,10 +46,14 @@ export interface AlarmRuleComplexFilterPredicateDialogData { }) export class AlarmRuleComplexFilterPredicateDialogComponent extends - DialogComponent - implements OnInit, ErrorStateMatcher { + DialogComponent { - complexFilterFormGroup: FormGroup>; + complexFilterFormGroup = this.fb.group( + { + operation: [ComplexOperation.AND, [Validators.required]], + predicates: this.fb.control(null, Validators.required) + } + ); complexOperations = Object.keys(ComplexOperation); complexOperationEnum = ComplexOperation; @@ -65,35 +61,18 @@ export class AlarmRuleComplexFilterPredicateDialogComponent extends isAdd: boolean; - submitted = false; - arguments = this.data.arguments; constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: AlarmRuleComplexFilterPredicateDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, - private fb: UntypedFormBuilder) { + private fb: FormBuilder) { super(store, router, dialogRef); this.isAdd = this.data.isAdd; - this.complexFilterFormGroup = this.fb.group( - { - operation: [this.data.complexPredicate.operation, [Validators.required]], - predicates: [this.data.complexPredicate.predicates, [Validators.required]] - } - ); - } - - ngOnInit(): void { - } - - isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = !!(control && control.invalid && this.submitted); - return originalErrorState || customErrorState; + this.complexFilterFormGroup.patchValue(this.data.complexPredicate, {emitEvent: false}); } cancel(): void { @@ -101,7 +80,6 @@ export class AlarmRuleComplexFilterPredicateDialogComponent extends } save(): void { - this.submitted = true; if (this.complexFilterFormGroup.valid) { const predicate: ComplexAlarmRuleFilterPredicate = this.complexFilterFormGroup.value as ComplexAlarmRuleFilterPredicate; predicate.type = FilterPredicateType.COMPLEX; diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.html index 7d7dab2470..e622e9e4f8 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.html @@ -16,9 +16,8 @@ --> - -

{{(data.isAdd ? 'alarm-rule.add-filter' : ('alarm-rule.edit-filter')) | translate}}

- + +

{{(data.isAdd ? 'alarm-rule.add-filter' : 'alarm-rule.edit-filter') | translate}}

-
+
{{ 'alarm-rule.general' | translate }}
@@ -81,20 +80,18 @@ formControlName="predicates">
- -
+
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.ts index fdff318c61..6961524bdd 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-dialog.component.ts @@ -14,19 +14,11 @@ /// limitations under the License. /// - import { Component, Inject, OnDestroy, SkipSelf } from '@angular/core'; - import { ErrorStateMatcher } from '@angular/material/core'; + import { Component, DestroyRef, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; - import { - FormGroup, - FormGroupDirective, - NgForm, - UntypedFormBuilder, - UntypedFormControl, - Validators - } from '@angular/forms'; + import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { @@ -37,11 +29,10 @@ } from '@shared/models/query/query.models'; import { DialogService } from '@core/services/dialog.service'; import { TranslateService } from '@ngx-translate/core'; - import { Subject } from 'rxjs'; - import { takeUntil } from 'rxjs/operators'; import { AlarmRuleFilter, AlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; import { FormControlsFrom } from "@shared/models/tenant.model"; + import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; export interface AlarmRuleFilterDialogData { filter: AlarmRuleFilter; @@ -53,13 +44,10 @@ @Component({ selector: 'tb-alarm-rule-filter-dialog', templateUrl: './alarm-rule-filter-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: AlarmRuleFilterDialogComponent}], + providers: [], styleUrls: ['./alarm-rule-filter-dialog.component.scss'] }) -export class AlarmRuleFilterDialogComponent extends DialogComponent - implements OnDestroy, ErrorStateMatcher { - - private destroy$ = new Subject(); +export class AlarmRuleFilterDialogComponent extends DialogComponent { filterFormGroup: FormGroup>; @@ -73,22 +61,21 @@ export class AlarmRuleFilterDialogComponent extends DialogComponent; constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: AlarmRuleFilterDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, private dialogs: DialogService, private translate: TranslateService, - private fb: UntypedFormBuilder) { + private fb: FormBuilder, + private destroyRef: DestroyRef) { super(store, router, dialogRef); + this.argumentsList = this.arguments ? Object.keys(this.arguments) : []; + this.filterFormGroup = this.fb.group( { argument: [this.data.filter.argument, [Validators.required]], @@ -98,7 +85,7 @@ export class AlarmRuleFilterDialogComponent extends DialogComponent { const prevValueType: EntityKeyValueType = this.filterFormGroup.value.valueType; const predicates: AlarmRuleFilterPredicate[] = this.filterFormGroup.get('predicates').value; @@ -119,35 +106,15 @@ export class AlarmRuleFilterDialogComponent extends DialogComponent { - return this.arguments ? Object.keys(this.arguments) : []; + this.dialogRef.close(this.filterFormGroup.value as AlarmRuleFilter); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.html index 1a71c92111..3f588a3d70 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.html @@ -15,67 +15,65 @@ limitations under the License. --> -
-
- -
- - -   -
-
- -
- @for (filterControl of filtersFormArray.controls; track filterControl; let index = $index) { -
-
- @if ($index) { -
- {{ complexOperationTranslationMap.get(operation) | translate }} -
- } -
-
-
-
{{ filterControl.value?.argument }}
-
{{ FilterPredicateTypeTranslationMap.get(filterControl.value?.predicates[0]?.type) | translate }}
- - -
+
+
+ +
+ + +   +
+
+ +
+ @for (filterControl of filtersFormArray.controls; track filterControl; let index = $index) { +
+
+ @if ($index) { +
+ {{ complexOperationTranslationMap.get(operation) | translate }}
- @if (index) { - - } + } +
+
+
+
{{ filterControl.value?.argument }}
+
{{ FilterPredicateTypeTranslationMap.get(filterControl.value?.predicates[0]?.type) | translate }}
+ +
+
+ @if (index) { + } - - filter.no-key-filters -
+ } + + filter.no-key-filters + +
-
- -
+ diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.ts index 5ed3bce4e9..86b7520910 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.ts @@ -14,21 +14,19 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, DestroyRef, forwardRef, Input } from '@angular/core'; import { AbstractControl, ControlValueAccessor, - FormControl, + FormArray, + FormBuilder, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormArray, - UntypedFormBuilder, - UntypedFormGroup, ValidationErrors, Validator, Validators } from '@angular/forms'; -import { Observable, Subject } from 'rxjs'; +import { Observable } from 'rxjs'; import { ComplexOperation, complexOperationTranslationMap, @@ -36,14 +34,13 @@ import { } from '@shared/models/query/query.models'; import { MatDialog } from '@angular/material/dialog'; import { deepClone } from '@core/utils'; -import { takeUntil } from 'rxjs/operators'; import { AlarmRuleFilterDialogComponent, AlarmRuleFilterDialogData } from "@home/components/alarm-rules/filter/alarm-rule-filter-dialog.component"; import { AlarmRuleFilter, FilterPredicateTypeTranslationMap } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; -import { UtilsService } from "@core/services/utils.service"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: 'tb-alarm-rule-filter-list', @@ -62,45 +59,34 @@ import { UtilsService } from "@core/services/utils.service"; } ] }) -export class AlarmRuleFilterListComponent implements ControlValueAccessor, Validator, OnInit, OnDestroy { +export class AlarmRuleFilterListComponent implements ControlValueAccessor, Validator { @Input() arguments: Record; - @Input() operation: ComplexOperation = ComplexOperation.AND; + @Input() + operation: ComplexOperation = ComplexOperation.AND; - filterListFormGroup: UntypedFormGroup; - filtersControl: FormControl; + filterListFormGroup = this.fb.group({ + filters: this.fb.array([]) + }); complexOperationTranslationMap = complexOperationTranslationMap; FilterPredicateTypeTranslationMap = FilterPredicateTypeTranslationMap - private destroy$ = new Subject(); - private propagateChange = null; - - constructor(private fb: UntypedFormBuilder, - private utils: UtilsService, - private dialog: MatDialog) { - } - - ngOnInit(): void { - this.filterListFormGroup = this.fb.group({ - filters: this.fb.array([]) - }); - this.filtersControl = this.fb.control(null); + private propagateChange = (v: any) => { }; + constructor(private fb: FormBuilder, + private dialog: MatDialog, + private destroyRef: DestroyRef) { this.filterListFormGroup.valueChanges.pipe( - takeUntil(this.destroy$) + takeUntilDestroyed(this.destroyRef) ).subscribe(() => this.updateModel()); } - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } - get filtersFormArray(): UntypedFormArray { - return this.filterListFormGroup.get('filters') as UntypedFormArray; + get filtersFormArray(): FormArray { + return this.filterListFormGroup.get('filters') as FormArray; } registerOnChange(fn: any): void { @@ -111,32 +97,28 @@ export class AlarmRuleFilterListComponent implements ControlValueAccessor, Valid } validate(): ValidationErrors | null { - return this.filterListFormGroup.valid && this.filtersControl.valid && this.filterListFormGroup.get('filters').value?.length ? null : { + return this.filterListFormGroup.valid && this.filterListFormGroup.get('filters').value?.length ? null : { filterList: {valid: false} }; } writeValue(filters: Array): void { - if (filters?.length === this.filtersFormArray?.length) { - this.filtersFormArray.patchValue(filters, {emitEvent: false}); - } else { - const keyFilterControls: Array = []; - if (filters) { - for (const filter of filters) { - keyFilterControls.push(this.fb.control(filter, [Validators.required])); - } + const keyFilterControls: Array = []; + if (filters) { + for (const filter of filters) { + keyFilterControls.push(this.fb.control(filter, [Validators.required])); } - this.filterListFormGroup.setControl('filters', this.fb.array(keyFilterControls), {emitEvent: false}); } - this.filtersControl.patchValue(filters, {emitEvent: false}); + this.filtersFormArray.clear(); + keyFilterControls.forEach(c => this.filtersFormArray.push(c)); } public removeFilter(index: number) { - (this.filterListFormGroup.get('filters') as UntypedFormArray).removeAt(index); + (this.filterListFormGroup.get('filters') as FormArray).removeAt(index); } public addFilter() { - const filtersFormArray = this.filterListFormGroup.get('filters') as UntypedFormArray; + const filtersFormArray = this.filterListFormGroup.get('filters') as FormArray; this.openFilterDialog(null).subscribe(result => { if (result) { filtersFormArray.push(this.fb.control(result, [Validators.required])); @@ -146,17 +128,17 @@ export class AlarmRuleFilterListComponent implements ControlValueAccessor, Valid public editFilter(index: number) { const filter: AlarmRuleFilter = - (this.filterListFormGroup.get('filters') as UntypedFormArray).at(index).value; + (this.filterListFormGroup.get('filters') as FormArray).at(index).value; this.openFilterDialog(filter).subscribe(result => { if (result) { - (this.filterListFormGroup.get('filters') as UntypedFormArray).at(index).patchValue(result); + (this.filterListFormGroup.get('filters') as FormArray).at(index).patchValue(result); } }); } private openFilterDialog(filter?: AlarmRuleFilter): Observable { const isAdd = !filter; - if (!filter) { + if (isAdd) { filter = { argument: null, valueType: EntityKeyValueType.STRING, @@ -178,18 +160,13 @@ export class AlarmRuleFilterListComponent implements ControlValueAccessor, Valid } get getUsedArguments(): Array { - const filters = this.filterListFormGroup.get('filters').value ?? []; - return filters.length ? filters.map((filter: AlarmRuleFilter) => filter.argument) : filters; + const filters = this.filterListFormGroup.get('filters').value as Array; + return filters.length ? filters.map((filter: AlarmRuleFilter) => filter.argument) : []; } private updateModel() { - const filters: Array = this.filterListFormGroup.getRawValue().filters; - this.filtersControl.patchValue(filters, {emitEvent: false}); - if (filters.length) { - this.propagateChange(filters); - } else { - this.propagateChange(null); - } + const filters = this.filterListFormGroup.value.filters as Array; + this.propagateChange(filters); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.html index 4ca4f9ffdf..210f3f9424 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.html @@ -15,7 +15,7 @@ limitations under the License. --> -
+
@@ -24,15 +24,14 @@
-   +  
@for (predicateControl of predicatesFormArray.controls; track predicateControl; let index = $index) {
+ [class.key-filter-list-divider]="$index"> @if (index) {
{{ complexOperationTranslations.get(operation) | translate }} @@ -60,25 +59,27 @@ } filter.no-filters + class="no-data-found flex items-center justify-center" translate> + filter.no-filters +
-
- - -
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.ts index 6772d6379c..2b7458ba46 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.ts @@ -14,20 +14,19 @@ /// limitations under the License. /// -import { Component, forwardRef, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, DestroyRef, forwardRef, Input } from '@angular/core'; import { AbstractControl, ControlValueAccessor, + FormArray, + FormBuilder, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormArray, - UntypedFormBuilder, - UntypedFormGroup, ValidationErrors, Validator, Validators } from '@angular/forms'; -import { Observable, of, Subject } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { BooleanOperation, ComplexOperation, @@ -39,9 +38,7 @@ import { StringOperation } from '@shared/models/query/query.models'; import { MatDialog } from '@angular/material/dialog'; -import { map, takeUntil } from 'rxjs/operators'; -import { ComponentType } from '@angular/cdk/portal'; -import { COMPLEX_FILTER_PREDICATE_DIALOG_COMPONENT_TOKEN } from '@home/components/tokens'; +import { map } from 'rxjs/operators'; import { AlarmRuleComplexFilterPredicateDialogComponent, AlarmRuleComplexFilterPredicateDialogData @@ -52,6 +49,7 @@ import { ComplexAlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; @Component({ selector: 'tb-alarm-rule-filter-predicate-list', @@ -70,7 +68,7 @@ import { CalculatedFieldArgument } from "@shared/models/calculated-field.models" } ] }) -export class AlarmRuleFilterPredicateListComponent implements ControlValueAccessor, Validator, OnInit, OnDestroy { +export class AlarmRuleFilterPredicateListComponent implements ControlValueAccessor, Validator { @Input() disabled: boolean; @@ -80,36 +78,26 @@ export class AlarmRuleFilterPredicateListComponent implements ControlValueAccess @Input() arguments: Record; - filterListFormGroup: UntypedFormGroup; + filterListFormGroup = this.fb.group({ + predicates: this.fb.array([]) + }); valueTypeEnum = EntityKeyValueType; complexOperationTranslations = complexOperationTranslationMap; - private destroy$ = new Subject(); - private propagateChange = null; + private propagateChange= (v: any) => { }; - constructor(private fb: UntypedFormBuilder, - @Inject(COMPLEX_FILTER_PREDICATE_DIALOG_COMPONENT_TOKEN) private complexFilterPredicateDialogComponent: ComponentType, - private dialog: MatDialog) { - } - - ngOnInit(): void { - this.filterListFormGroup = this.fb.group({ - predicates: this.fb.array([]) - }); + constructor(private fb: FormBuilder, + private dialog: MatDialog, + private destroyRef: DestroyRef) { this.filterListFormGroup.valueChanges.pipe( - takeUntil(this.destroy$) + takeUntilDestroyed(this.destroyRef) ).subscribe(() => this.updateModel()); } - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } - - get predicatesFormArray(): UntypedFormArray { - return this.filterListFormGroup.get('predicates') as UntypedFormArray; + get predicatesFormArray(): FormArray { + return this.filterListFormGroup.get('predicates') as FormArray; } registerOnChange(fn: any): void { @@ -135,22 +123,14 @@ export class AlarmRuleFilterPredicateListComponent implements ControlValueAccess } writeValue(predicates: Array): void { - if (predicates?.length === this.predicatesFormArray.length) { - this.predicatesFormArray.patchValue(predicates, {emitEvent: false}); - } else { - const predicateControls: Array = []; - if (predicates) { - for (const predicate of predicates) { - predicateControls.push(this.fb.control(predicate, [Validators.required])); - } - } - this.filterListFormGroup.setControl('predicates', this.fb.array(predicateControls), {emitEvent: false}); - if (this.disabled) { - this.filterListFormGroup.disable({emitEvent: false}); - } else { - this.filterListFormGroup.enable({emitEvent: false}); + const predicateControls: Array = []; + if (predicates) { + for (const predicate of predicates) { + predicateControls.push(this.fb.control(predicate, [Validators.required])); } } + this.predicatesFormArray.clear(); + predicateControls.forEach(predicate => this.predicatesFormArray.push(predicate)); } public removePredicate(index: number) { @@ -158,7 +138,7 @@ export class AlarmRuleFilterPredicateListComponent implements ControlValueAccess } public addPredicate(complex: boolean) { - const predicatesFormArray = this.filterListFormGroup.get('predicates') as UntypedFormArray; + const predicatesFormArray = this.filterListFormGroup.get('predicates') as FormArray; const predicate = this.createDefaultFilterPredicate(this.valueType, complex); let observable: Observable; if (complex) { @@ -217,23 +197,11 @@ export class AlarmRuleFilterPredicateListComponent implements ControlValueAccess arguments: this.arguments, } }).afterClosed().pipe( - map((result) => { - if (result) { - predicate = result; - return predicate; - } else { - return null; - } - }) + map(result => result) ); } private updateModel() { - const predicates: Array = this.filterListFormGroup.getRawValue().predicates; - if (predicates.length) { - this.propagateChange(predicates); - } else { - this.propagateChange(null); - } + this.propagateChange(this.filterListFormGroup.get('predicates').value); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.html index c27035ff0d..c7bcc92012 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.html @@ -18,19 +18,12 @@
- - - {{'alarm-rule.static' | translate}} - - - {{'alarm-rule.dynamic' | translate}} - + + {{'alarm-rule.static' | translate}} + {{'alarm-rule.dynamic' | translate}} - @if (mode === 'static') { + @if (!dynamicModeControl.value) { @switch (valueType) { @case (valueTypeEnum.STRING) { diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.ts index 707f482e6e..ae5208d103 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-value.component.ts @@ -17,10 +17,10 @@ import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, + FormBuilder, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormBuilder, ValidationErrors, Validator, ValidatorFn, @@ -30,7 +30,6 @@ import { EntityKeyValueType } from '@shared/models/query/query.models'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; import { AlarmRuleValue } from "@shared/models/alarm-rule.models"; -import { isDefinedAndNotNull } from "@core/utils"; import { FormControlsFrom } from "@shared/models/tenant.model"; @Component({ @@ -62,16 +61,18 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces filterPredicateValueFormGroup: FormGroup>>; - mode: 'static' | 'dynamic' = 'static'; + dynamicModeControl = this.fb.control(false); - private propagateChange = null; - private propagateChangePending = false; + argumentsList: Array; - constructor(private fb: UntypedFormBuilder, + private propagateChange= (v: any) => { }; + + constructor(private fb: FormBuilder, private destroyRef: DestroyRef) { } ngOnInit(): void { + this.argumentsList = this.arguments ? Object.keys(this.arguments): []; let defaultValue: string | number | boolean; let defaultValueValidators: ValidatorFn[]; switch (this.valueType) { @@ -94,42 +95,30 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces } this.filterPredicateValueFormGroup = this.fb.group({ staticValue: [defaultValue, defaultValueValidators], - dynamicValueArgument: [null, Validators.required] + dynamicValueArgument: ['', Validators.required] }); this.filterPredicateValueFormGroup.valueChanges.pipe( takeUntilDestroyed(this.destroyRef) ).subscribe(() => { this.updateModel(); }); + this.dynamicModeControl.valueChanges.pipe( + takeUntilDestroyed(this.destroyRef) + ).subscribe(value => this.updateValueModeValidators(value)) } - private updateValueModeValidators(mode: 'static' | 'dynamic'): void { - if (mode === 'static') { - this.filterPredicateValueFormGroup.get('staticValue').enable({emitEvent: false}); - this.filterPredicateValueFormGroup.get('dynamicValueArgument').disable({emitEvent: false}); - } else { + private updateValueModeValidators(isDynamicMode: boolean): void { + if (isDynamicMode) { this.filterPredicateValueFormGroup.get('staticValue').disable({emitEvent: false}); this.filterPredicateValueFormGroup.get('dynamicValueArgument').enable({emitEvent: false}); + } else { + this.filterPredicateValueFormGroup.get('staticValue').enable({emitEvent: false}); + this.filterPredicateValueFormGroup.get('dynamicValueArgument').disable({emitEvent: false}); } } - get argumentsList(): Array { - return this.arguments ? Object.keys(this.arguments): []; - } - registerOnChange(fn: any): void { this.propagateChange = fn; - if (this.propagateChangePending) { - this.propagateChangePending = false; - setTimeout(() => { - this.updateModel(); - }, 0); - } - } - - onModeChange(mode: 'static' | 'dynamic') { - this.mode = mode; - this.updateValueModeValidators(mode); } registerOnTouched(fn: any): void { @@ -142,18 +131,11 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces } writeValue(predicateValue: AlarmRuleValue): void { - this.propagateChangePending = false; this.filterPredicateValueFormGroup.patchValue(predicateValue, {emitEvent: false}); - this.mode = isDefinedAndNotNull(predicateValue.dynamicValueArgument) ? 'dynamic' : 'static'; - this.updateValueModeValidators(this.mode); + this.dynamicModeControl.patchValue(!!predicateValue.dynamicValueArgument?.length); } private updateModel() { - const predicateValue: AlarmRuleValue = this.filterPredicateValueFormGroup.value; - if (this.propagateChange) { - this.propagateChange(predicateValue); - } else { - this.propagateChangePending = true; - } + this.propagateChange(this.filterPredicateValueFormGroup.value); } } diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts index 97daba14f0..a49d4cf42e 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts @@ -14,13 +14,12 @@ /// limitations under the License. /// -import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, DestroyRef, forwardRef, Input } from '@angular/core'; import { ControlValueAccessor, - FormGroup, + FormBuilder, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormBuilder, ValidationErrors, Validator } from '@angular/forms'; @@ -41,7 +40,6 @@ import { AlarmRuleComplexFilterPredicateDialogComponent, AlarmRuleComplexFilterPredicateDialogData } from "@home/components/alarm-rules/filter/alarm-rule-complex-filter-predicate-dialog.component"; -import { FormControlsFrom } from "@shared/models/tenant.model"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; @Component({ @@ -61,7 +59,7 @@ import { CalculatedFieldArgument } from "@shared/models/calculated-field.models" } ] }) -export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, Validator, OnInit { +export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, Validator { @Input() valueType: EntityKeyValueType; @@ -69,7 +67,12 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, @Input() arguments: Record; - filterPredicateFormGroup: FormGroup>; + filterPredicateFormGroup = this.fb.group({ + operation: [], + ignoreCase: false, + predicates: [], + value: [] + }); type: FilterPredicateType; @@ -87,20 +90,11 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, booleanOperationEnum = BooleanOperation; booleanOperationTranslations = booleanOperationTranslationMap; - private propagateChange = null; + private propagateChange= (v: any) => { }; - constructor(private fb: UntypedFormBuilder, + constructor(private fb: FormBuilder, private dialog: MatDialog, private destroyRef: DestroyRef) { - } - - ngOnInit(): void { - this.filterPredicateFormGroup = this.fb.group({ - operation: [], - ignoreCase: false, - predicates: [], - value: [] - }); this.filterPredicateFormGroup.valueChanges.pipe( takeUntilDestroyed(this.destroyRef) ).subscribe(() => { @@ -127,12 +121,7 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, } private updateModel() { - let predicate: AlarmRuleFilterPredicate = null; - if (this.filterPredicateFormGroup.valid) { - predicate = this.filterPredicateFormGroup.getRawValue(); - predicate.type = this.type; - } - this.propagateChange(predicate); + this.propagateChange({type: this.type, ...this.filterPredicateFormGroup.value}); } public openComplexFilterDialog() { @@ -141,7 +130,7 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, disableClose: true, panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], data: { - complexPredicate: this.filterPredicateFormGroup.getRawValue() as ComplexAlarmRuleFilterPredicate, + complexPredicate: this.filterPredicateFormGroup.value as ComplexAlarmRuleFilterPredicate, valueType: this.valueType, isAdd: false, arguments: this.arguments, @@ -149,8 +138,7 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, }).afterClosed().subscribe( (result) => { if (result) { - this.filterPredicateFormGroup.patchValue(result, {emitEvent: false}); - this.updateModel(); + this.filterPredicateFormGroup.patchValue(result); } } ); diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.html index c9f3dd61c8..cb390b6c0b 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.html @@ -17,7 +17,7 @@ -->
diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.ts index 8a092e58cd..498b2a0a81 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-text.component.ts @@ -86,7 +86,7 @@ export class AlarmRuleFilterTextComponent { } } - requiredClass = false; + isRequired = false; public filterText: string; @@ -95,7 +95,7 @@ export class AlarmRuleFilterTextComponent { } private updateFilterText(value: AlarmRuleExpression) { - this.requiredClass = false; + this.isRequired = false; if (value && (value.expression || value.filters)) { if (value.type === AlarmRuleExpressionType.SIMPLE) { this.filterText = this.keyFiltersToText(this.translate, this.datePipe, value.filters, value.operation); @@ -108,7 +108,7 @@ export class AlarmRuleFilterTextComponent { } else { if (this.required) { this.filterText = this.addFilterPrompt; - this.requiredClass = true; + this.isRequired = true; } else { this.filterText = this.noFilterText; } diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts index fd104353b2..c0dbc23984 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts @@ -33,7 +33,7 @@ import { ArgumentEntityTypeTranslations, ArgumentType, ArgumentTypeTranslations, - CalculatedFieldArgumentValue, CFArgumentDynamicSourceType, + CalculatedFieldArgumentValue, getCalculatedFieldCurrentEntityFilter } from '@shared/models/calculated-field.models'; import { debounceTime, distinctUntilChanged, filter } from 'rxjs/operators'; @@ -144,7 +144,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit, AfterViewI this.argumentFormGroup.patchValue(this.argument, {emitEvent: false}); this.currentEntityFilter = getCalculatedFieldCurrentEntityFilter(this.entityName, this.entityId); this.updateEntityFilter(this.entityType, true); - this.updatedRefEntityIdState(this.entityType); + this.updatedRefEntityIdState(this.entityType, false); this.toggleByEntityKeyType(this.argument.refEntityKey?.type); this.setInitialEntityKeyType(); this.setInitialEntityType(); @@ -168,7 +168,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit, AfterViewI saveArgument(): void { const value = this.argumentFormGroup.value as CalculatedFieldArgumentValue; if (this.entityType === ArgumentEntityType.Owner) { - value.refDynamicSource = CFArgumentDynamicSourceType.CURRENT_OWNER; + value.refDynamicSourceConfiguration.type = ArgumentEntityType.Owner; } else if (this.entityType === ArgumentEntityType.Tenant) { value.refEntityId = new TenantId(this.tenantId) as any; } @@ -188,7 +188,9 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit, AfterViewI private updatedArgumentType(): void { let argumentType = ArgumentEntityType.Current; - if (this.argument.refEntityId?.entityType) { + if (this.argument.refDynamicSourceConfiguration?.type === ArgumentEntityType.Owner) { + argumentType = ArgumentEntityType.Owner; + } else if (this.argument.refEntityId?.entityType) { argumentType = this.argument.refEntityId.entityType; } this.argumentType.setValue(argumentType, {emitEvent: false}); @@ -312,9 +314,9 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit, AfterViewI }; } - private updatedRefEntityIdState(type: ArgumentEntityType): void { + private updatedRefEntityIdState(type: ArgumentEntityType, emitEvent = true): void { const isEntityWithId = !!type && type !== ArgumentEntityType.Tenant && type !== ArgumentEntityType.Current; - this.argumentFormGroup.get('refEntityId')[isEntityWithId ? 'enable' : 'disable'](); + this.argumentFormGroup.get('refEntityId')[isEntityWithId ? 'enable' : 'disable']({emitEvent}); if (!isEntityWithId) { this.entityNameSubject.next(null); } diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html index 555fc35f0c..15d2f4b09b 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html @@ -44,6 +44,8 @@
@if (argument.refEntityId?.entityType === ArgumentEntityType.Tenant) { {{ 'calculated-fields.argument-current-tenant' | translate }} + } @else if (argument.refDynamicSourceConfiguration?.type === ArgumentEntityType.Owner) { + {{ 'calculated-fields.argument-owner' | translate }} } @else if (argument.refEntityId?.id) { {{ entityTypeTranslations.get(argument.refEntityId.entityType).type | translate }} } @else { diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/debug-dialog/calculated-field-debug-dialog.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/debug-dialog/calculated-field-debug-dialog.component.html index 91a83af6d4..168657b8cb 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/debug-dialog/calculated-field-debug-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/debug-dialog/calculated-field-debug-dialog.component.html @@ -17,7 +17,7 @@ -->
-

{{ 'calculated-fields.debugging' | translate}}

+

{{ dialogTitle | translate}}