Browse Source

UI: Fixed calculated field bugs and redesign alarm rule

pull/14542/head
ArtemDzhereleiko 10 months ago
parent
commit
bde1974362
  1. 10
      ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html
  2. 4
      ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.scss
  3. 40
      ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.ts
  4. 205
      ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html
  5. 2
      ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition.component.html
  6. 23
      ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html
  7. 2
      ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html
  8. 1
      ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.scss
  9. 1
      ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.scss
  10. 11
      ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts
  11. 1
      ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts
  12. 2
      ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html
  13. 4
      ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.scss
  14. 2
      ui-ngx/src/app/modules/home/components/calculated-fields/components/geofencing-configuration/calculated-field-geofencing-zone-groups-panel.component.ts
  15. 2
      ui-ngx/src/app/modules/home/components/calculated-fields/components/geofencing-configuration/calculated-field-geofencing-zone-groups-table.component.html
  16. 2
      ui-ngx/src/app/modules/home/components/calculated-fields/components/metrics/calculated-field-metrics-table.component.html
  17. 8
      ui-ngx/src/assets/locale/locale.constant-en_US.json

10
ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.html

@ -84,7 +84,7 @@
</div> </div>
<ng-container formGroupName="configuration"> <ng-container formGroupName="configuration">
<div class="tb-form-panel"> <div class="tb-form-panel">
<div class="tb-form-panel-title tb-required">{{ 'calculated-fields.arguments' | translate }}</div> <div class="tb-form-panel-title tb-required" [class.tb-disabled]="!fieldFormGroup.get('entityId.id').value || !fieldFormGroup.get('name').value">{{ 'calculated-fields.arguments' | translate }}</div>
<tb-calculated-field-arguments-table formControlName="arguments" <tb-calculated-field-arguments-table formControlName="arguments"
[entityId]="data.entityId || fieldFormGroup.get('entityId').value" [entityId]="data.entityId || fieldFormGroup.get('entityId').value"
[tenantId]="data.tenantId" [tenantId]="data.tenantId"
@ -94,14 +94,14 @@
[entityName]="entityName"/> [entityName]="entityName"/>
</div> </div>
<div class="tb-form-panel"> <div class="tb-form-panel">
<div class="tb-form-panel-title">{{ 'alarm-rule.create-conditions' | translate }}</div> <div class="tb-form-panel-title" [class.tb-disabled]="!disabledClearRuleButton">{{ 'alarm-rule.create-conditions' | translate }}</div>
<div class="flex flex-1 flex-col"> <div class="flex flex-1 flex-col">
<tb-create-cf-alarm-rules formControlName="createRules" [arguments]="arguments" [testScript]="onTestScript.bind(this)"> <tb-create-cf-alarm-rules formControlName="createRules" [arguments]="arguments" [testScript]="onTestScript.bind(this)">
</tb-create-cf-alarm-rules> </tb-create-cf-alarm-rules>
</div> </div>
</div> </div>
<div class="tb-form-panel"> <div class="tb-form-panel">
<div class="tb-form-panel-title">{{ 'alarm-rule.clear-condition' | translate }}</div> <div class="tb-form-panel-title" [class.tb-disabled]="!disabledClearRuleButton">{{ 'alarm-rule.clear-condition' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2 pb-2" <div class="flex flex-row items-center justify-start gap-2 pb-2"
[class.!hidden]="!configFormGroup.get('clearRule').value"> [class.!hidden]="!configFormGroup.get('clearRule').value">
<div class="clear-alarm-rule flex flex-1 flex-row"> <div class="clear-alarm-rule flex flex-1 flex-row">
@ -118,7 +118,7 @@
</button> </button>
</div> </div>
<div *ngIf="!configFormGroup.get('clearRule').value"> <div *ngIf="!configFormGroup.get('clearRule').value">
<span translate class="tb-prompt flex items-center justify-center">alarm-rule.no-clear-alarm-rule</span> <span translate class="tb-prompt text-base flex items-center justify-center">alarm-rule.no-clear-alarm-rule</span>
</div> </div>
<div [class.!hidden]="configFormGroup.get('clearRule').value"> <div [class.!hidden]="configFormGroup.get('clearRule').value">
<button mat-stroked-button color="primary" <button mat-stroked-button color="primary"
@ -131,7 +131,7 @@
</div> </div>
<div class="tb-form-panel no-gap"> <div class="tb-form-panel no-gap">
<mat-expansion-panel class="tb-settings" [expanded]="false"> <mat-expansion-panel class="tb-settings" [expanded]="false">
<mat-expansion-panel-header> <mat-expansion-panel-header [class.tb-disabled]="!disabledClearRuleButton">
{{ 'alarm-rule.advanced-settings' | translate }} {{ 'alarm-rule.advanced-settings' | translate }}
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>

4
ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.scss

@ -17,6 +17,10 @@
.calculated-field-dialog-container { .calculated-field-dialog-container {
width: 869px; width: 869px;
max-width: 100%; max-width: 100%;
.tb-disabled {
color: rgba(0, 0, 0, 0.38);
}
} }
.clear-alarm-rule { .clear-alarm-rule {

40
ui-ngx/src/app/modules/home/components/alarm-rules/alarm-rule-dialog.component.ts

@ -75,7 +75,7 @@ export class AlarmRuleDialogComponent extends DialogComponent<AlarmRuleDialogCom
id: [null as null | string, Validators.required], id: [null as null | string, Validators.required],
}), }),
configuration: this.fb.group({ configuration: this.fb.group({
arguments: this.fb.control({}), arguments: this.fb.control({}, Validators.required),
propagate: [false], propagate: [false],
propagateToOwner: [false], propagateToOwner: [false],
propagateToTenant: [false], propagateToTenant: [false],
@ -164,30 +164,6 @@ export class AlarmRuleDialogComponent extends DialogComponent<AlarmRuleDialogCom
this.configFormGroup.patchValue({clearRule: clearAlarmRule}); this.configFormGroup.patchValue({clearRule: clearAlarmRule});
} }
removeRelationType(key: string): void {
const keys: string[] = this.configFormGroup.get('propagateRelationTypes').value;
const index = keys.indexOf(key);
if (index >= 0) {
keys.splice(index, 1);
this.configFormGroup.get('propagateRelationTypes').setValue(keys);
}
}
addRelationType(event: MatChipInputEvent): void {
const input = event.chipInput.inputElement;
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);
}
}
if (input) {
input.value = '';
}
}
get fromGroupValue(): CalculatedField { get fromGroupValue(): CalculatedField {
return deepTrim(this.fieldFormGroup.value as CalculatedField); return deepTrim(this.fieldFormGroup.value as CalculatedField);
} }
@ -197,7 +173,7 @@ export class AlarmRuleDialogComponent extends DialogComponent<AlarmRuleDialogCom
} }
add(): void { add(): void {
if (this.fieldFormGroup.valid) { if (this.fieldFormGroup.valid && Object.keys(this.arguments ?? {}).length > 0) {
const alarmRule = { entityId: this.data.entityId, ...(this.data.value ?? {}), ...this.fromGroupValue}; const alarmRule = { entityId: this.data.entityId, ...(this.data.value ?? {}), ...this.fromGroupValue};
alarmRule.configuration.type = CalculatedFieldType.ALARM; alarmRule.configuration.type = CalculatedFieldType.ALARM;
@ -206,8 +182,8 @@ export class AlarmRuleDialogComponent extends DialogComponent<AlarmRuleDialogCom
.subscribe(calculatedField => this.dialogRef.close(calculatedField)); .subscribe(calculatedField => this.dialogRef.close(calculatedField));
} else { } else {
this.fieldFormGroup.get('name').markAsTouched(); this.fieldFormGroup.get('name').markAsTouched();
this.entityTypeSelect.markAsTouched(); this.entityTypeSelect?.markAsTouched();
this.entityAutocompleteComponent.markAsTouched(); this.entityAutocompleteComponent?.markAsTouched();
} }
} }
@ -235,10 +211,18 @@ export class AlarmRuleDialogComponent extends DialogComponent<AlarmRuleDialogCom
if (Object.keys(this.arguments ?? {}).length > 0) { if (Object.keys(this.arguments ?? {}).length > 0) {
this.fieldFormGroup.get('configuration.createRules').enable({emitEvent: false}); this.fieldFormGroup.get('configuration.createRules').enable({emitEvent: false});
this.fieldFormGroup.get('configuration.clearRule').enable({emitEvent: false}); this.fieldFormGroup.get('configuration.clearRule').enable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagate').enable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateToOwner').enable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateToTenant').enable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateRelationTypes').enable({emitEvent: false});
this.disabledClearRuleButton = true; this.disabledClearRuleButton = true;
} else { } else {
this.fieldFormGroup.get('configuration.createRules').disable({emitEvent: false}); this.fieldFormGroup.get('configuration.createRules').disable({emitEvent: false});
this.fieldFormGroup.get('configuration.clearRule').disable({emitEvent: false}); this.fieldFormGroup.get('configuration.clearRule').disable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagate').disable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateToOwner').disable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateToTenant').disable({emitEvent: false});
this.fieldFormGroup.get('configuration.propagateRelationTypes').disable({emitEvent: false});
this.disabledClearRuleButton = false; this.disabledClearRuleButton = false;
} }
} }

