From 77d2c786afa1cd7386775a84e9b58adaecaf8da6 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 5 Oct 2020 18:18:46 +0300 Subject: [PATCH] UI: Added device profile alarm conditional type --- .../profile/DurationAlarmConditionSpec.java | 2 + .../profile/RepeatingAlarmConditionSpec.java | 2 + .../profile/SimpleAlarmConditionSpec.java | 2 + .../alarm/alarm-rule-condition.component.html | 1 - .../profile/alarm/alarm-rule.component.html | 142 ++++++++++-------- .../profile/alarm/alarm-rule.component.scss | 29 +--- .../profile/alarm/alarm-rule.component.ts | 92 ++++++++---- .../alarm/create-alarm-rules.component.html | 2 +- .../alarm/create-alarm-rules.component.scss | 4 - ui-ngx/src/app/shared/models/device.models.ts | 24 ++- .../assets/locale/locale.constant-en_US.json | 14 +- 11 files changed, 184 insertions(+), 130 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java index c6d54ca3ad..459274aa59 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DurationAlarmConditionSpec.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.common.data.device.profile; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import java.util.concurrent.TimeUnit; @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class DurationAlarmConditionSpec implements AlarmConditionSpec { private TimeUnit unit; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java index 808c673cb9..e79a6ff265 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/RepeatingAlarmConditionSpec.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.common.data.device.profile; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import java.util.concurrent.TimeUnit; @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class RepeatingAlarmConditionSpec implements AlarmConditionSpec { private int count; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java index e96d5dda29..547044581a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SimpleAlarmConditionSpec.java @@ -15,9 +15,11 @@ */ package org.thingsboard.server.common.data.device.profile; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class SimpleAlarmConditionSpec implements AlarmConditionSpec { @Override public AlarmConditionSpecType getType() { diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition.component.html index 2160b6b04a..170182ded3 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition.component.html @@ -17,7 +17,6 @@ -->
-
device-profile.alarm-rule-condition
-
- - -
-
-
device-profile.condition-duration
- - - -
-
- -
- - - - - {{ 'device-profile.condition-duration-value-required' | translate }} - - - {{ 'device-profile.condition-duration-value-range' | translate }} - - - {{ 'device-profile.condition-duration-value-range' | translate }} - - - - - - - {{ timeUnitTranslations.get(timeUnit) | translate }} + + + + +
+
+ + device-profile.condition-type + + + {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} - - {{ 'device-profile.condition-duration-time-unit-required' | translate }} + + {{ 'device-profile.condition-type-required' | translate }} +
+ + + + + {{ 'device-profile.condition-duration-value-required' | translate }} + + + {{ 'device-profile.condition-duration-value-range' | translate }} + + + {{ 'device-profile.condition-duration-value-range' | translate }} + + + {{ 'device-profile.condition-duration-value-pattern' | translate }} + + + + + + + {{ timeUnitTranslations.get(timeUnit) | translate }} + + + + {{ 'device-profile.condition-duration-time-unit-required' | translate }} + + +
+
+ + + + + {{ 'device-profile.condition-repeating-value-required' | translate }} + + + {{ 'device-profile.condition-repeating-value-range' | translate }} + + + {{ 'device-profile.condition-repeating-value-range' | translate }} + + + {{ 'device-profile.condition-repeating-value-pattern' | translate }} + + +
-
-
-
- - - -
-
device-profile.alarm-rule-details
-
-
-
- - device-profile.alarm-details - - -
+ + + +
{{ 'device-profile.schedule' | translate }}
+
+ + + device-profile.alarm-details + + + +
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.scss b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.scss index ed8d08806f..8af986af69 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.scss +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.scss @@ -14,33 +14,8 @@ * limitations under the License. */ :host { - .tb-condition-duration { - padding: 8px; - border: 1px groove rgba(0, 0, 0, .25); - border-radius: 4px; - } - .mat-expansion-panel.advanced-settings { - box-shadow: none; - border: none; - padding: 0; - } -} - -:host ::ng-deep { - .mat-expansion-panel.advanced-settings { - .mat-expansion-panel-body { - padding: 0; - } - } - .mat-form-field.duration-value-field { - .mat-form-field-infix { - width: 120px; - } - } - .mat-form-field.duration-unit-field { - .mat-form-field-infix { - width: 120px; - } + .row { + margin-top: 1em; } } diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts index 74365dc8a8..a96b27a76e 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { ChangeDetectorRef, Component, forwardRef, Input, NgZone, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, FormBuilder, @@ -25,9 +25,9 @@ import { Validator, Validators } from '@angular/forms'; -import { AlarmRule } from '@shared/models/device.models'; +import { AlarmConditionType, AlarmConditionTypeTranslationMap, AlarmRule } from '@shared/models/device.models'; import { MatDialog } from '@angular/material/dialog'; -import { TimeUnit, timeUnitTranslationMap } from '../../../../../shared/models/time/time.models'; +import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; @Component({ @@ -51,6 +51,9 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat timeUnits = Object.keys(TimeUnit); timeUnitTranslations = timeUnitTranslationMap; + alarmConditionTypes = Object.keys(AlarmConditionType); + AlarmConditionType = AlarmConditionType; + alarmConditionTypeTranslation = AlarmConditionTypeTranslationMap; @Input() disabled: boolean; @@ -64,8 +67,6 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat this.requiredValue = coerceBooleanProperty(value); } - enableDuration = false; - private modelValue: AlarmRule; alarmRuleFormGroup: FormGroup; @@ -87,11 +88,18 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat this.alarmRuleFormGroup = this.fb.group({ condition: this.fb.group({ condition: [null, Validators.required], - durationUnit: [null], - durationValue: [null] + spec: this.fb.group({ + type: [AlarmConditionType.SIMPLE, Validators.required], + unit: [{value: null, disable: true}, Validators.required], + value: [{value: null, disable: true}, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]], + count: [{value: null, disable: true}, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]] + }) }, Validators.required), alarmDetails: [null] }); + this.alarmRuleFormGroup.get('condition.spec.type').valueChanges.subscribe((type) => { + this.updateValidators(type, true, true); + }); this.alarmRuleFormGroup.valueChanges.subscribe(() => { this.updateModel(); }); @@ -108,9 +116,13 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat writeValue(value: AlarmRule): void { this.modelValue = value; - this.enableDuration = value && !!value.condition.durationValue; + if (this.modelValue?.condition?.spec === null) { + this.modelValue.condition.spec = { + type: AlarmConditionType.SIMPLE + }; + } this.alarmRuleFormGroup.reset(this.modelValue || undefined, {emitEvent: false}); - this.updateValidators(); + this.updateValidators(this.modelValue?.condition?.spec?.type); } public validate(c: FormControl) { @@ -121,31 +133,45 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat }; } - public enableDurationChanged(enableDuration) { - this.enableDuration = enableDuration; - this.updateValidators(true, true); - } - - private updateValidators(resetDuration = false, emitEvent = false) { - if (this.enableDuration) { - this.alarmRuleFormGroup.get('condition').get('durationValue') - .setValidators([Validators.required, Validators.min(1), Validators.max(2147483647)]); - this.alarmRuleFormGroup.get('condition').get('durationUnit') - .setValidators([Validators.required]); - } else { - this.alarmRuleFormGroup.get('condition').get('durationValue') - .setValidators([]); - this.alarmRuleFormGroup.get('condition').get('durationUnit') - .setValidators([]); - if (resetDuration) { - this.alarmRuleFormGroup.get('condition').patchValue({ - durationValue: null, - durationUnit: null - }); - } + private updateValidators(type: AlarmConditionType, resetDuration = false, emitEvent = false) { + switch (type) { + case AlarmConditionType.DURATION: + this.alarmRuleFormGroup.get('condition.spec.value').enable(); + this.alarmRuleFormGroup.get('condition.spec.unit').enable(); + this.alarmRuleFormGroup.get('condition.spec.count').disable(); + if (resetDuration) { + this.alarmRuleFormGroup.get('condition.spec').patchValue({ + count: null + }); + } + break; + case AlarmConditionType.REPEATING: + this.alarmRuleFormGroup.get('condition.spec.count').enable(); + this.alarmRuleFormGroup.get('condition.spec.value').disable(); + this.alarmRuleFormGroup.get('condition.spec.unit').disable(); + if (resetDuration) { + this.alarmRuleFormGroup.get('condition.spec').patchValue({ + value: null, + unit: null + }); + } + break; + case AlarmConditionType.SIMPLE: + this.alarmRuleFormGroup.get('condition.spec.value').disable(); + this.alarmRuleFormGroup.get('condition.spec.unit').disable(); + this.alarmRuleFormGroup.get('condition.spec.count').disable(); + if (resetDuration) { + this.alarmRuleFormGroup.get('condition.spec').patchValue({ + value: null, + unit: null, + count: null + }); + } + break; } - this.alarmRuleFormGroup.get('condition').get('durationValue').updateValueAndValidity({emitEvent}); - this.alarmRuleFormGroup.get('condition').get('durationUnit').updateValueAndValidity({emitEvent}); + this.alarmRuleFormGroup.get('condition.spec.value').updateValueAndValidity({emitEvent}); + this.alarmRuleFormGroup.get('condition.spec.unit').updateValueAndValidity({emitEvent}); + this.alarmRuleFormGroup.get('condition.spec.count').updateValueAndValidity({emitEvent}); } private updateModel() { diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html index 121df96386..d83fc44807 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html @@ -19,7 +19,7 @@
-
+
alarm.severity ( + [ + [AlarmConditionType.SIMPLE, 'device-profile.condition-type-simple'], + [AlarmConditionType.DURATION, 'device-profile.condition-type-duration'], + [AlarmConditionType.REPEATING, 'device-profile.condition-type-repeating'] + ] +); + +export interface AlarmConditionSpec{ + type?: AlarmConditionType; + unit?: TimeUnit; + value?: number; + count?: number; +} + export interface AlarmCondition { condition: Array; - durationUnit?: TimeUnit; - durationValue?: number; + spec?: AlarmConditionSpec; } export interface AlarmRule { 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 64f5da5dfb..8d07a597bd 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -834,6 +834,7 @@ "condition-duration-value": "Duration value", "condition-duration-time-unit": "Time unit", "condition-duration-value-range": "Duration value should be in a range from 1 to 2147483647.", + "condition-duration-value-pattern": "Duration value should be integers.", "condition-duration-value-required": "Duration value is required.", "condition-duration-time-unit-required": "Time unit is required.", "advanced-settings": "Advanced settings", @@ -844,7 +845,18 @@ "alarm-details": "Alarm details", "alarm-rule-condition": "Alarm rule condition", "enter-alarm-rule-condition-prompt": "Please add alarm rule condition", - "edit-alarm-rule-condition": "Edit alarm rule condition" + "edit-alarm-rule-condition": "Edit alarm rule condition", + "condition": "Condition", + "condition-type": "Condition type", + "condition-type-simple": "Simple", + "condition-type-duration": "Duration", + "condition-type-repeating": "Repeating", + "condition-type-required": "Condition type is required.", + "condition-repeating-value": "Count of events", + "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-required": "Count of events is required.", + "schedule": "Schedule" }, "dialog": { "close": "Close dialog"