From 18b1f882ec6b1c85c9e958effc02f3e33644585d Mon Sep 17 00:00:00 2001 From: ArtemDzhereleiko Date: Fri, 28 Nov 2025 10:20:50 +0200 Subject: [PATCH] UI: Add missing for option for filters --- .../alarm-rules/alarm-rule.module.ts | 6 +- ...alarm-rule-condition-dialog.component.html | 6 +- ...f-alarm-rule-condition-dialog.component.ts | 32 +++- ...mplex-filter-predicate-dialog.component.ts | 11 +- .../alarm-rule-filter-dialog.component.ts | 2 +- .../alarm-rule-filter-list.component.html | 2 +- ...rm-rule-filter-predicate-list.component.ts | 26 +-- ...ter-predicate-no-data-value.component.html | 77 +++++++++ ...ilter-predicate-no-data-value.component.ts | 159 ++++++++++++++++++ ...rule-filter-predicate-value.component.html | 9 + ...m-rule-filter-predicate-value.component.ts | 26 ++- ...alarm-rule-filter-predicate.component.html | 17 +- .../alarm-rule-filter-predicate.component.ts | 86 +++++++--- .../alarm-rule-filter-text.component.ts | 34 ++-- .../app/shared/models/alarm-rule.models.ts | 94 ++++++++++- .../assets/locale/locale.constant-en_US.json | 8 +- 16 files changed, 519 insertions(+), 76 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-no-data-value.component.html create mode 100644 ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-no-data-value.component.ts diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule.module.ts b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule.module.ts index c02c11a170..52d91188bc 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule.module.ts +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule.module.ts @@ -50,6 +50,9 @@ import { AlarmRuleFilterDialogComponent } from "@home/components/alarm-rules/fil import { AlarmRuleDetailsDialogComponent } from "@home/components/alarm-rules/alarm-rule-details-dialog.component"; import { AlarmRuleFilterConfigComponent } from "@home/components/alarm-rules/alarm-rule-filter-config.component"; import { AlarmRuleTableHeaderComponent } from "@home/components/alarm-rules/alarm-rule-table-header.component"; +import { + AlarmRuleFilterPredicateNoDataValueComponent +} from "@home/components/alarm-rules/filter/alarm-rule-filter-predicate-no-data-value.component"; @NgModule({ declarations: [ @@ -69,7 +72,8 @@ import { AlarmRuleTableHeaderComponent } from "@home/components/alarm-rules/alar AlarmRuleComplexFilterPredicateDialogComponent, AlarmRuleDetailsDialogComponent, AlarmRuleFilterConfigComponent, - AlarmRuleTableHeaderComponent + AlarmRuleTableHeaderComponent, + AlarmRuleFilterPredicateNoDataValueComponent ], imports: [ CommonModule, 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 feafcaa0a4..5d94476e6e 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 @@ -78,10 +78,14 @@ alarm-rule.condition-type - + {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} + @if (isNoData) { + alarm-rule.condition-type-hint + } @if (conditionFormGroup.get('type').value == AlarmConditionType.DURATION) {
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 48b290b32c..3635d415d7 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 @@ -28,7 +28,8 @@ import { AlarmRuleCondition, AlarmRuleConditionType, AlarmRuleConditionTypeTranslationMap, - AlarmRuleExpressionType + AlarmRuleExpressionType, + AlarmRuleFilter } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument, @@ -102,6 +103,8 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent; + isNoData: boolean = false; + constructor(protected store: Store, protected router: Router, @Inject(MAT_DIALOG_DATA) public data: CfAlarmRuleConditionDialogData, @@ -136,12 +139,20 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent { this.updateValidators(type, true); }); + this.conditionFormGroup.get('expression.filters').valueChanges.pipe( + takeUntilDestroyed() + ).subscribe((filters) => { + this.checkIsNoData(filters); + }); + this.conditionFormGroup.get('expression.type').valueChanges.pipe( takeUntilDestroyed() ).subscribe((type) => { @@ -185,6 +196,25 @@ export class CfAlarmRuleConditionDialogComponent extends DialogComponent) { + this.isNoData = this.hasNoData(filters); + if (this.isNoData && this.conditionFormGroup.get('type').value !== AlarmRuleConditionType.SIMPLE) { + this.conditionFormGroup.get('type').patchValue(AlarmRuleConditionType.SIMPLE); + } + } + + private hasNoData(data: Array) { + const search = (filter) => { + if (!filter) return false; + if (Array.isArray(filter)) return filter.some(search); + if (typeof filter !== 'object') return false; + if (filter.type === 'NO_DATA') return true; + if (filter.predicates?.length) return filter.predicates.some(search); + return false; + }; + return search(data); + }; + private updateValidators(type: AlarmRuleConditionType, emitEvent = false) { switch (type) { case AlarmRuleConditionType.DURATION: 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 941ce326e1..d2c9389de1 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 @@ -24,10 +24,13 @@ import { DialogComponent } from '@app/shared/components/dialog.component'; import { ComplexOperation, complexOperationTranslationMap, - EntityKeyValueType, - FilterPredicateType + EntityKeyValueType } from '@shared/models/query/query.models'; -import { AlarmRuleFilterPredicate, ComplexAlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; +import { + AlarmRuleFilterPredicate, + AlarmRuleFilterPredicateType, + ComplexAlarmRuleFilterPredicate +} from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; export interface AlarmRuleComplexFilterPredicateDialogData { @@ -81,7 +84,7 @@ export class AlarmRuleComplexFilterPredicateDialogComponent extends save(): void { const predicate = this.complexFilterFormGroup.value as ComplexAlarmRuleFilterPredicate; - predicate.type = FilterPredicateType.COMPLEX; + predicate.type = AlarmRuleFilterPredicateType.COMPLEX; this.dialogRef.close(predicate); } } 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 6961524bdd..0858fd90ae 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 @@ -78,7 +78,7 @@ export class AlarmRuleFilterDialogComponent extends DialogComponent
{{ filterControl.value?.argument }}
-
{{ FilterPredicateTypeTranslationMap.get(filterControl.value?.predicates[0]?.type) | translate }}
+
{{ FilterPredicateTypeTranslationMap.get(filterControl.value?.valueType) | translate }}
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 036083c826..3300a1fceb 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 @@ -14,7 +14,7 @@ /// 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 { ControlValueAccessor, FormBuilder, @@ -49,7 +49,7 @@ import { FormControlsFrom } from "@shared/models/tenant.model"; } ] }) -export class AlarmRuleFilterPredicateValueComponent implements ControlValueAccessor, Validator, OnInit { +export class AlarmRuleFilterPredicateValueComponent implements ControlValueAccessor, Validator, OnInit, OnChanges { @Input() arguments: Record; @@ -110,6 +110,20 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces ).subscribe(value => this.updateValueModeValidators(value)); } + ngOnChanges(changes: SimpleChanges) { + if (changes.argumentInUse) { + const argumentInUseChanges = changes.argumentInUse; + if (!argumentInUseChanges.firstChange && argumentInUseChanges.currentValue !== argumentInUseChanges.previousValue) { + if (this.dynamicModeControl.value) { + if (this.argumentInUse === this.filterPredicateValueFormGroup.get('dynamicValueArgument').value) { + this.filterPredicateValueFormGroup.get('dynamicValueArgument').setErrors({argumentInUse: true}); + this.filterPredicateValueFormGroup.updateValueAndValidity(); + } + } + } + } + } + setDisabledState(isDisabled: boolean): void { if (isDisabled) { this.filterPredicateValueFormGroup.disable({emitEvent: false}); @@ -125,6 +139,12 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces if (isDynamicMode) { this.filterPredicateValueFormGroup.get('staticValue').disable({emitEvent: false}); this.filterPredicateValueFormGroup.get('dynamicValueArgument').enable(); + setTimeout(()=> { + if (this.filterPredicateValueFormGroup.get('dynamicValueArgument').value && this.argumentInUse === this.filterPredicateValueFormGroup.get('dynamicValueArgument').value) { + this.filterPredicateValueFormGroup.get('dynamicValueArgument').setErrors({argumentInUse: true}); + this.filterPredicateValueFormGroup.updateValueAndValidity(); + } + }, 0); } else { this.filterPredicateValueFormGroup.get('dynamicValueArgument').disable({emitEvent: false}); this.filterPredicateValueFormGroup.get('staticValue').enable(); @@ -146,7 +166,7 @@ export class AlarmRuleFilterPredicateValueComponent implements ControlValueAcces writeValue(predicateValue: AlarmRuleValue): void { this.filterPredicateValueFormGroup.patchValue(predicateValue, {emitEvent: false}); - this.dynamicModeControl.patchValue(!!predicateValue.dynamicValueArgument?.length, {emitEvent: false}); + this.dynamicModeControl.patchValue(!!predicateValue?.dynamicValueArgument?.length, {emitEvent: false}); } private updateModel() { diff --git a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.html b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.html index d73c222f9d..b297117b5d 100644 --- a/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.html @@ -27,9 +27,11 @@ - - {{ 'alarm-rule.ignore-case' | translate }} - + @if (filterPredicateFormGroup.get('operation').value !== stringOperation.NO_DATA) { + + {{ 'alarm-rule.ignore-case' | translate }} + + }
} @case (filterPredicateType.NUMERIC) { @@ -68,7 +70,14 @@ } } - @if (type !== filterPredicateType.COMPLEX) { + @if (filterPredicateFormGroup.get('operation').value === stringOperation.NO_DATA) { + + + } @else if (type !== filterPredicateType.COMPLEX) { { }; @@ -132,11 +134,45 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor, writeValue(predicate: AlarmRuleFilterPredicate): void { this.type = predicate.type; - this.filterPredicateFormGroup.patchValue(predicate, {emitEvent: false}); + if (predicate.type === AlarmRuleFilterPredicateType.NO_DATA) { + this.type = AlarmRuleFilterPredicateType[this.valueType]; + this.filterPredicateFormGroup.patchValue({operation: 'NO_DATA', duration: predicate}, {emitEvent: false}); + } else { + this.filterPredicateFormGroup.patchValue(predicate, {emitEvent: false}); + } } private updateModel() { - this.propagateChange({type: this.type, ...this.filterPredicateFormGroup.value}); + const predicate = this.filterPredicateFormGroup.value; + if (predicate.operation === 'NO_DATA') { + this.propagateChange(predicate.duration); + } else { + if (!predicate.value) { + switch (this.valueType) { + case EntityKeyValueType.STRING: + predicate.value = { + staticValue: '' + }; + break; + case EntityKeyValueType.NUMERIC: + predicate.value = { + staticValue: 0 + }; + break; + case EntityKeyValueType.DATE_TIME: + predicate.value = { + staticValue: Date.now() + }; + break; + case EntityKeyValueType.BOOLEAN: + predicate.value = { + staticValue: false + }; + break; + } + } + this.propagateChange({type: this.type, ...predicate}); + } } public openComplexFilterDialog() { 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 498b2a0a81..f824fdc876 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 @@ -16,25 +16,27 @@ import { Component, Input } from '@angular/core'; import { - booleanOperationTranslationMap, ComplexOperation, complexOperationTranslationMap, - EntityKeyValueType, - FilterPredicateType, - numericOperationTranslationMap, - stringOperationTranslationMap + EntityKeyValueType } from '@shared/models/query/query.models'; import { TranslateService } from '@ngx-translate/core'; import { DatePipe } from '@angular/common'; import { + alarmRuleBooleanOperationTranslationMap, AlarmRuleExpression, AlarmRuleExpressionType, AlarmRuleFilter, AlarmRuleFilterPredicate, + AlarmRuleFilterPredicateType, + alarmRuleNumericOperationTranslationMap, + AlarmRuleStringOperation, + alarmRuleStringOperationTranslationMap, ComplexAlarmRuleFilterPredicate } from "@shared/models/alarm-rule.models"; import { CalculatedFieldArgument } from "@shared/models/calculated-field.models"; import { coerceBoolean } from "@shared/decorators/coercion"; +import { timeUnitTranslationMap } from "@shared/models/time/time.models"; @Component({ selector: 'tb-alarm-rule-filter-text', @@ -137,21 +139,21 @@ export class AlarmRuleFilterTextComponent { const filterOperation: ComplexOperation = complexOperation ? complexOperation : (keyFilter.operation ?? ComplexOperation.AND); const predicates = keyFilterPredicates.map((keyFilterPredicate: AlarmRuleFilterPredicate) => { - if (keyFilterPredicate.type === FilterPredicateType.COMPLEX) { + if (keyFilterPredicate.type === AlarmRuleFilterPredicateType.COMPLEX) { const complexPredicate = keyFilterPredicate as ComplexAlarmRuleFilterPredicate; const complexOperation = complexPredicate.operation ?? ComplexOperation.AND; return this.filterPredicateToText(translate, datePipe, keyFilter, complexPredicate.predicates, complexOperation); } else { let operation: string; let value: string; - const val = keyFilterPredicate.value; + const val = keyFilterPredicate.type === AlarmRuleFilterPredicateType.NO_DATA ? keyFilterPredicate.duration : keyFilterPredicate.value; const dynamicValue = val?.dynamicValueArgument?.length; if (dynamicValue) { value = '' + val?.dynamicValueArgument + ''; } switch (keyFilterPredicate.type) { - case FilterPredicateType.STRING: - operation = translate.instant(stringOperationTranslationMap.get(keyFilterPredicate.operation)); + case AlarmRuleFilterPredicateType.STRING: + operation = translate.instant(alarmRuleStringOperationTranslationMap.get(keyFilterPredicate.operation)); if (keyFilterPredicate.ignoreCase) { operation += ' ' + translate.instant('filter.ignore-case'); } @@ -159,8 +161,8 @@ export class AlarmRuleFilterTextComponent { value = `'${keyFilterPredicate.value.staticValue}'`; } break; - case FilterPredicateType.NUMERIC: - operation = translate.instant(numericOperationTranslationMap.get(keyFilterPredicate.operation)); + case AlarmRuleFilterPredicateType.NUMERIC: + operation = translate.instant(alarmRuleNumericOperationTranslationMap.get(keyFilterPredicate.operation)); if (!dynamicValue) { if (keyFilter.valueType === EntityKeyValueType.DATE_TIME) { value = datePipe.transform(keyFilterPredicate.value.staticValue, 'yyyy-MM-dd HH:mm'); @@ -169,12 +171,18 @@ export class AlarmRuleFilterTextComponent { } } break; - case FilterPredicateType.BOOLEAN: - operation = translate.instant(booleanOperationTranslationMap.get(keyFilterPredicate.operation)); + case AlarmRuleFilterPredicateType.BOOLEAN: + operation = translate.instant(alarmRuleBooleanOperationTranslationMap.get(keyFilterPredicate.operation)); if (!dynamicValue) { value = translate.instant(keyFilterPredicate.value.staticValue ? 'value.true' : 'value.false'); } break; + case AlarmRuleFilterPredicateType.NO_DATA: + operation = translate.instant(alarmRuleStringOperationTranslationMap.get(AlarmRuleStringOperation.NO_DATA)); + if (!dynamicValue) { + value = keyFilterPredicate.duration.staticValue + ' ' + translate.instant(timeUnitTranslationMap.get(keyFilterPredicate.unit)).toLowerCase(); + } + break; } if (!dynamicValue) { value = `${value}`; diff --git a/ui-ngx/src/app/shared/models/alarm-rule.models.ts b/ui-ngx/src/app/shared/models/alarm-rule.models.ts index c9b549d78a..b92bf8bea6 100644 --- a/ui-ngx/src/app/shared/models/alarm-rule.models.ts +++ b/ui-ngx/src/app/shared/models/alarm-rule.models.ts @@ -118,7 +118,8 @@ export interface AlarmRulePredicateInfo { export type AlarmRuleFilterPredicate = StringAlarmRuleFilterPredicate | NumericAlarmRuleFilterPredicate | BooleanAlarmRuleFilterPredicate | - ComplexAlarmRuleFilterPredicate; + ComplexAlarmRuleFilterPredicate | + NoDataAlarmRuleFilterPredicate; export interface AlarmRuleValue { dynamicValueArgument?: string; @@ -126,26 +127,33 @@ export interface AlarmRuleValue { } export interface StringAlarmRuleFilterPredicate { - type: FilterPredicateType.STRING; - operation: StringOperation; + type: AlarmRuleFilterPredicateType.STRING; + operation: AlarmRuleStringOperation; value: AlarmRuleValue; ignoreCase: boolean; } export interface NumericAlarmRuleFilterPredicate { - type: FilterPredicateType.NUMERIC; - operation: NumericOperation; + type: AlarmRuleFilterPredicateType.NUMERIC; + operation: AlarmRuleNumericOperation; value: AlarmRuleValue; } export interface BooleanAlarmRuleFilterPredicate { - type: FilterPredicateType.BOOLEAN; - operation: BooleanOperation; + type: AlarmRuleFilterPredicateType.BOOLEAN; + operation: AlarmRuleBooleanOperation; value: AlarmRuleValue; } +export interface NoDataAlarmRuleFilterPredicate { + type: AlarmRuleFilterPredicateType.NO_DATA; + unit: TimeUnit, + operation: AlarmRuleStringOperation.NO_DATA | AlarmRuleNumericOperation.NO_DATA | AlarmRuleBooleanOperation.NO_DATA; + duration: AlarmRuleValue; +} + export interface BaseComplexFilterPredicate { - type: FilterPredicateType.COMPLEX; + type: AlarmRuleFilterPredicateType.COMPLEX; operation: ComplexOperation; predicates: Array; } @@ -157,3 +165,73 @@ export interface AlarmRuleFilterConfig { entityType?: EntityType; entities?: Array; } + +export enum AlarmRuleFilterPredicateType { + STRING = 'STRING', + NUMERIC = 'NUMERIC', + BOOLEAN = 'BOOLEAN', + COMPLEX = 'COMPLEX', + NO_DATA = 'NO_DATA' +} + +export enum AlarmRuleStringOperation { + EQUAL = 'EQUAL', + NOT_EQUAL = 'NOT_EQUAL', + NO_DATA = 'NO_DATA', + STARTS_WITH = 'STARTS_WITH', + ENDS_WITH = 'ENDS_WITH', + CONTAINS = 'CONTAINS', + NOT_CONTAINS = 'NOT_CONTAINS', + IN = 'IN', + NOT_IN = 'NOT_IN', +} + +export const alarmRuleStringOperationTranslationMap = new Map( + [ + [AlarmRuleStringOperation.EQUAL, 'filter.operation.equal'], + [AlarmRuleStringOperation.NOT_EQUAL, 'filter.operation.not-equal'], + [AlarmRuleStringOperation.STARTS_WITH, 'filter.operation.starts-with'], + [AlarmRuleStringOperation.ENDS_WITH, 'filter.operation.ends-with'], + [AlarmRuleStringOperation.CONTAINS, 'filter.operation.contains'], + [AlarmRuleStringOperation.NOT_CONTAINS, 'filter.operation.not-contains'], + [AlarmRuleStringOperation.IN, 'filter.operation.in'], + [AlarmRuleStringOperation.NOT_IN, 'filter.operation.not-in'], + [AlarmRuleStringOperation.NO_DATA, 'alarm-rule.missing-for'] + ] +); + +export enum AlarmRuleNumericOperation { + EQUAL = 'EQUAL', + NOT_EQUAL = 'NOT_EQUAL', + NO_DATA = 'NO_DATA', + GREATER = 'GREATER', + LESS = 'LESS', + GREATER_OR_EQUAL = 'GREATER_OR_EQUAL', + LESS_OR_EQUAL = 'LESS_OR_EQUAL' +} + +export const alarmRuleNumericOperationTranslationMap = new Map( + [ + [AlarmRuleNumericOperation.EQUAL, 'filter.operation.equal'], + [AlarmRuleNumericOperation.NOT_EQUAL, 'filter.operation.not-equal'], + [AlarmRuleNumericOperation.GREATER, 'filter.operation.greater'], + [AlarmRuleNumericOperation.LESS, 'filter.operation.less'], + [AlarmRuleNumericOperation.GREATER_OR_EQUAL, 'filter.operation.greater-or-equal'], + [AlarmRuleNumericOperation.LESS_OR_EQUAL, 'filter.operation.less-or-equal'], + [AlarmRuleNumericOperation.NO_DATA, 'alarm-rule.missing-for'] + ] +); + +export enum AlarmRuleBooleanOperation { + EQUAL = 'EQUAL', + NOT_EQUAL = 'NOT_EQUAL', + NO_DATA = 'NO_DATA', +} + +export const alarmRuleBooleanOperationTranslationMap = new Map( + [ + [AlarmRuleBooleanOperation.EQUAL, 'filter.operation.equal'], + [AlarmRuleBooleanOperation.NOT_EQUAL, 'filter.operation.not-equal'], + [AlarmRuleBooleanOperation.NO_DATA, 'alarm-rule.missing-for'] + ] +); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 538b3a8352..1899802715 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1466,6 +1466,7 @@ "enter-alarm-rule-condition-prompt": "Please add alarm rule condition", "edit-alarm-rule-condition": "Edit alarm rule condition", "condition-type": "Condition type", + "condition-type-hint": "\"Duration\" and \"Repeating\" options are not available when the \"Missing for\" operation is used in the filter.", "select-alarm-severity": "Select alarm severity", "add-create-alarm-rule-prompt": "Please add create alarm rule", "add-create-alarm-rule": "Add create condition", @@ -1497,7 +1498,12 @@ "no-alarm-rule-types-matching": "No alarm rule types matching '{{entitySubtype}}' were found.", "alarm-rule-type-list-empty": "No alarm rule types selected.", "alarm-rule-type-list": "Alarm rule type list", - "alarm-rule-entity-list": "Entity list" + "alarm-rule-entity-list": "Entity list", + "missing-for": "missing for", + "time-unit": "Unit", + "value-required": "Value is required.", + "min-value": "Value must be 0 or greater.", + "argument-in-use": "Argument is used as general argument." }, "ai-models": { "ai-models": "AI models",