205
ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition-dialog.component.html

@ -19,12 +19,6 @@
<mat-toolbar color="primary"> <mat-toolbar color="primary">
<h2>{{ (readonly ? 'alarm-rule.alarm-rule-condition' : 'alarm-rule.edit-alarm-rule-condition') | translate }}</h2> <h2>{{ (readonly ? 'alarm-rule.alarm-rule-condition' : 'alarm-rule.edit-alarm-rule-condition') | translate }}</h2>
<span class="flex-1"></span> <span class="flex-1"></span>
<div formGroupName="expression" class="flex flex-row items-center justify-start gt-xs:gap-4" style="min-width: fit-content;">
<tb-toggle-select formControlName="type" appearance="fill-invert" selectMediaBreakpoint="xs">
<tb-toggle-option [value]="AlarmRuleExpressionType.SIMPLE">{{ 'alarm-rule.expression-type.simple' | translate }}</tb-toggle-option>
<tb-toggle-option [value]="AlarmRuleExpressionType.TBEL">{{ 'alarm-rule.expression-type.script' | translate }}</tb-toggle-option>
</tb-toggle-select>
</div>
<button mat-icon-button <button mat-icon-button
(click)="cancel()" (click)="cancel()"
type="button"> type="button">
@ -33,105 +27,116 @@
</mat-toolbar> </mat-toolbar>
<div mat-dialog-content> <div mat-dialog-content>
<div class="tb-form-panel no-padding no-border"> <div class="tb-form-panel no-padding no-border">
<div class="flex flex-1 flex-col" formGroupName="expression"> <div class="tb-form-panel stroked">
@if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) { <div class="flex flex-row items-center justify-between" formGroupName="expression">
<div class="tb-form-panel"> <div class="tb-form-panel-title">{{ 'alarm-rule.mode' | translate }}</div>
<div class="flex flex-row items-center justify-between"> <tb-toggle-select formControlName="type" selectMediaBreakpoint="xs">
<div class="tb-form-panel-title">{{ 'alarm-rule.argument-filters' | translate }}</div> <tb-toggle-option [value]="AlarmRuleExpressionType.SIMPLE">{{ 'alarm-rule.expression-type.simple' | translate }}</tb-toggle-option>
<tb-toggle-select formControlName="operation" <tb-toggle-option [value]="AlarmRuleExpressionType.TBEL">{{ 'alarm-rule.expression-type.script' | translate }}</tb-toggle-option>
selectMediaBreakpoint="xs"> </tb-toggle-select>
<tb-toggle-option [value]="ComplexOperation.AND">{{ complexOperationTranslationMap.get(ComplexOperation.AND) | translate }}</tb-toggle-option> </div>
<tb-toggle-option [value]="ComplexOperation.OR">{{ complexOperationTranslationMap.get(ComplexOperation.OR) | translate }}</tb-toggle-option> <div class="tb-form-panel no-padding no-border">
</tb-toggle-select> <div class="flex flex-1 flex-col" formGroupName="expression">
</div> @if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) {
<tb-alarm-rule-filter-list <div class="tb-form-panel stroked">
[operation]="conditionFormGroup.get('expression.operation').value" <div class="flex flex-row items-center justify-between">
[arguments]="arguments" <div class="tb-form-panel-title">{{ 'alarm-rule.argument-filters' | translate }}</div>
formControlName="filters"> <tb-toggle-select formControlName="operation"
</tb-alarm-rule-filter-list> selectMediaBreakpoint="xs">
</div> <tb-toggle-option [value]="ComplexOperation.AND">{{ complexOperationTranslationMap.get(ComplexOperation.AND) | translate }}</tb-toggle-option>
} @else { <tb-toggle-option [value]="ComplexOperation.OR">{{ complexOperationTranslationMap.get(ComplexOperation.OR) | translate }}</tb-toggle-option>
<div class="tb-form-panel no-gap"> </tb-toggle-select>
<div class="tb-form-panel-title tb-required"> </div>
{{ 'alarm-rule.script' | translate }} <tb-alarm-rule-filter-list
</div> [operation]="conditionFormGroup.get('expression.operation').value"
<tb-js-func formControlName="expression" [arguments]="arguments"
functionName="expression" formControlName="filters">
class="tb-alarm-rule-script" </tb-alarm-rule-filter-list>
[disableUndefinedCheck]="true"
[scriptLanguage]="scriptLanguage.TBEL"
[functionArgs]="functionArgs"
[highlightRules]="argumentsHighlightRules"
[editorCompleter]="argumentsEditorCompleter"
noValidate="true"
[helpPopupStyle]="{ width: '1200px' }"
helpId="alarm-rule/expression_fn">
<div toolbarPrefixButton
class="tb-primary-background tbel-script-lang-chip">{{ 'alarm-rule.tbel' | translate }}
</div> </div>
<button toolbarSuffixButton } @else {
mat-icon-button <div class="tb-form-panel no-gap stroked">
matTooltip="{{ 'calculated-fields.test-script-function' | translate }}" <div class="tb-form-panel-title tb-required">
matTooltipPosition="above" {{ 'alarm-rule.script' | translate }}
class="tb-mat-32" </div>
[disabled]="!argumentsList.length" <tb-js-func formControlName="expression"
(click)="onTestScript($event)"> functionName="expression"
<mat-icon class="material-icons" color="primary">bug_report</mat-icon> class="tb-alarm-rule-script"
</button> [disableUndefinedCheck]="true"
</tb-js-func> [scriptLanguage]="scriptLanguage.TBEL"
<div> [functionArgs]="functionArgs"
<button mat-button mat-raised-button color="primary" [highlightRules]="argumentsHighlightRules"
type="button" [editorCompleter]="argumentsEditorCompleter"
(click)="onTestScript($event)" noValidate="true"
[disabled]="!argumentsList.length"> [helpPopupStyle]="{ width: '1200px' }"
{{ 'calculated-fields.test-script-function' | translate }} helpId="alarm-rule/expression_fn">
</button> <div toolbarPrefixButton
</div> class="tb-primary-background tbel-script-lang-chip">{{ 'alarm-rule.tbel' | translate }}
</div>
<button toolbarSuffixButton
mat-icon-button
matTooltip="{{ 'calculated-fields.test-script-function' | translate }}"
matTooltipPosition="above"
class="tb-mat-32"
[disabled]="!argumentsList.length"
(click)="onTestScript($event)">
<mat-icon class="material-icons" color="primary">bug_report</mat-icon>
</button>
</tb-js-func>
<div>
<button mat-button mat-raised-button color="primary"
type="button"
(click)="onTestScript($event)"
[disabled]="!argumentsList.length">
{{ 'calculated-fields.test-script-function' | translate }}
</button>
</div>
</div>
}
</div> </div>
}
</div>
@if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) { @if (conditionFormGroup.get('expression.type').value === AlarmRuleExpressionType.SIMPLE) {
<div class="tb-form-panel no-gap"> <div class="tb-form-panel no-gap stroked">
<mat-expansion-panel class="tb-settings" [expanded]="true"> <mat-expansion-panel class="tb-settings" [expanded]="true">
<mat-expansion-panel-header> <mat-expansion-panel-header>
{{ 'alarm-rule.filter-preview' | translate }} {{ 'alarm-rule.filter-preview' | translate }}
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<div> <div>
@if (specText) { @if (specText) {
<span class="spec-text">{{ specText }}</span> <span class="spec-text">{{ specText }}</span>
} }
@if (conditionFormGroup.get('expression.filters').value?.length) { @if (conditionFormGroup.get('expression.filters').value?.length) {
<tb-alarm-rule-filter-text [alarmRuleExpression]="conditionFormGroup.get('expression').value" <tb-alarm-rule-filter-text [alarmRuleExpression]="conditionFormGroup.get('expression').value"
[arguments]="arguments" [arguments]="arguments"
class="flex-1" class="flex-1"
[nowrap]="false" [nowrap]="false"
required> required>
</tb-alarm-rule-filter-text> </tb-alarm-rule-filter-text>
} @else { } @else {
<span class="tb-prompt justify-center">{{ 'alarm-rule.no-filter-preview' | translate }}</span> <span class="tb-prompt text-base justify-center">{{ 'alarm-rule.no-filter-preview' | translate }}</span>
} }
</div> </div>
</ng-template> </ng-template>
</mat-expansion-panel> </mat-expansion-panel>
</div> </div>
} }
</div>
</div>
<section class="tb-form-panel"> <section class="tb-form-panel stroked">
<div class="tb-form-panel-title">{{ 'alarm-rule.condition-settings' | translate }}</div> <div class="flex flex-row items-center justify-between">
<mat-form-field class="mat-block" hideRequiredMarker appearance="outline" subscriptSizing="dynamic"> <div class="tb-form-panel-title">{{ 'alarm-rule.type' | translate }}</div>
<mat-label translate>alarm-rule.condition-type</mat-label> <tb-toggle-select formControlName="type" selectMediaBreakpoint="xs" [disabled]="isNoData">
<mat-select formControlName="type" required> <tb-toggle-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType">
<mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType"
[disabled]="isNoData ? alarmConditionType === AlarmConditionType.REPEATING || alarmConditionType === AlarmConditionType.DURATION : false">
{{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }}
</mat-option> </tb-toggle-option>
</mat-select> </tb-toggle-select>
@if (isNoData) { </div>
<mat-hint translate>alarm-rule.condition-type-hint</mat-hint> @if (isNoData) {
} <div class="tb-form-hint tb-primary-fill max-args-warning flex items-center gap-2">
</mat-form-field> <span>{{ 'alarm-rule.condition-type-hint' | translate }}</span>
</div>
}
@if (conditionFormGroup.get('type').value == AlarmConditionType.DURATION) { @if (conditionFormGroup.get('type').value == AlarmConditionType.DURATION) {
<div class="tb-form-panel stroked no-padding-bottom"> <div class="tb-form-panel stroked no-padding-bottom">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">

2
ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-rule-condition.component.html

@ -31,7 +31,7 @@
[nowrap]="true" [nowrap]="true"
[specText]="specText" [specText]="specText"
required required
addFilterPrompt="{{ (isClearCondition ? 'alarm-rule.enter-alarm-rule-clear-condition-prompt' :'alarm-rule.enter-alarm-rule-condition-prompt') | translate }}"> addFilterPrompt="{{ 'alarm-rule.enter-alarm-rule-condition-prompt' | translate }}">
</tb-alarm-rule-filter-text> </tb-alarm-rule-filter-text>
<mat-icon [color]="disabled ? '' : (conditionSet() && this.filtersArgumentsValid ? 'primary' : 'warn')" <mat-icon [color]="disabled ? '' : (conditionSet() && this.filtersArgumentsValid ? 'primary' : 'warn')"
class="tb-mat-20 tb-alarm-rule-schedule-edit-icon"> class="tb-mat-20 tb-alarm-rule-schedule-edit-icon">

23
ui-ngx/src/app/modules/home/components/alarm-rules/cf-alarm-schedule-dialog.component.html

@ -19,10 +19,6 @@
<mat-toolbar color="primary"> <mat-toolbar color="primary">
<h2>{{ (readonly ? 'alarm-rule.schedule-title' : 'alarm-rule.edit-schedule') | translate }}</h2> <h2>{{ (readonly ? 'alarm-rule.schedule-title' : 'alarm-rule.edit-schedule') | translate }}</h2>
<span class="flex-1"></span> <span class="flex-1"></span>
<tb-toggle-select [formControl]="dynamicModeControl" appearance="fill-invert" selectMediaBreakpoint="xs">
<tb-toggle-option [value]="false">{{ 'alarm-rule.static-schedule' | translate }}</tb-toggle-option>
<tb-toggle-option [value]="true">{{ 'alarm-rule.dynamic-schedule' | translate }}</tb-toggle-option>
</tb-toggle-select>
<button mat-icon-button <button mat-icon-button
(click)="cancel()" (click)="cancel()"
type="button"> type="button">
@ -30,10 +26,21 @@
</button> </button>
</mat-toolbar> </mat-toolbar>
<div mat-dialog-content> <div mat-dialog-content>
<tb-cf-alarm-schedule [arguments]="arguments" <div class="tb-form-panel no-padding no-border">
[dynamicMode]="dynamicModeControl.value" <div class="tb-form-panel stroked no-padding-bottom">
[formControl]="alarmScheduleControl"> <div class="flex flex-row items-center justify-between">
</tb-cf-alarm-schedule> <div class="tb-form-panel-title">{{ 'alarm-rule.mode' | translate }}</div>
<tb-toggle-select [formControl]="dynamicModeControl" selectMediaBreakpoint="xs">
<tb-toggle-option [value]="false">{{ 'alarm-rule.static-schedule' | translate }}</tb-toggle-option>
<tb-toggle-option [value]="true">{{ 'alarm-rule.dynamic-schedule' | translate }}</tb-toggle-option>
</tb-toggle-select>
</div>
<tb-cf-alarm-schedule [arguments]="arguments"
[dynamicMode]="dynamicModeControl.value"
[formControl]="alarmScheduleControl">
</tb-cf-alarm-schedule>
</div>
</div>
</div> </div>
<div mat-dialog-actions class="justify-end"> <div mat-dialog-actions class="justify-end">
<button mat-button color="primary" <button mat-button color="primary"

2
ui-ngx/src/app/modules/home/components/alarm-rules/create-cf-alarm-rules.component.html

@ -49,7 +49,7 @@
</div> </div>
} }
@if (!createAlarmRulesFormArray().controls.length) { @if (!createAlarmRulesFormArray().controls.length) {
<span translate class="flex items-center justify-center tb-prompt required" [class.required]="!disabled"> <span translate class="flex items-center justify-center tb-prompt text-base required" [class.required]="!disabled">
alarm-rule.add-create-alarm-rule-prompt alarm-rule.add-create-alarm-rule-prompt
</span> </span>
} }

