Commit 77d2c786afa1cd7386775a84e9b58adaecaf8da6
1 parent
1278339e
UI: Added device profile alarm conditional type
Showing
11 changed files
with
184 additions
and
130 deletions
... | ... | @@ -15,11 +15,13 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
18 | 19 | import lombok.Data; |
19 | 20 | |
20 | 21 | import java.util.concurrent.TimeUnit; |
21 | 22 | |
22 | 23 | @Data |
24 | +@JsonIgnoreProperties(ignoreUnknown = true) | |
23 | 25 | public class DurationAlarmConditionSpec implements AlarmConditionSpec { |
24 | 26 | |
25 | 27 | private TimeUnit unit; | ... | ... |
... | ... | @@ -15,11 +15,13 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
18 | 19 | import lombok.Data; |
19 | 20 | |
20 | 21 | import java.util.concurrent.TimeUnit; |
21 | 22 | |
22 | 23 | @Data |
24 | +@JsonIgnoreProperties(ignoreUnknown = true) | |
23 | 25 | public class RepeatingAlarmConditionSpec implements AlarmConditionSpec { |
24 | 26 | |
25 | 27 | private int count; | ... | ... |
... | ... | @@ -15,9 +15,11 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.common.data.device.profile; |
17 | 17 | |
18 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
18 | 19 | import lombok.Data; |
19 | 20 | |
20 | 21 | @Data |
22 | +@JsonIgnoreProperties(ignoreUnknown = true) | |
21 | 23 | public class SimpleAlarmConditionSpec implements AlarmConditionSpec { |
22 | 24 | @Override |
23 | 25 | public AlarmConditionSpecType getType() { | ... | ... |
... | ... | @@ -17,7 +17,6 @@ |
17 | 17 | --> |
18 | 18 | <div fxLayout="column" fxFlex> |
19 | 19 | <div fxLayout="row" fxLayoutAlign="start center" style="min-height: 40px;"> |
20 | - <div class="tb-small" translate>device-profile.alarm-rule-condition</div> | |
21 | 20 | <span fxFlex></span> |
22 | 21 | <a mat-button color="primary" |
23 | 22 | type="button" | ... | ... |
... | ... | @@ -16,70 +16,90 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <div fxLayout="column" [formGroup]="alarmRuleFormGroup"> |
19 | - <div formGroupName="condition" fxLayout="row" fxLayoutGap="8px" fxFlex> | |
20 | - <tb-alarm-rule-condition fxFlex | |
21 | - formControlName="condition"> | |
22 | - </tb-alarm-rule-condition> | |
23 | - <div fxLayout="column"> | |
24 | - <div fxLayout="row" fxLayoutAlign="start center" style="min-height: 40px;"> | |
25 | - <div class="tb-small" translate>device-profile.condition-duration</div> | |
26 | - <span fxFlex></span> | |
27 | - <mat-slide-toggle [disabled]="disabled" | |
28 | - color="primary" | |
29 | - [ngModelOptions]="{standalone: true}" | |
30 | - (ngModelChange)="enableDurationChanged($event)" | |
31 | - [ngModel]="enableDuration"> | |
32 | - </mat-slide-toggle> | |
33 | - </div> | |
34 | - <div class="tb-condition-duration" fxFlex fxLayout="row" fxLayoutGap="8px"> | |
35 | - <span style="min-width: 250px;" *ngIf="!enableDuration"></span> | |
36 | - <div style="min-width: 250px;" fxLayout="row" fxLayoutGap="8px" *ngIf="enableDuration"> | |
37 | - <mat-form-field class="mat-block duration-value-field" hideRequiredMarker floatLabel="always"> | |
38 | - <mat-label></mat-label> | |
39 | - <input type="number" | |
40 | - required | |
41 | - step="1" | |
42 | - min="1" max="2147483647" matInput | |
43 | - placeholder="{{ 'device-profile.condition-duration-value' | translate }}" | |
44 | - formControlName="durationValue"> | |
45 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition').get('durationValue').hasError('required')"> | |
46 | - {{ 'device-profile.condition-duration-value-required' | translate }} | |
47 | - </mat-error> | |
48 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition').get('durationValue').hasError('min')"> | |
49 | - {{ 'device-profile.condition-duration-value-range' | translate }} | |
50 | - </mat-error> | |
51 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition').get('durationValue').hasError('max')"> | |
52 | - {{ 'device-profile.condition-duration-value-range' | translate }} | |
53 | - </mat-error> | |
54 | - </mat-form-field> | |
55 | - <mat-form-field class="mat-block duration-unit-field" hideRequiredMarker floatLabel="always"> | |
56 | - <mat-label></mat-label> | |
57 | - <mat-select formControlName="durationUnit" | |
58 | - required | |
59 | - placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}"> | |
60 | - <mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit"> | |
61 | - {{ timeUnitTranslations.get(timeUnit) | translate }} | |
19 | + <mat-tab-group> | |
20 | + <mat-tab label="{{ 'device-profile.condition' | translate }}" formGroupName="condition"> | |
21 | + <tb-alarm-rule-condition fxFlex class="row" | |
22 | + formControlName="condition"> | |
23 | + </tb-alarm-rule-condition> | |
24 | + <section class="row"> | |
25 | + <div formGroupName="spec"> | |
26 | + <mat-form-field class="mat-block" hideRequiredMarker> | |
27 | + <mat-label translate>device-profile.condition-type</mat-label> | |
28 | + <mat-select formControlName="type" required> | |
29 | + <mat-option *ngFor="let alarmConditionType of alarmConditionTypes" [value]="alarmConditionType"> | |
30 | + {{ alarmConditionTypeTranslation.get(alarmConditionType) | translate }} | |
62 | 31 | </mat-option> |
63 | 32 | </mat-select> |
64 | - <mat-error *ngIf="alarmRuleFormGroup.get('condition').get('durationUnit').hasError('required')"> | |
65 | - {{ 'device-profile.condition-duration-time-unit-required' | translate }} | |
33 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.type').hasError('required')"> | |
34 | + {{ 'device-profile.condition-type-required' | translate }} | |
66 | 35 | </mat-error> |
67 | 36 | </mat-form-field> |
37 | + <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.DURATION"> | |
38 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
39 | + <mat-label></mat-label> | |
40 | + <input type="number" required | |
41 | + step="1" min="1" max="2147483647" matInput | |
42 | + placeholder="{{ 'device-profile.condition-duration-value' | translate }}" | |
43 | + formControlName="value"> | |
44 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('required')"> | |
45 | + {{ 'device-profile.condition-duration-value-required' | translate }} | |
46 | + </mat-error> | |
47 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('min')"> | |
48 | + {{ 'device-profile.condition-duration-value-range' | translate }} | |
49 | + </mat-error> | |
50 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('max')"> | |
51 | + {{ 'device-profile.condition-duration-value-range' | translate }} | |
52 | + </mat-error> | |
53 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.value').hasError('pattern')"> | |
54 | + {{ 'device-profile.condition-duration-value-pattern' | translate }} | |
55 | + </mat-error> | |
56 | + </mat-form-field> | |
57 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
58 | + <mat-label></mat-label> | |
59 | + <mat-select formControlName="unit" | |
60 | + required | |
61 | + placeholder="{{ 'device-profile.condition-duration-time-unit' | translate }}"> | |
62 | + <mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit"> | |
63 | + {{ timeUnitTranslations.get(timeUnit) | translate }} | |
64 | + </mat-option> | |
65 | + </mat-select> | |
66 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.unit').hasError('required')"> | |
67 | + {{ 'device-profile.condition-duration-time-unit-required' | translate }} | |
68 | + </mat-error> | |
69 | + </mat-form-field> | |
70 | + </div> | |
71 | + <div fxLayout="row" fxLayoutGap="8px" *ngIf="alarmRuleFormGroup.get('condition.spec.type').value == AlarmConditionType.REPEATING"> | |
72 | + <mat-form-field class="mat-block" hideRequiredMarker fxFlex floatLabel="always"> | |
73 | + <mat-label></mat-label> | |
74 | + <input type="number" required | |
75 | + step="1" min="1" max="2147483647" matInput | |
76 | + placeholder="{{ 'device-profile.condition-repeating-value' | translate }}" | |
77 | + formControlName="count"> | |
78 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('required')"> | |
79 | + {{ 'device-profile.condition-repeating-value-required' | translate }} | |
80 | + </mat-error> | |
81 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('min')"> | |
82 | + {{ 'device-profile.condition-repeating-value-range' | translate }} | |
83 | + </mat-error> | |
84 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('max')"> | |
85 | + {{ 'device-profile.condition-repeating-value-range' | translate }} | |
86 | + </mat-error> | |
87 | + <mat-error *ngIf="alarmRuleFormGroup.get('condition.spec.count').hasError('pattern')"> | |
88 | + {{ 'device-profile.condition-repeating-value-pattern' | translate }} | |
89 | + </mat-error> | |
90 | + </mat-form-field> | |
91 | + </div> | |
68 | 92 | </div> |
69 | - </div> | |
70 | - </div> | |
71 | - </div> | |
72 | - <mat-expansion-panel class="advanced-settings" [expanded]="false"> | |
73 | - <mat-expansion-panel-header> | |
74 | - <mat-panel-title> | |
75 | - <div fxFlex fxLayout="row" fxLayoutAlign="end center"> | |
76 | - <div class="tb-small" translate>device-profile.alarm-rule-details</div> | |
77 | - </div> | |
78 | - </mat-panel-title> | |
79 | - </mat-expansion-panel-header> | |
80 | - <mat-form-field class="mat-block"> | |
81 | - <mat-label translate>device-profile.alarm-details</mat-label> | |
82 | - <textarea matInput formControlName="alarmDetails" rows="5"></textarea> | |
83 | - </mat-form-field> | |
84 | - </mat-expansion-panel> | |
93 | + </section> | |
94 | + </mat-tab> | |
95 | + <mat-tab label="{{ 'device-profile.schedule' | translate }}"> | |
96 | + <div class="row">{{ 'device-profile.schedule' | translate }}</div> | |
97 | + </mat-tab> | |
98 | + <mat-tab label="{{ 'device-profile.alarm-rule-details' | translate }}"> | |
99 | + <mat-form-field class="mat-block row"> | |
100 | + <mat-label translate>device-profile.alarm-details</mat-label> | |
101 | + <textarea matInput formControlName="alarmDetails" rows="5"></textarea> | |
102 | + </mat-form-field> | |
103 | + </mat-tab> | |
104 | + </mat-tab-group> | |
85 | 105 | </div> | ... | ... |
... | ... | @@ -14,33 +14,8 @@ |
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | :host { |
17 | - .tb-condition-duration { | |
18 | - padding: 8px; | |
19 | - border: 1px groove rgba(0, 0, 0, .25); | |
20 | - border-radius: 4px; | |
21 | - } | |
22 | - .mat-expansion-panel.advanced-settings { | |
23 | - box-shadow: none; | |
24 | - border: none; | |
25 | - padding: 0; | |
26 | - } | |
27 | -} | |
28 | - | |
29 | -:host ::ng-deep { | |
30 | - .mat-expansion-panel.advanced-settings { | |
31 | - .mat-expansion-panel-body { | |
32 | - padding: 0; | |
33 | - } | |
34 | - } | |
35 | - .mat-form-field.duration-value-field { | |
36 | - .mat-form-field-infix { | |
37 | - width: 120px; | |
38 | - } | |
39 | - } | |
40 | - .mat-form-field.duration-unit-field { | |
41 | - .mat-form-field-infix { | |
42 | - width: 120px; | |
43 | - } | |
17 | + .row { | |
18 | + margin-top: 1em; | |
44 | 19 | } |
45 | 20 | } |
46 | 21 | ... | ... |
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import { ChangeDetectorRef, Component, forwardRef, Input, NgZone, OnInit } from '@angular/core'; | |
17 | +import { Component, forwardRef, Input, OnInit } from '@angular/core'; | |
18 | 18 | import { |
19 | 19 | ControlValueAccessor, |
20 | 20 | FormBuilder, |
... | ... | @@ -25,9 +25,9 @@ import { |
25 | 25 | Validator, |
26 | 26 | Validators |
27 | 27 | } from '@angular/forms'; |
28 | -import { AlarmRule } from '@shared/models/device.models'; | |
28 | +import { AlarmConditionType, AlarmConditionTypeTranslationMap, AlarmRule } from '@shared/models/device.models'; | |
29 | 29 | import { MatDialog } from '@angular/material/dialog'; |
30 | -import { TimeUnit, timeUnitTranslationMap } from '../../../../../shared/models/time/time.models'; | |
30 | +import { TimeUnit, timeUnitTranslationMap } from '@shared/models/time/time.models'; | |
31 | 31 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
32 | 32 | |
33 | 33 | @Component({ |
... | ... | @@ -51,6 +51,9 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
51 | 51 | |
52 | 52 | timeUnits = Object.keys(TimeUnit); |
53 | 53 | timeUnitTranslations = timeUnitTranslationMap; |
54 | + alarmConditionTypes = Object.keys(AlarmConditionType); | |
55 | + AlarmConditionType = AlarmConditionType; | |
56 | + alarmConditionTypeTranslation = AlarmConditionTypeTranslationMap; | |
54 | 57 | |
55 | 58 | @Input() |
56 | 59 | disabled: boolean; |
... | ... | @@ -64,8 +67,6 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
64 | 67 | this.requiredValue = coerceBooleanProperty(value); |
65 | 68 | } |
66 | 69 | |
67 | - enableDuration = false; | |
68 | - | |
69 | 70 | private modelValue: AlarmRule; |
70 | 71 | |
71 | 72 | alarmRuleFormGroup: FormGroup; |
... | ... | @@ -87,11 +88,18 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
87 | 88 | this.alarmRuleFormGroup = this.fb.group({ |
88 | 89 | condition: this.fb.group({ |
89 | 90 | condition: [null, Validators.required], |
90 | - durationUnit: [null], | |
91 | - durationValue: [null] | |
91 | + spec: this.fb.group({ | |
92 | + type: [AlarmConditionType.SIMPLE, Validators.required], | |
93 | + unit: [{value: null, disable: true}, Validators.required], | |
94 | + value: [{value: null, disable: true}, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]], | |
95 | + count: [{value: null, disable: true}, [Validators.required, Validators.min(1), Validators.max(2147483647), Validators.pattern('[0-9]*')]] | |
96 | + }) | |
92 | 97 | }, Validators.required), |
93 | 98 | alarmDetails: [null] |
94 | 99 | }); |
100 | + this.alarmRuleFormGroup.get('condition.spec.type').valueChanges.subscribe((type) => { | |
101 | + this.updateValidators(type, true, true); | |
102 | + }); | |
95 | 103 | this.alarmRuleFormGroup.valueChanges.subscribe(() => { |
96 | 104 | this.updateModel(); |
97 | 105 | }); |
... | ... | @@ -108,9 +116,13 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
108 | 116 | |
109 | 117 | writeValue(value: AlarmRule): void { |
110 | 118 | this.modelValue = value; |
111 | - this.enableDuration = value && !!value.condition.durationValue; | |
119 | + if (this.modelValue?.condition?.spec === null) { | |
120 | + this.modelValue.condition.spec = { | |
121 | + type: AlarmConditionType.SIMPLE | |
122 | + }; | |
123 | + } | |
112 | 124 | this.alarmRuleFormGroup.reset(this.modelValue || undefined, {emitEvent: false}); |
113 | - this.updateValidators(); | |
125 | + this.updateValidators(this.modelValue?.condition?.spec?.type); | |
114 | 126 | } |
115 | 127 | |
116 | 128 | public validate(c: FormControl) { |
... | ... | @@ -121,31 +133,45 @@ export class AlarmRuleComponent implements ControlValueAccessor, OnInit, Validat |
121 | 133 | }; |
122 | 134 | } |
123 | 135 | |
124 | - public enableDurationChanged(enableDuration) { | |
125 | - this.enableDuration = enableDuration; | |
126 | - this.updateValidators(true, true); | |
127 | - } | |
128 | - | |
129 | - private updateValidators(resetDuration = false, emitEvent = false) { | |
130 | - if (this.enableDuration) { | |
131 | - this.alarmRuleFormGroup.get('condition').get('durationValue') | |
132 | - .setValidators([Validators.required, Validators.min(1), Validators.max(2147483647)]); | |
133 | - this.alarmRuleFormGroup.get('condition').get('durationUnit') | |
134 | - .setValidators([Validators.required]); | |
135 | - } else { | |
136 | - this.alarmRuleFormGroup.get('condition').get('durationValue') | |
137 | - .setValidators([]); | |
138 | - this.alarmRuleFormGroup.get('condition').get('durationUnit') | |
139 | - .setValidators([]); | |
140 | - if (resetDuration) { | |
141 | - this.alarmRuleFormGroup.get('condition').patchValue({ | |
142 | - durationValue: null, | |
143 | - durationUnit: null | |
144 | - }); | |
145 | - } | |
136 | + private updateValidators(type: AlarmConditionType, resetDuration = false, emitEvent = false) { | |
137 | + switch (type) { | |
138 | + case AlarmConditionType.DURATION: | |
139 | + this.alarmRuleFormGroup.get('condition.spec.value').enable(); | |
140 | + this.alarmRuleFormGroup.get('condition.spec.unit').enable(); | |
141 | + this.alarmRuleFormGroup.get('condition.spec.count').disable(); | |
142 | + if (resetDuration) { | |
143 | + this.alarmRuleFormGroup.get('condition.spec').patchValue({ | |
144 | + count: null | |
145 | + }); | |
146 | + } | |
147 | + break; | |
148 | + case AlarmConditionType.REPEATING: | |
149 | + this.alarmRuleFormGroup.get('condition.spec.count').enable(); | |
150 | + this.alarmRuleFormGroup.get('condition.spec.value').disable(); | |
151 | + this.alarmRuleFormGroup.get('condition.spec.unit').disable(); | |
152 | + if (resetDuration) { | |
153 | + this.alarmRuleFormGroup.get('condition.spec').patchValue({ | |
154 | + value: null, | |
155 | + unit: null | |
156 | + }); | |
157 | + } | |
158 | + break; | |
159 | + case AlarmConditionType.SIMPLE: | |
160 | + this.alarmRuleFormGroup.get('condition.spec.value').disable(); | |
161 | + this.alarmRuleFormGroup.get('condition.spec.unit').disable(); | |
162 | + this.alarmRuleFormGroup.get('condition.spec.count').disable(); | |
163 | + if (resetDuration) { | |
164 | + this.alarmRuleFormGroup.get('condition.spec').patchValue({ | |
165 | + value: null, | |
166 | + unit: null, | |
167 | + count: null | |
168 | + }); | |
169 | + } | |
170 | + break; | |
146 | 171 | } |
147 | - this.alarmRuleFormGroup.get('condition').get('durationValue').updateValueAndValidity({emitEvent}); | |
148 | - this.alarmRuleFormGroup.get('condition').get('durationUnit').updateValueAndValidity({emitEvent}); | |
172 | + this.alarmRuleFormGroup.get('condition.spec.value').updateValueAndValidity({emitEvent}); | |
173 | + this.alarmRuleFormGroup.get('condition.spec.unit').updateValueAndValidity({emitEvent}); | |
174 | + this.alarmRuleFormGroup.get('condition.spec.count').updateValueAndValidity({emitEvent}); | |
149 | 175 | } |
150 | 176 | |
151 | 177 | private updateModel() { | ... | ... |
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | <div *ngFor="let createAlarmRuleControl of createAlarmRulesFormArray().controls; let $index = index; |
20 | 20 | last as isLast;" fxLayout="row" fxLayoutAlign="start center" |
21 | 21 | fxLayoutGap="8px" style="padding-bottom: 8px;" [formGroup]="createAlarmRuleControl"> |
22 | - <div class="create-alarm-rule" fxFlex fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="start"> | |
22 | + <div class="create-alarm-rule" fxFlex fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="start"> | |
23 | 23 | <mat-form-field class="severity mat-block" floatLabel="always" hideRequiredMarker> |
24 | 24 | <mat-label translate>alarm.severity</mat-label> |
25 | 25 | <mat-select formControlName="severity" | ... | ... |
... | ... | @@ -210,10 +210,30 @@ export function createDeviceTransportConfiguration(type: DeviceTransportType): D |
210 | 210 | return transportConfiguration; |
211 | 211 | } |
212 | 212 | |
213 | +export enum AlarmConditionType { | |
214 | + SIMPLE = 'SIMPLE', | |
215 | + DURATION = 'DURATION', | |
216 | + REPEATING = 'REPEATING' | |
217 | +} | |
218 | + | |
219 | +export const AlarmConditionTypeTranslationMap = new Map<AlarmConditionType, string>( | |
220 | + [ | |
221 | + [AlarmConditionType.SIMPLE, 'device-profile.condition-type-simple'], | |
222 | + [AlarmConditionType.DURATION, 'device-profile.condition-type-duration'], | |
223 | + [AlarmConditionType.REPEATING, 'device-profile.condition-type-repeating'] | |
224 | + ] | |
225 | +); | |
226 | + | |
227 | +export interface AlarmConditionSpec{ | |
228 | + type?: AlarmConditionType; | |
229 | + unit?: TimeUnit; | |
230 | + value?: number; | |
231 | + count?: number; | |
232 | +} | |
233 | + | |
213 | 234 | export interface AlarmCondition { |
214 | 235 | condition: Array<KeyFilter>; |
215 | - durationUnit?: TimeUnit; | |
216 | - durationValue?: number; | |
236 | + spec?: AlarmConditionSpec; | |
217 | 237 | } |
218 | 238 | |
219 | 239 | export interface AlarmRule { | ... | ... |
... | ... | @@ -834,6 +834,7 @@ |
834 | 834 | "condition-duration-value": "Duration value", |
835 | 835 | "condition-duration-time-unit": "Time unit", |
836 | 836 | "condition-duration-value-range": "Duration value should be in a range from 1 to 2147483647.", |
837 | + "condition-duration-value-pattern": "Duration value should be integers.", | |
837 | 838 | "condition-duration-value-required": "Duration value is required.", |
838 | 839 | "condition-duration-time-unit-required": "Time unit is required.", |
839 | 840 | "advanced-settings": "Advanced settings", |
... | ... | @@ -844,7 +845,18 @@ |
844 | 845 | "alarm-details": "Alarm details", |
845 | 846 | "alarm-rule-condition": "Alarm rule condition", |
846 | 847 | "enter-alarm-rule-condition-prompt": "Please add alarm rule condition", |
847 | - "edit-alarm-rule-condition": "Edit alarm rule condition" | |
848 | + "edit-alarm-rule-condition": "Edit alarm rule condition", | |
849 | + "condition": "Condition", | |
850 | + "condition-type": "Condition type", | |
851 | + "condition-type-simple": "Simple", | |
852 | + "condition-type-duration": "Duration", | |
853 | + "condition-type-repeating": "Repeating", | |
854 | + "condition-type-required": "Condition type is required.", | |
855 | + "condition-repeating-value": "Count of events", | |
856 | + "condition-repeating-value-range": "Count of events should be in a range from 1 to 2147483647.", | |
857 | + "condition-repeating-value-pattern": "Count of events should be integers.", | |
858 | + "condition-repeating-value-required": "Count of events is required.", | |
859 | + "schedule": "Schedule" | |
848 | 860 | }, |
849 | 861 | "dialog": { |
850 | 862 | "close": "Close dialog" | ... | ... |