1
ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-list.component.scss

@ -25,6 +25,7 @@
max-height: 300px; max-height: 300px;
.no-data-found { .no-data-found {
height: 50px; height: 50px;
font-size: 16px;
} }
&-divider { &-divider {

1
ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate-list.component.scss

@ -22,6 +22,7 @@
.predicate-list { .predicate-list {
.no-data-found { .no-data-found {
height: 50px; height: 50px;
font-size: 16px;
} }
} }

11
ui-ngx/src/app/modules/home/components/alarm-rules/filter/alarm-rule-filter-predicate.component.ts

@ -150,6 +150,13 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor,
this.filterPredicateFormGroup.disable({emitEvent: false}); this.filterPredicateFormGroup.disable({emitEvent: false});
} else { } else {
this.filterPredicateFormGroup.enable({emitEvent: false}); this.filterPredicateFormGroup.enable({emitEvent: false});
if (this.filterPredicateFormGroup.get('operation').value === 'NO_DATA') {
this.filterPredicateFormGroup.get('duration').enable({emitEvent: false});
this.filterPredicateFormGroup.get('value').disable({emitEvent: false});
} else {
this.filterPredicateFormGroup.get('duration').disable({emitEvent: false});
this.filterPredicateFormGroup.get('value').enable({emitEvent: false});
}
} }
} }
@ -170,12 +177,8 @@ export class AlarmRuleFilterPredicateComponent implements ControlValueAccessor,
} }
if (predicate.type === AlarmRuleFilterPredicateType.NO_DATA) { if (predicate.type === AlarmRuleFilterPredicateType.NO_DATA) {
this.type = AlarmRuleFilterPredicateType[this.valueType]; this.type = AlarmRuleFilterPredicateType[this.valueType];
this.filterPredicateFormGroup.get('duration').enable({emitEvent: false});
this.filterPredicateFormGroup.get('value').disable({emitEvent: false});
this.filterPredicateFormGroup.patchValue({operation: 'NO_DATA', duration: predicate}, {emitEvent: false}); this.filterPredicateFormGroup.patchValue({operation: 'NO_DATA', duration: predicate}, {emitEvent: false});
} else { } else {
this.filterPredicateFormGroup.get('duration').disable({emitEvent: false});
this.filterPredicateFormGroup.get('value').enable({emitEvent: false});
this.filterPredicateFormGroup.patchValue(predicate, {emitEvent: false}); this.filterPredicateFormGroup.patchValue(predicate, {emitEvent: false});
} }
} }

1
ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-argument-panel.component.ts

@ -318,6 +318,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit, AfterViewI
).subscribe((key) => { ).subscribe((key) => {
if (this.argumentFormGroup.get('argumentName').pristine) { if (this.argumentFormGroup.get('argumentName').pristine) {
this.argumentFormGroup.get('argumentName').setValue(key); this.argumentFormGroup.get('argumentName').setValue(key);
this.argumentFormGroup.get('argumentName').markAsTouched({emitEvent: false});
} }
}); });
} }

2
ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.html

@ -128,7 +128,7 @@
</div> </div>
<div [class.!hidden]="(dataSource.isEmpty() | async) === false" <div [class.!hidden]="(dataSource.isEmpty() | async) === false"
[class.required]="!disable" [class.required]="!disable"
class="tb-prompt flex flex-1 items-end justify-center tb-prompt required"> class="tb-prompt flex flex-1 items-end justify-center text-base required">
{{ 'calculated-fields.no-arguments' | translate }} {{ 'calculated-fields.no-arguments' | translate }}
</div> </div>
<div class="flex h-9 justify-between"> <div class="flex h-9 justify-between">

4
ui-ngx/src/app/modules/home/components/calculated-fields/components/calculated-field-arguments/calculated-field-arguments-table.component.scss

@ -41,6 +41,10 @@
} }
} }
.no-data-found {
font-size: 16px;
}
.max-args-warning { .max-args-warning {
.mat-icon { .mat-icon {
color: #FAA405; color: #FAA405;

2
ui-ngx/src/app/modules/home/components/calculated-fields/components/geofencing-configuration/calculated-field-geofencing-zone-groups-panel.component.ts

@ -278,7 +278,7 @@ export class CalculatedFieldGeofencingZoneGroupsPanelComponent implements OnInit
this.enableAutocomplete = (this.entityId.entityType === EntityType.DEVICE_PROFILE || this.entityId.entityType === EntityType.ASSET_PROFILE) && type === ArgumentEntityType.Owner; this.enableAutocomplete = (this.entityId.entityType === EntityType.DEVICE_PROFILE || this.entityId.entityType === EntityType.ASSET_PROFILE) && type === ArgumentEntityType.Owner;
this.geofencingFormGroup.get('refEntityId').get('id').setValue(null); this.geofencingFormGroup.get('refEntityId').get('id').setValue(null);
this.geofencingFormGroup.get('perimeterKeyName').reset(''); this.geofencingFormGroup.get('perimeterKeyName').reset('');
const isEntityWithId = !!type && ![ArgumentEntityType.Tenant, ArgumentEntityType.Current, ArgumentEntityType.Owner].includes(type); const isEntityWithId = !!type && ![ArgumentEntityType.Tenant, ArgumentEntityType.Current, ArgumentEntityType.Owner, ArgumentEntityType.RelationQuery].includes(type);
this.geofencingFormGroup.get('refEntityId').get('id')[isEntityWithId ? 'enable' : 'disable'](); this.geofencingFormGroup.get('refEntityId').get('id')[isEntityWithId ? 'enable' : 'disable']();
if (!isEntityWithId) { if (!isEntityWithId) {
this.entityNameSubject.next(null); this.entityNameSubject.next(null);

2
ui-ngx/src/app/modules/home/components/calculated-fields/components/geofencing-configuration/calculated-field-geofencing-zone-groups-table.component.html

@ -128,7 +128,7 @@
} }
</div> </div>
<div [class.!hidden]="(dataSource.isEmpty() | async) === false" <div [class.!hidden]="(dataSource.isEmpty() | async) === false"
class="tb-prompt flex flex-1 items-end justify-center tb-prompt required"> class="tb-prompt flex flex-1 items-end justify-center text-base required">
{{ 'calculated-fields.no-zone-configured' | translate }} {{ 'calculated-fields.no-zone-configured' | translate }}
</div> </div>
<div class="flex h-9 justify-between"> <div class="flex h-9 justify-between">

2
ui-ngx/src/app/modules/home/components/calculated-fields/components/metrics/calculated-field-metrics-table.component.html

@ -102,7 +102,7 @@
</table> </table>
</div> </div>
<div [class.!hidden]="(dataSource.isEmpty() | async) === false" <div [class.!hidden]="(dataSource.isEmpty() | async) === false"
class="tb-prompt flex flex-1 items-end justify-center required"> class="tb-prompt flex flex-1 items-end justify-center text-base required">
{{ 'calculated-fields.metrics.no-metrics-configured' | translate }} {{ 'calculated-fields.metrics.no-metrics-configured' | translate }}
</div> </div>
<div class="flex h-9 justify-between"> <div class="flex h-9 justify-between">

8
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1403,7 +1403,7 @@
"target-entity": "Target entity", "target-entity": "Target entity",
"target-entities": "Target entities", "target-entities": "Target entities",
"alarm-type": "Alarm type", "alarm-type": "Alarm type",
"alarm-type-hint": "Unique identifier (e.g., HighTemperatureAlarm) across the scope of the alarm originator (Device, Asset, etc.) to prevent conflicts.", "alarm-type-hint": "Unique identifier (e.g., HighTempAlarm) across the scope of the alarm originator (Device, Asset, etc.) to prevent conflicts.",
"alarm-type-required": "Alarm type is required.", "alarm-type-required": "Alarm type is required.",
"alarm-type-pattern": "Alarm type is invalid.", "alarm-type-pattern": "Alarm type is invalid.",
"alarm-type-max-length": "Alarm type should be less than 256 characters.", "alarm-type-max-length": "Alarm type should be less than 256 characters.",
@ -1513,8 +1513,8 @@
"condition-repeating-value-range": "Count of events should be in a range from 1 to 2147483647.", "condition-repeating-value-range": "Count of events should be in a range from 1 to 2147483647.",
"condition-repeating-value-pattern": "Count of events should be integers.", "condition-repeating-value-pattern": "Count of events should be integers.",
"condition-repeating-value-required": "Count of events is required.", "condition-repeating-value-required": "Count of events is required.",
"create-conditions": "Alarm Trigger Conditions", "create-conditions": "Trigger conditions",
"clear-condition": "Alarm Clear Condition", "clear-condition": "Clear condition",
"no-clear-alarm-rule": "No clear condition configured.", "no-clear-alarm-rule": "No clear condition configured.",
"advanced-settings": "Advanced settings", "advanced-settings": "Advanced settings",
"propagate-alarm": "Propagate alarm to related entities", "propagate-alarm": "Propagate alarm to related entities",
@ -1532,6 +1532,8 @@
"alarm-rule-entity-list": "Entity list", "alarm-rule-entity-list": "Entity list",
"missing-for": "missing for", "missing-for": "missing for",
"time-unit": "Unit", "time-unit": "Unit",
"mode": "Mode",
"type": "Type",
"value-required": "Value is required.", "value-required": "Value is required.",
"min-value": "Value must be 0 or greater.", "min-value": "Value must be 0 or greater.",
"argument-in-use": "Argument is used as general argument.", "argument-in-use": "Argument is used as general argument.",

Loading…
Cancel
Save