Showing
52 changed files
with
285 additions
and
236 deletions
... | ... | @@ -88,14 +88,20 @@ |
88 | 88 | </fieldset> |
89 | 89 | </div> |
90 | 90 | <div mat-dialog-actions fxLayout="row"> |
91 | - <div fxLayout="row" *ngIf="alarm$ | async; let alarm;"> | |
91 | + <button mat-button color="primary" | |
92 | + type="button" | |
93 | + [disabled]="(isLoading$ | async)" | |
94 | + (click)="close()" cdkFocusInitial> | |
95 | + {{ 'action.close' | translate }} | |
96 | + </button> | |
97 | + <span fxFlex></span> | |
98 | + <div fxLayout="row" *ngIf="alarm$ | async; let alarm;" fxLayoutGap="8px"> | |
92 | 99 | <button *ngIf="allowAcknowledgment && (alarm.status === alarmStatuses.ACTIVE_UNACK || |
93 | 100 | alarm.status === alarmStatuses.CLEARED_UNACK)" |
94 | 101 | mat-raised-button |
95 | 102 | color="primary" |
96 | 103 | type="button" |
97 | 104 | (click)="acknowledge()" |
98 | - style="margin-right: 20px;" | |
99 | 105 | [disabled]="(isLoading$ | async)"> |
100 | 106 | {{ 'alarm.acknowledge' | translate }} |
101 | 107 | </button> |
... | ... | @@ -109,12 +115,5 @@ |
109 | 115 | {{ 'alarm.clear' | translate }} |
110 | 116 | </button> |
111 | 117 | </div> |
112 | - <span fxFlex></span> | |
113 | - <button mat-button color="primary" | |
114 | - type="button" | |
115 | - [disabled]="(isLoading$ | async)" | |
116 | - (click)="close()" cdkFocusInitial> | |
117 | - {{ 'action.close' | translate }} | |
118 | - </button> | |
119 | 118 | </div> |
120 | 119 | </form> | ... | ... |
... | ... | @@ -59,16 +59,16 @@ |
59 | 59 | </fieldset> |
60 | 60 | </div> |
61 | 61 | <div mat-dialog-actions fxLayoutAlign="end center"> |
62 | - <button mat-raised-button color="primary" | |
63 | - type="submit" | |
64 | - [disabled]="(isLoading$ | async) || entityAliasFormGroup.invalid || !entityAliasFormGroup.dirty"> | |
65 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
66 | - </button> | |
67 | 62 | <button mat-button color="primary" |
68 | 63 | type="button" |
69 | 64 | [disabled]="(isLoading$ | async)" |
70 | 65 | (click)="cancel()" cdkFocusInitial> |
71 | 66 | {{ 'action.cancel' | translate }} |
72 | 67 | </button> |
68 | + <button mat-raised-button color="primary" | |
69 | + type="submit" | |
70 | + [disabled]="(isLoading$ | async) || entityAliasFormGroup.invalid || !entityAliasFormGroup.dirty"> | |
71 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
72 | + </button> | |
73 | 73 | </div> |
74 | 74 | </form> | ... | ... |
... | ... | @@ -95,11 +95,6 @@ |
95 | 95 | {{ 'alias.add' | translate }} |
96 | 96 | </button> |
97 | 97 | <span fxFlex></span> |
98 | - <button mat-raised-button color="primary" | |
99 | - type="submit" | |
100 | - [disabled]="(isLoading$ | async) || entityAliasesFormGroup.invalid || !entityAliasesFormGroup.dirty"> | |
101 | - {{ 'action.save' | translate }} | |
102 | - </button> | |
103 | 98 | <button mat-button color="primary" |
104 | 99 | type="button" |
105 | 100 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -107,5 +102,10 @@ |
107 | 102 | cdkFocusInitial> |
108 | 103 | {{ 'action.cancel' | translate }} |
109 | 104 | </button> |
105 | + <button mat-raised-button color="primary" | |
106 | + type="submit" | |
107 | + [disabled]="(isLoading$ | async) || entityAliasesFormGroup.invalid || !entityAliasesFormGroup.dirty"> | |
108 | + {{ 'action.save' | translate }} | |
109 | + </button> | |
110 | 110 | </div> |
111 | 111 | </form> | ... | ... |
... | ... | @@ -44,16 +44,16 @@ |
44 | 44 | </fieldset> |
45 | 45 | </div> |
46 | 46 | <div mat-dialog-actions fxLayoutAlign="end center"> |
47 | - <button mat-raised-button color="primary" | |
48 | - type="submit" | |
49 | - [disabled]="(isLoading$ | async) || attributeFormGroup.invalid || !attributeFormGroup.dirty"> | |
50 | - {{ 'action.add' | translate }} | |
51 | - </button> | |
52 | 47 | <button mat-button color="primary" |
53 | 48 | type="button" |
54 | 49 | [disabled]="(isLoading$ | async)" |
55 | 50 | (click)="cancel()" cdkFocusInitial> |
56 | 51 | {{ 'action.cancel' | translate }} |
57 | 52 | </button> |
53 | + <button mat-raised-button color="primary" | |
54 | + type="submit" | |
55 | + [disabled]="(isLoading$ | async) || attributeFormGroup.invalid || !attributeFormGroup.dirty"> | |
56 | + {{ 'action.add' | translate }} | |
57 | + </button> | |
58 | 58 | </div> |
59 | 59 | </form> | ... | ... |
... | ... | @@ -55,21 +55,22 @@ |
55 | 55 | </mat-radio-group> |
56 | 56 | </fieldset> |
57 | 57 | </div> |
58 | - <div mat-dialog-actions fxLayoutAlign="end center"> | |
58 | + <div mat-dialog-actions fxLayout="row"> | |
59 | 59 | <mat-checkbox formControlName="openDashboard" |
60 | - style="margin-bottom: 0; padding-right: 20px;"> | |
60 | + style="margin-bottom: 0;"> | |
61 | 61 | {{ 'dashboard.open-dashboard' | translate }} |
62 | 62 | </mat-checkbox> |
63 | - <button mat-raised-button color="primary" | |
64 | - type="submit" | |
65 | - [disabled]="(isLoading$ | async) || addWidgetFormGroup.invalid || !addWidgetFormGroup.dirty"> | |
66 | - {{ 'action.add' | translate }} | |
67 | - </button> | |
63 | + <span fxFlex></span> | |
68 | 64 | <button mat-button color="primary" |
69 | 65 | type="button" |
70 | 66 | [disabled]="(isLoading$ | async)" |
71 | 67 | (click)="cancel()" cdkFocusInitial> |
72 | 68 | {{ 'action.cancel' | translate }} |
73 | 69 | </button> |
70 | + <button mat-raised-button color="primary" | |
71 | + type="submit" | |
72 | + [disabled]="(isLoading$ | async) || addWidgetFormGroup.invalid || !addWidgetFormGroup.dirty"> | |
73 | + {{ 'action.add' | translate }} | |
74 | + </button> | |
74 | 75 | </div> |
75 | 76 | </form> | ... | ... |
... | ... | @@ -40,11 +40,6 @@ |
40 | 40 | </fieldset> |
41 | 41 | </div> |
42 | 42 | <div mat-dialog-actions fxLayoutAlign="end center"> |
43 | - <button mat-raised-button color="primary" | |
44 | - type="submit" | |
45 | - [disabled]="(isLoading$ | async) || stateFormGroup.invalid"> | |
46 | - {{ 'action.select' | translate }} | |
47 | - </button> | |
48 | 43 | <button mat-button color="primary" |
49 | 44 | type="button" |
50 | 45 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -52,5 +47,10 @@ |
52 | 47 | cdkFocusInitial> |
53 | 48 | {{ 'action.cancel' | translate }} |
54 | 49 | </button> |
50 | + <button mat-raised-button color="primary" | |
51 | + type="submit" | |
52 | + [disabled]="(isLoading$ | async) || stateFormGroup.invalid"> | |
53 | + {{ 'action.select' | translate }} | |
54 | + </button> | |
55 | 55 | </div> |
56 | 56 | </form> | ... | ... |
... | ... | @@ -46,12 +46,6 @@ |
46 | 46 | </fieldset> |
47 | 47 | </div> |
48 | 48 | <div mat-dialog-actions fxLayoutAlign="end center"> |
49 | - <button mat-raised-button color="primary" | |
50 | - *ngIf="!data.readonly" | |
51 | - type="submit" | |
52 | - [disabled]="(isLoading$ | async) || complexFilterFormGroup.invalid || !complexFilterFormGroup.dirty"> | |
53 | - {{ (isAdd ? 'action.add' : 'action.update') | translate }} | |
54 | - </button> | |
55 | 49 | <button mat-button color="primary" |
56 | 50 | type="button" |
57 | 51 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -59,5 +53,11 @@ |
59 | 53 | cdkFocusInitial> |
60 | 54 | {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} |
61 | 55 | </button> |
56 | + <button mat-raised-button color="primary" | |
57 | + *ngIf="!data.readonly" | |
58 | + type="submit" | |
59 | + [disabled]="(isLoading$ | async) || complexFilterFormGroup.invalid || !complexFilterFormGroup.dirty"> | |
60 | + {{ (isAdd ? 'action.add' : 'action.update') | translate }} | |
61 | + </button> | |
62 | 62 | </div> |
63 | 63 | </form> | ... | ... |
... | ... | @@ -55,16 +55,16 @@ |
55 | 55 | </fieldset> |
56 | 56 | </div> |
57 | 57 | <div mat-dialog-actions fxLayoutAlign="end center"> |
58 | - <button mat-raised-button color="primary" | |
59 | - type="submit" | |
60 | - [disabled]="(isLoading$ | async) || filterFormGroup.invalid || !filterFormGroup.dirty"> | |
61 | - {{ (isAdd ? 'action.add' : 'action.update') | translate }} | |
62 | - </button> | |
63 | 58 | <button mat-button color="primary" |
64 | 59 | type="button" |
65 | 60 | [disabled]="(isLoading$ | async)" |
66 | 61 | (click)="cancel()" cdkFocusInitial> |
67 | 62 | {{ 'action.cancel' | translate }} |
68 | 63 | </button> |
64 | + <button mat-raised-button color="primary" | |
65 | + type="submit" | |
66 | + [disabled]="(isLoading$ | async) || filterFormGroup.invalid || !filterFormGroup.dirty"> | |
67 | + {{ (isAdd ? 'action.add' : 'action.update') | translate }} | |
68 | + </button> | |
69 | 69 | </div> |
70 | 70 | </form> | ... | ... |
... | ... | @@ -46,12 +46,6 @@ |
46 | 46 | </fieldset> |
47 | 47 | </div> |
48 | 48 | <div mat-dialog-actions fxLayoutAlign="end center"> |
49 | - <button mat-raised-button color="primary" | |
50 | - *ngIf="!data.readonly" | |
51 | - type="submit" | |
52 | - [disabled]="(isLoading$ | async) || filterUserInfoFormGroup.invalid || !filterUserInfoFormGroup.dirty"> | |
53 | - {{ 'action.update' | translate }} | |
54 | - </button> | |
55 | 49 | <button mat-button color="primary" |
56 | 50 | type="button" |
57 | 51 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -59,5 +53,11 @@ |
59 | 53 | cdkFocusInitial> |
60 | 54 | {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} |
61 | 55 | </button> |
56 | + <button mat-raised-button color="primary" | |
57 | + *ngIf="!data.readonly" | |
58 | + type="submit" | |
59 | + [disabled]="(isLoading$ | async) || filterUserInfoFormGroup.invalid || !filterUserInfoFormGroup.dirty"> | |
60 | + {{ 'action.update' | translate }} | |
61 | + </button> | |
62 | 62 | </div> |
63 | 63 | </form> | ... | ... |
... | ... | @@ -88,11 +88,6 @@ |
88 | 88 | {{ 'filter.add' | translate }} |
89 | 89 | </button> |
90 | 90 | <span fxFlex></span> |
91 | - <button mat-raised-button color="primary" | |
92 | - type="submit" | |
93 | - [disabled]="(isLoading$ | async) || filtersFormGroup.invalid || !filtersFormGroup.dirty"> | |
94 | - {{ 'action.save' | translate }} | |
95 | - </button> | |
96 | 91 | <button mat-button color="primary" |
97 | 92 | type="button" |
98 | 93 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -100,5 +95,10 @@ |
100 | 95 | cdkFocusInitial> |
101 | 96 | {{ 'action.cancel' | translate }} |
102 | 97 | </button> |
98 | + <button mat-raised-button color="primary" | |
99 | + type="submit" | |
100 | + [disabled]="(isLoading$ | async) || filtersFormGroup.invalid || !filtersFormGroup.dirty"> | |
101 | + {{ 'action.save' | translate }} | |
102 | + </button> | |
103 | 103 | </div> |
104 | 104 | </form> | ... | ... |
... | ... | @@ -79,12 +79,6 @@ |
79 | 79 | </fieldset> |
80 | 80 | </div> |
81 | 81 | <div mat-dialog-actions fxLayoutAlign="end center"> |
82 | - <button mat-raised-button color="primary" | |
83 | - type="submit" | |
84 | - *ngIf="!data.readonly" | |
85 | - [disabled]="(isLoading$ | async) || keyFilterFormGroup.invalid || !keyFilterFormGroup.dirty"> | |
86 | - {{ (data.isAdd ? 'action.add' : 'action.update') | translate }} | |
87 | - </button> | |
88 | 82 | <button mat-button color="primary" |
89 | 83 | type="button" |
90 | 84 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -92,5 +86,11 @@ |
92 | 86 | cdkFocusInitial> |
93 | 87 | {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} |
94 | 88 | </button> |
89 | + <button mat-raised-button color="primary" | |
90 | + type="submit" | |
91 | + *ngIf="!data.readonly" | |
92 | + [disabled]="(isLoading$ | async) || keyFilterFormGroup.invalid || !keyFilterFormGroup.dirty"> | |
93 | + {{ (data.isAdd ? 'action.add' : 'action.update') | translate }} | |
94 | + </button> | |
95 | 95 | </div> |
96 | 96 | </form> | ... | ... |
... | ... | @@ -65,16 +65,16 @@ |
65 | 65 | </fieldset> |
66 | 66 | </div> |
67 | 67 | <div mat-dialog-actions fxLayoutAlign="end center"> |
68 | - <button mat-raised-button color="primary" | |
69 | - type="submit" | |
70 | - [disabled]="(isLoading$ | async) || userFilterFormGroup.invalid || !userFilterFormGroup.dirty"> | |
71 | - {{ 'action.update' | translate }} | |
72 | - </button> | |
73 | 68 | <button mat-button color="primary" |
74 | 69 | type="button" |
75 | 70 | [disabled]="(isLoading$ | async)" |
76 | 71 | (click)="cancel()" cdkFocusInitial> |
77 | 72 | {{ 'action.cancel' | translate }} |
78 | 73 | </button> |
74 | + <button mat-raised-button color="primary" | |
75 | + type="submit" | |
76 | + [disabled]="(isLoading$ | async) || userFilterFormGroup.invalid || !userFilterFormGroup.dirty"> | |
77 | + {{ 'action.update' | translate }} | |
78 | + </button> | |
79 | 79 | </div> |
80 | 80 | </form> | ... | ... |
... | ... | @@ -43,16 +43,16 @@ |
43 | 43 | </fieldset> |
44 | 44 | </div> |
45 | 45 | <div mat-dialog-actions fxLayoutAlign="end center"> |
46 | - <button mat-raised-button color="primary" | |
47 | - type="submit" | |
48 | - [disabled]="(isLoading$ | async) || importFormGroup.invalid || !importFormGroup.dirty"> | |
49 | - {{ 'action.import' | translate }} | |
50 | - </button> | |
51 | 46 | <button mat-button color="primary" |
52 | 47 | type="button" |
53 | 48 | [disabled]="(isLoading$ | async)" |
54 | 49 | (click)="cancel()" cdkFocusInitial> |
55 | 50 | {{ 'action.cancel' | translate }} |
56 | 51 | </button> |
52 | + <button mat-raised-button color="primary" | |
53 | + type="submit" | |
54 | + [disabled]="(isLoading$ | async) || importFormGroup.invalid || !importFormGroup.dirty"> | |
55 | + {{ 'action.import' | translate }} | |
56 | + </button> | |
57 | 57 | </div> |
58 | 58 | </form> | ... | ... |
... | ... | @@ -108,17 +108,17 @@ |
108 | 108 | </fieldset> |
109 | 109 | </div> |
110 | 110 | <div mat-dialog-actions fxLayoutAlign="end center"> |
111 | - <button mat-raised-button color="primary" | |
112 | - *ngIf="!readonly" | |
113 | - type="submit" | |
114 | - [disabled]="(isLoading$ | async) || conditionFormGroup.invalid || !conditionFormGroup.dirty"> | |
115 | - {{ 'action.save' | translate }} | |
116 | - </button> | |
117 | 111 | <button mat-button color="primary" |
118 | 112 | type="button" |
119 | 113 | [disabled]="(isLoading$ | async)" |
120 | 114 | (click)="cancel()" cdkFocusInitial> |
121 | 115 | {{ (readonly ? 'action.close' : 'action.cancel') | translate }} |
122 | 116 | </button> |
117 | + <button mat-raised-button color="primary" | |
118 | + *ngIf="!readonly" | |
119 | + type="submit" | |
120 | + [disabled]="(isLoading$ | async) || conditionFormGroup.invalid || !conditionFormGroup.dirty"> | |
121 | + {{ 'action.save' | translate }} | |
122 | + </button> | |
123 | 123 | </div> |
124 | 124 | </form> | ... | ... |
... | ... | @@ -37,17 +37,17 @@ |
37 | 37 | </fieldset> |
38 | 38 | </div> |
39 | 39 | <div mat-dialog-actions fxLayoutAlign="end center"> |
40 | - <button mat-raised-button color="primary" | |
41 | - *ngIf="!readonly" | |
42 | - type="submit" | |
43 | - [disabled]="(isLoading$ | async) || alarmScheduleFormGroup.invalid || !alarmScheduleFormGroup.dirty"> | |
44 | - {{ 'action.save' | translate }} | |
45 | - </button> | |
46 | 40 | <button mat-button color="primary" |
47 | 41 | type="button" |
48 | 42 | [disabled]="(isLoading$ | async)" |
49 | 43 | (click)="cancel()" cdkFocusInitial> |
50 | 44 | {{ (readonly ? 'action.close' : 'action.cancel') | translate }} |
51 | 45 | </button> |
46 | + <button mat-raised-button color="primary" | |
47 | + *ngIf="!readonly" | |
48 | + type="submit" | |
49 | + [disabled]="(isLoading$ | async) || alarmScheduleFormGroup.invalid || !alarmScheduleFormGroup.dirty"> | |
50 | + {{ 'action.save' | translate }} | |
51 | + </button> | |
52 | 52 | </div> |
53 | 53 | </form> | ... | ... |
... | ... | @@ -47,9 +47,9 @@ |
47 | 47 | <mat-icon>remove_circle_outline</mat-icon> |
48 | 48 | </button> |
49 | 49 | </div> |
50 | - <div *ngIf="!createAlarmRulesFormArray().controls.length"> | |
50 | + <div *ngIf="!createAlarmRulesFormArray().controls.length && !disabled"> | |
51 | 51 | <span translate fxLayoutAlign="center center" style="margin: 16px 0" |
52 | - class="tb-prompt">device-profile.no-create-alarm-rules</span> | |
52 | + class="tb-prompt required">device-profile.add-create-alarm-rule-prompt</span> | |
53 | 53 | </div> |
54 | 54 | <div fxLayout="row" *ngIf="!disabled"> |
55 | 55 | <button mat-stroked-button color="primary" | ... | ... |
... | ... | @@ -23,11 +23,11 @@ import { |
23 | 23 | FormControl, |
24 | 24 | FormGroup, |
25 | 25 | NG_VALIDATORS, |
26 | - NG_VALUE_ACCESSOR, | |
26 | + NG_VALUE_ACCESSOR, ValidationErrors, | |
27 | 27 | Validator, |
28 | 28 | Validators |
29 | 29 | } from '@angular/forms'; |
30 | -import { AlarmRule } from '@shared/models/device.models'; | |
30 | +import { AlarmRule, alarmRuleValidator } from '@shared/models/device.models'; | |
31 | 31 | import { MatDialog } from '@angular/material/dialog'; |
32 | 32 | import { Subscription } from 'rxjs'; |
33 | 33 | import { AlarmSeverity, alarmSeverityTranslations } from '../../../../../shared/models/alarm.models'; |
... | ... | @@ -141,10 +141,23 @@ export class CreateAlarmRulesComponent implements ControlValueAccessor, OnInit, |
141 | 141 | }; |
142 | 142 | const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; |
143 | 143 | createAlarmRulesArray.push(this.fb.group({ |
144 | - severity: [null, Validators.required], | |
145 | - alarmRule: [createAlarmRule, Validators.required] | |
144 | + severity: [this.getFirstUnusedSeverity(), Validators.required], | |
145 | + alarmRule: [createAlarmRule, alarmRuleValidator] | |
146 | 146 | })); |
147 | 147 | this.createAlarmRulesFormGroup.updateValueAndValidity(); |
148 | + if (!this.createAlarmRulesFormGroup.valid) { | |
149 | + this.updateModel(); | |
150 | + } | |
151 | + } | |
152 | + | |
153 | + private getFirstUnusedSeverity(): AlarmSeverity { | |
154 | + for (const severityKey of Object.keys(AlarmSeverity)) { | |
155 | + const severity = AlarmSeverity[severityKey]; | |
156 | + if (this.usedSeverities.indexOf(severity) === -1) { | |
157 | + return severity; | |
158 | + } | |
159 | + } | |
160 | + return null; | |
148 | 161 | } |
149 | 162 | |
150 | 163 | public validate(c: FormControl) { | ... | ... |
... | ... | @@ -25,7 +25,7 @@ import { |
25 | 25 | Validator, |
26 | 26 | Validators |
27 | 27 | } from '@angular/forms'; |
28 | -import { AlarmRule, DeviceProfileAlarm } from '@shared/models/device.models'; | |
28 | +import { AlarmRule, DeviceProfileAlarm, deviceProfileAlarmValidator } from '@shared/models/device.models'; | |
29 | 29 | import { MatDialog } from '@angular/material/dialog'; |
30 | 30 | import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; |
31 | 31 | import { MatChipInputEvent } from '@angular/material/chips'; |
... | ... | @@ -92,7 +92,7 @@ export class DeviceProfileAlarmComponent implements ControlValueAccessor, OnInit |
92 | 92 | clearRule: [null], |
93 | 93 | propagate: [null], |
94 | 94 | propagateRelationTypes: [null] |
95 | - }); | |
95 | + }, { validators: deviceProfileAlarmValidator }); | |
96 | 96 | this.alarmFormGroup.valueChanges.subscribe(() => { |
97 | 97 | this.updateModel(); |
98 | 98 | }); | ... | ... |
... | ... | @@ -30,7 +30,7 @@ import { |
30 | 30 | import { Store } from '@ngrx/store'; |
31 | 31 | import { AppState } from '@app/core/core.state'; |
32 | 32 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
33 | -import { DeviceProfileAlarm } from '@shared/models/device.models'; | |
33 | +import { DeviceProfileAlarm, deviceProfileAlarmValidator } from '@shared/models/device.models'; | |
34 | 34 | import { guid } from '@core/utils'; |
35 | 35 | import { Subscription } from 'rxjs'; |
36 | 36 | import { MatDialog } from '@angular/material/dialog'; |
... | ... | @@ -141,7 +141,7 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni |
141 | 141 | id: guid(), |
142 | 142 | alarmType: '', |
143 | 143 | createRules: { |
144 | - empty: { | |
144 | + CRITICAL: { | |
145 | 145 | condition: { |
146 | 146 | condition: [] |
147 | 147 | } |
... | ... | @@ -149,8 +149,11 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni |
149 | 149 | } |
150 | 150 | }; |
151 | 151 | const alarmsArray = this.deviceProfileAlarmsFormGroup.get('alarms') as FormArray; |
152 | - alarmsArray.push(this.fb.control(alarm, [Validators.required])); | |
152 | + alarmsArray.push(this.fb.control(alarm, [deviceProfileAlarmValidator])); | |
153 | 153 | this.deviceProfileAlarmsFormGroup.updateValueAndValidity(); |
154 | + if (!this.deviceProfileAlarmsFormGroup.valid) { | |
155 | + this.updateModel(); | |
156 | + } | |
154 | 157 | } |
155 | 158 | |
156 | 159 | public validate(c: FormControl) { | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | -<form (ngSubmit)="save()" style="min-width: 1000px;"> | |
18 | +<form (ngSubmit)="save()" style="width: 1000px;"> | |
19 | 19 | <mat-toolbar color="primary"> |
20 | 20 | <h2>{{ (isAdd ? 'device-profile.add' : 'device-profile.edit' ) | translate }}</h2> |
21 | 21 | <span fxFlex></span> |
... | ... | @@ -37,11 +37,6 @@ |
37 | 37 | </tb-device-profile> |
38 | 38 | </div> |
39 | 39 | <div mat-dialog-actions fxLayoutAlign="end center"> |
40 | - <button mat-raised-button color="primary" | |
41 | - type="submit" | |
42 | - [disabled]="(isLoading$ | async) || deviceProfileComponent.entityForm?.invalid || !deviceProfileComponent.entityForm?.dirty"> | |
43 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
44 | - </button> | |
45 | 40 | <button mat-button color="primary" |
46 | 41 | type="button" |
47 | 42 | cdkFocusInitial |
... | ... | @@ -49,5 +44,10 @@ |
49 | 44 | (click)="cancel()"> |
50 | 45 | {{ 'action.cancel' | translate }} |
51 | 46 | </button> |
47 | + <button mat-raised-button color="primary" | |
48 | + type="submit" | |
49 | + [disabled]="(isLoading$ | async) || deviceProfileComponent.entityForm?.invalid || !deviceProfileComponent.entityForm?.dirty"> | |
50 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
51 | + </button> | |
52 | 52 | </div> |
53 | 53 | </form> | ... | ... |
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | </div> |
42 | 42 | <div class="mat-padding" fxLayout="column"> |
43 | 43 | <form [formGroup]="entityForm"> |
44 | - <fieldset [disabled]="(isLoading$ | async) || !isEdit"> | |
44 | + <fieldset [disabled]="(isLoading$ | async) || !isEdit" style="min-width: 0;"> | |
45 | 45 | <mat-form-field class="mat-block"> |
46 | 46 | <mat-label translate>device-profile.name</mat-label> |
47 | 47 | <input matInput formControlName="name" required/> | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | -<form (ngSubmit)="save()" style="min-width: 600px;"> | |
18 | +<form (ngSubmit)="save()" style="width: 600px;"> | |
19 | 19 | <mat-toolbar color="primary"> |
20 | 20 | <h2>{{ (isAdd ? 'tenant-profile.add' : 'tenant-profile.edit' ) | translate }}</h2> |
21 | 21 | <span fxFlex></span> |
... | ... | @@ -37,11 +37,6 @@ |
37 | 37 | </tb-tenant-profile> |
38 | 38 | </div> |
39 | 39 | <div mat-dialog-actions fxLayoutAlign="end center"> |
40 | - <button mat-raised-button color="primary" | |
41 | - type="submit" | |
42 | - [disabled]="(isLoading$ | async) || tenantProfileComponent.entityForm?.invalid || !tenantProfileComponent.entityForm?.dirty"> | |
43 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
44 | - </button> | |
45 | 40 | <button mat-button color="primary" |
46 | 41 | type="button" |
47 | 42 | cdkFocusInitial |
... | ... | @@ -49,5 +44,10 @@ |
49 | 44 | (click)="cancel()"> |
50 | 45 | {{ 'action.cancel' | translate }} |
51 | 46 | </button> |
47 | + <button mat-raised-button color="primary" | |
48 | + type="submit" | |
49 | + [disabled]="(isLoading$ | async) || tenantProfileComponent.entityForm?.invalid || !tenantProfileComponent.entityForm?.dirty"> | |
50 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
51 | + </button> | |
52 | 52 | </div> |
53 | 53 | </form> | ... | ... |
... | ... | @@ -53,17 +53,16 @@ |
53 | 53 | </div> |
54 | 54 | <div mat-dialog-actions fxLayout="row"> |
55 | 55 | <span fxFlex></span> |
56 | - <button mat-button mat-raised-button color="primary" | |
57 | - type="submit" | |
58 | - [disabled]="(isLoading$ | async) || relationFormGroup.invalid || !(relationFormGroup.dirty || additionalInfo.dirty)"> | |
59 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
60 | - </button> | |
61 | 56 | <button mat-button color="primary" |
62 | - style="margin-right: 20px;" | |
63 | 57 | type="button" |
64 | 58 | [disabled]="(isLoading$ | async)" |
65 | 59 | (click)="cancel()" cdkFocusInitial> |
66 | 60 | {{ 'action.cancel' | translate }} |
67 | 61 | </button> |
62 | + <button mat-button mat-raised-button color="primary" | |
63 | + type="submit" | |
64 | + [disabled]="(isLoading$ | async) || relationFormGroup.invalid || !(relationFormGroup.dirty || additionalInfo.dirty)"> | |
65 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
66 | + </button> | |
68 | 67 | </div> |
69 | 68 | </form> | ... | ... |
... | ... | @@ -147,16 +147,16 @@ |
147 | 147 | </fieldset> |
148 | 148 | </div> |
149 | 149 | <div mat-dialog-actions fxLayoutAlign="end center"> |
150 | - <button mat-raised-button color="primary" | |
151 | - type="submit" | |
152 | - [disabled]="(isLoading$ | async) || widgetActionFormGroup.invalid || actionTypeFormGroup.invalid || (!widgetActionFormGroup.dirty && !actionTypeFormGroup.dirty)"> | |
153 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
154 | - </button> | |
155 | 150 | <button mat-button color="primary" |
156 | 151 | type="button" |
157 | 152 | [disabled]="(isLoading$ | async)" |
158 | 153 | (click)="cancel()" cdkFocusInitial> |
159 | 154 | {{ 'action.cancel' | translate }} |
160 | 155 | </button> |
156 | + <button mat-raised-button color="primary" | |
157 | + type="submit" | |
158 | + [disabled]="(isLoading$ | async) || widgetActionFormGroup.invalid || actionTypeFormGroup.invalid || (!widgetActionFormGroup.dirty && !actionTypeFormGroup.dirty)"> | |
159 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
160 | + </button> | |
161 | 161 | </div> |
162 | 162 | </form> | ... | ... |
... | ... | @@ -38,16 +38,16 @@ |
38 | 38 | </tb-data-key-config> |
39 | 39 | </div> |
40 | 40 | <div mat-dialog-actions fxLayoutAlign="end center"> |
41 | - <button mat-raised-button color="primary" | |
42 | - type="submit" | |
43 | - [disabled]="(isLoading$ | async) || dataKeyFormGroup.invalid || !dataKeyFormGroup.dirty"> | |
44 | - {{ 'action.save' | translate }} | |
45 | - </button> | |
46 | 41 | <button mat-button color="primary" |
47 | 42 | type="button" |
48 | 43 | [disabled]="(isLoading$ | async)" |
49 | 44 | (click)="cancel()" cdkFocusInitial> |
50 | 45 | {{ 'action.cancel' | translate }} |
51 | 46 | </button> |
47 | + <button mat-raised-button color="primary" | |
48 | + type="submit" | |
49 | + [disabled]="(isLoading$ | async) || dataKeyFormGroup.invalid || !dataKeyFormGroup.dirty"> | |
50 | + {{ 'action.save' | translate }} | |
51 | + </button> | |
52 | 52 | </div> |
53 | 53 | </form> | ... | ... |
... | ... | @@ -50,17 +50,16 @@ |
50 | 50 | </mat-chip-list> |
51 | 51 | </mat-form-field> |
52 | 52 | <div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center"> |
53 | + <button type="button" | |
54 | + mat-button | |
55 | + (click)="cancel()"> | |
56 | + {{ 'action.cancel' | translate }} | |
57 | + </button> | |
53 | 58 | <button type="submit" |
54 | 59 | mat-raised-button |
55 | 60 | color="primary" |
56 | 61 | [disabled]="alarmFilterFormGroup.invalid || !alarmFilterFormGroup.dirty"> |
57 | 62 | {{ 'action.update' | translate }} |
58 | 63 | </button> |
59 | - <button type="button" | |
60 | - mat-button | |
61 | - (click)="cancel()" | |
62 | - style="margin-right: 20px;"> | |
63 | - {{ 'action.cancel' | translate }} | |
64 | - </button> | |
65 | 64 | </div> |
66 | 65 | </form> | ... | ... |
... | ... | @@ -28,7 +28,6 @@ |
28 | 28 | <div class="tb-panel-actions" fxLayout="row" *ngIf="!settings.autoConfirm"> |
29 | 29 | <span fxFlex></span> |
30 | 30 | <button mat-button mat-raised-button color="primary" |
31 | - style="margin-right: 20px;" | |
32 | 31 | type="button" (click)="apply()"> |
33 | 32 | {{ 'action.ok' | translate }} |
34 | 33 | </button> | ... | ... |
... | ... | @@ -40,17 +40,17 @@ |
40 | 40 | </fieldset> |
41 | 41 | </div> |
42 | 42 | <div mat-dialog-actions fxLayoutAlign="end center"> |
43 | - <button mat-raised-button color="primary" | |
44 | - type="submit" | |
45 | - [disabled]="(isLoading$ | async) || addEntitiesToCustomerFormGroup.invalid | |
46 | - || !addEntitiesToCustomerFormGroup.dirty"> | |
47 | - {{ 'action.assign' | translate }} | |
48 | - </button> | |
49 | 43 | <button mat-button color="primary" |
50 | 44 | type="button" |
51 | 45 | [disabled]="(isLoading$ | async)" |
52 | 46 | (click)="cancel()" cdkFocusInitial> |
53 | 47 | {{ 'action.cancel' | translate }} |
54 | 48 | </button> |
49 | + <button mat-raised-button color="primary" | |
50 | + type="submit" | |
51 | + [disabled]="(isLoading$ | async) || addEntitiesToCustomerFormGroup.invalid | |
52 | + || !addEntitiesToCustomerFormGroup.dirty"> | |
53 | + {{ 'action.assign' | translate }} | |
54 | + </button> | |
55 | 55 | </div> |
56 | 56 | </form> | ... | ... |
... | ... | @@ -39,17 +39,17 @@ |
39 | 39 | </fieldset> |
40 | 40 | </div> |
41 | 41 | <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> |
42 | - <button mat-raised-button color="primary" | |
43 | - type="submit" | |
44 | - [disabled]="(isLoading$ | async) || assignToCustomerFormGroup.invalid | |
45 | - || !assignToCustomerFormGroup.dirty"> | |
46 | - {{ 'action.assign' | translate }} | |
47 | - </button> | |
48 | 42 | <button mat-button color="primary" |
49 | 43 | type="button" |
50 | 44 | [disabled]="(isLoading$ | async)" |
51 | 45 | (click)="cancel()" cdkFocusInitial> |
52 | 46 | {{ 'action.cancel' | translate }} |
53 | 47 | </button> |
48 | + <button mat-raised-button color="primary" | |
49 | + type="submit" | |
50 | + [disabled]="(isLoading$ | async) || assignToCustomerFormGroup.invalid | |
51 | + || !assignToCustomerFormGroup.dirty"> | |
52 | + {{ 'action.assign' | translate }} | |
53 | + </button> | |
54 | 54 | </div> |
55 | 55 | </form> | ... | ... |
... | ... | @@ -41,11 +41,6 @@ |
41 | 41 | </fieldset> |
42 | 42 | </div> |
43 | 43 | <div mat-dialog-actions fxLayoutAlign="end center"> |
44 | - <button mat-raised-button color="primary" | |
45 | - type="submit" | |
46 | - [disabled]="(isLoading$ | async) || widgetFormGroup.invalid"> | |
47 | - {{ 'action.add' | translate }} | |
48 | - </button> | |
49 | 44 | <button mat-button color="primary" |
50 | 45 | type="button" |
51 | 46 | [disabled]="(isLoading$ | async)" |
... | ... | @@ -53,5 +48,10 @@ |
53 | 48 | cdkFocusInitial> |
54 | 49 | {{ 'action.cancel' | translate }} |
55 | 50 | </button> |
51 | + <button mat-raised-button color="primary" | |
52 | + type="submit" | |
53 | + [disabled]="(isLoading$ | async) || widgetFormGroup.invalid"> | |
54 | + {{ 'action.add' | translate }} | |
55 | + </button> | |
56 | 56 | </div> |
57 | 57 | </form> | ... | ... |
... | ... | @@ -152,17 +152,17 @@ |
152 | 152 | </fieldset> |
153 | 153 | </div> |
154 | 154 | <div mat-dialog-actions fxLayoutAlign="end center"> |
155 | - <button mat-raised-button color="primary" | |
156 | - type="submit" | |
157 | - [disabled]="(isLoading$ | async) || settingsFormGroup.invalid || gridSettingsFormGroup.invalid | |
158 | - || (!settingsFormGroup.dirty && !gridSettingsFormGroup.dirty)"> | |
159 | - {{ 'action.save' | translate }} | |
160 | - </button> | |
161 | 155 | <button mat-button color="primary" |
162 | 156 | type="button" |
163 | 157 | [disabled]="(isLoading$ | async)" |
164 | 158 | (click)="cancel()" cdkFocusInitial> |
165 | 159 | {{ 'action.cancel' | translate }} |
166 | 160 | </button> |
161 | + <button mat-raised-button color="primary" | |
162 | + type="submit" | |
163 | + [disabled]="(isLoading$ | async) || settingsFormGroup.invalid || gridSettingsFormGroup.invalid | |
164 | + || (!settingsFormGroup.dirty && !gridSettingsFormGroup.dirty)"> | |
165 | + {{ 'action.save' | translate }} | |
166 | + </button> | |
167 | 167 | </div> |
168 | 168 | </form> | ... | ... |
... | ... | @@ -54,11 +54,6 @@ |
54 | 54 | </fieldset> |
55 | 55 | </div> |
56 | 56 | <div mat-dialog-actions fxLayoutAlign="end center"> |
57 | - <button mat-raised-button color="primary" | |
58 | - type="submit" | |
59 | - [disabled]="(isLoading$ | async) || layoutsFormGroup.invalid || !layoutsFormGroup.dirty"> | |
60 | - {{ 'action.save' | translate }} | |
61 | - </button> | |
62 | 57 | <button mat-button |
63 | 58 | color="primary" |
64 | 59 | type="button" |
... | ... | @@ -66,5 +61,10 @@ |
66 | 61 | (click)="cancel()" cdkFocusInitial> |
67 | 62 | {{ 'action.cancel' | translate }} |
68 | 63 | </button> |
64 | + <button mat-raised-button color="primary" | |
65 | + type="submit" | |
66 | + [disabled]="(isLoading$ | async) || layoutsFormGroup.invalid || !layoutsFormGroup.dirty"> | |
67 | + {{ 'action.save' | translate }} | |
68 | + </button> | |
69 | 69 | </div> |
70 | 70 | </form> | ... | ... |
... | ... | @@ -41,18 +41,17 @@ |
41 | 41 | </div> |
42 | 42 | <div mat-dialog-actions fxLayout="row"> |
43 | 43 | <span fxFlex></span> |
44 | - <button mat-button mat-raised-button color="primary" | |
45 | - type="submit" | |
46 | - [disabled]="(isLoading$ | async) || dashboardCustomersFormGroup.invalid | |
47 | - || !dashboardCustomersFormGroup.dirty"> | |
48 | - {{ actionName | translate }} | |
49 | - </button> | |
50 | 44 | <button mat-button color="primary" |
51 | - style="margin-right: 20px;" | |
52 | 45 | type="button" |
53 | 46 | [disabled]="(isLoading$ | async)" |
54 | 47 | (click)="cancel()" cdkFocusInitial> |
55 | 48 | {{ 'action.cancel' | translate }} |
56 | 49 | </button> |
50 | + <button mat-button mat-raised-button color="primary" | |
51 | + type="submit" | |
52 | + [disabled]="(isLoading$ | async) || dashboardCustomersFormGroup.invalid | |
53 | + || !dashboardCustomersFormGroup.dirty"> | |
54 | + {{ actionName | translate }} | |
55 | + </button> | |
57 | 56 | </div> |
58 | 57 | </form> | ... | ... |
... | ... | @@ -52,16 +52,16 @@ |
52 | 52 | </fieldset> |
53 | 53 | </div> |
54 | 54 | <div mat-dialog-actions fxLayoutAlign="end center"> |
55 | - <button mat-raised-button color="primary" | |
56 | - type="submit" | |
57 | - [disabled]="(isLoading$ | async) || stateFormGroup.invalid || !stateFormGroup.dirty"> | |
58 | - {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
59 | - </button> | |
60 | 55 | <button mat-button color="primary" |
61 | 56 | type="button" |
62 | 57 | [disabled]="(isLoading$ | async)" |
63 | 58 | (click)="cancel()" cdkFocusInitial> |
64 | 59 | {{ 'action.cancel' | translate }} |
65 | 60 | </button> |
61 | + <button mat-raised-button color="primary" | |
62 | + type="submit" | |
63 | + [disabled]="(isLoading$ | async) || stateFormGroup.invalid || !stateFormGroup.dirty"> | |
64 | + {{ (isAdd ? 'action.add' : 'action.save') | translate }} | |
65 | + </button> | |
66 | 66 | </div> |
67 | 67 | </form> | ... | ... |
... | ... | @@ -136,16 +136,16 @@ |
136 | 136 | </fieldset> |
137 | 137 | </div> |
138 | 138 | <div mat-dialog-actions fxLayoutAlign="end center"> |
139 | - <button mat-raised-button color="primary" | |
140 | - type="submit" | |
141 | - [disabled]="(isLoading$ | async) || statesFormGroup.invalid || !statesFormGroup.dirty"> | |
142 | - {{ 'action.save' | translate }} | |
143 | - </button> | |
144 | 139 | <button mat-button color="primary" |
145 | 140 | type="button" |
146 | 141 | [disabled]="(isLoading$ | async)" |
147 | 142 | (click)="cancel()" cdkFocusInitial> |
148 | 143 | {{ 'action.cancel' | translate }} |
149 | 144 | </button> |
145 | + <button mat-raised-button color="primary" | |
146 | + type="submit" | |
147 | + [disabled]="(isLoading$ | async) || statesFormGroup.invalid || !statesFormGroup.dirty"> | |
148 | + {{ 'action.save' | translate }} | |
149 | + </button> | |
150 | 150 | </div> |
151 | 151 | </form> | ... | ... |
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 | </div> |
71 | 71 | </div> |
72 | 72 | </mat-tab> |
73 | -<mat-tab *ngIf="entity" | |
73 | +<mat-tab *ngIf="entity && !isEdit" | |
74 | 74 | label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab"> |
75 | 75 | <tb-audit-log-table detailsMode="true" [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id"></tb-audit-log-table> |
76 | 76 | </mat-tab> | ... | ... |
... | ... | @@ -36,17 +36,17 @@ |
36 | 36 | </fieldset> |
37 | 37 | </div> |
38 | 38 | <div mat-dialog-actions fxLayoutAlign="end center"> |
39 | - <button *ngIf="!isReadOnly" mat-raised-button color="primary" | |
40 | - type="submit" | |
41 | - [disabled]="(isLoading$ | async) || deviceCredentialsFormGroup.invalid | |
42 | - || !deviceCredentialsFormGroup.dirty"> | |
43 | - {{ 'action.save' | translate }} | |
44 | - </button> | |
45 | 39 | <button mat-button color="primary" |
46 | 40 | type="button" |
47 | 41 | [disabled]="(isLoading$ | async)" |
48 | 42 | (click)="cancel()" cdkFocusInitial> |
49 | 43 | {{ (isReadOnly ? 'action.close' : 'action.cancel') | translate }} |
50 | 44 | </button> |
45 | + <button *ngIf="!isReadOnly" mat-raised-button color="primary" | |
46 | + type="submit" | |
47 | + [disabled]="(isLoading$ | async) || deviceCredentialsFormGroup.invalid | |
48 | + || !deviceCredentialsFormGroup.dirty"> | |
49 | + {{ 'action.save' | translate }} | |
50 | + </button> | |
51 | 51 | </div> |
52 | 52 | </form> | ... | ... |
... | ... | @@ -46,16 +46,16 @@ |
46 | 46 | </mat-form-field> |
47 | 47 | </div> |
48 | 48 | <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> |
49 | - <button mat-raised-button color="primary" | |
50 | - type="submit" | |
51 | - [disabled]="(isLoading$ | async) || changePassword.invalid"> | |
52 | - {{ 'profile.change-password' | translate }} | |
53 | - </button> | |
54 | 49 | <button mat-button color="primary" |
55 | 50 | type="button" |
56 | 51 | [disabled]="(isLoading$ | async)" |
57 | 52 | [mat-dialog-close]="false" cdkFocusInitial> |
58 | 53 | {{ 'action.cancel' | translate }} |
59 | 54 | </button> |
55 | + <button mat-raised-button color="primary" | |
56 | + type="submit" | |
57 | + [disabled]="(isLoading$ | async) || changePassword.invalid"> | |
58 | + {{ 'profile.change-password' | translate }} | |
59 | + </button> | |
60 | 60 | </div> |
61 | 61 | </form> | ... | ... |
... | ... | @@ -40,16 +40,16 @@ |
40 | 40 | </fieldset> |
41 | 41 | </div> |
42 | 42 | <div mat-dialog-actions fxLayoutAlign="end center"> |
43 | - <button mat-raised-button color="primary" | |
44 | - type="submit" | |
45 | - [disabled]="(isLoading$ | async) || tbRuleNode.ruleNodeFormGroup.invalid || !tbRuleNode.ruleNodeFormGroup.dirty"> | |
46 | - {{ 'action.add' | translate }} | |
47 | - </button> | |
48 | 43 | <button mat-button color="primary" |
49 | 44 | type="button" |
50 | 45 | [disabled]="(isLoading$ | async)" |
51 | 46 | (click)="cancel()" cdkFocusInitial> |
52 | 47 | {{ 'action.cancel' | translate }} |
53 | 48 | </button> |
49 | + <button mat-raised-button color="primary" | |
50 | + type="submit" | |
51 | + [disabled]="(isLoading$ | async) || tbRuleNode.ruleNodeFormGroup.invalid || !tbRuleNode.ruleNodeFormGroup.dirty"> | |
52 | + {{ 'action.add' | translate }} | |
53 | + </button> | |
54 | 54 | </div> |
55 | 55 | </form> | ... | ... |
... | ... | @@ -39,16 +39,16 @@ |
39 | 39 | </fieldset> |
40 | 40 | </div> |
41 | 41 | <div mat-dialog-actions fxLayoutAlign="end center"> |
42 | - <button mat-raised-button color="primary" | |
43 | - type="submit" | |
44 | - [disabled]="(isLoading$ | async) || ruleNodeLinkFormGroup.invalid || !ruleNodeLinkFormGroup.dirty"> | |
45 | - {{ 'action.add' | translate }} | |
46 | - </button> | |
47 | 42 | <button mat-button color="primary" |
48 | 43 | type="button" |
49 | 44 | [disabled]="(isLoading$ | async)" |
50 | 45 | (click)="cancel()" cdkFocusInitial> |
51 | 46 | {{ 'action.cancel' | translate }} |
52 | 47 | </button> |
48 | + <button mat-raised-button color="primary" | |
49 | + type="submit" | |
50 | + [disabled]="(isLoading$ | async) || ruleNodeLinkFormGroup.invalid || !ruleNodeLinkFormGroup.dirty"> | |
51 | + {{ 'action.add' | translate }} | |
52 | + </button> | |
53 | 53 | </div> |
54 | 54 | </form> | ... | ... |
... | ... | @@ -41,11 +41,6 @@ |
41 | 41 | </mat-form-field> |
42 | 42 | </div> |
43 | 43 | <div mat-dialog-actions fxLayoutAlign="end center"> |
44 | - <button mat-raised-button color="primary" | |
45 | - type="submit" | |
46 | - [disabled]="(isLoading$ | async) || detailsForm.invalid || !detailsForm.dirty"> | |
47 | - {{ 'action.add' | translate }} | |
48 | - </button> | |
49 | 44 | <button mat-button color="primary" |
50 | 45 | type="button" |
51 | 46 | cdkFocusInitial |
... | ... | @@ -53,5 +48,10 @@ |
53 | 48 | (click)="cancel()"> |
54 | 49 | {{ 'action.cancel' | translate }} |
55 | 50 | </button> |
51 | + <button mat-raised-button color="primary" | |
52 | + type="submit" | |
53 | + [disabled]="(isLoading$ | async) || detailsForm.invalid || !detailsForm.dirty"> | |
54 | + {{ 'action.add' | translate }} | |
55 | + </button> | |
56 | 56 | </div> |
57 | 57 | </form> | ... | ... |
... | ... | @@ -46,17 +46,17 @@ |
46 | 46 | </fieldset> |
47 | 47 | </div> |
48 | 48 | <div mat-dialog-actions fxLayoutAlign="end center"> |
49 | - <button mat-raised-button color="primary" | |
50 | - type="submit" | |
51 | - [disabled]="(isLoading$ | async) || saveWidgetTypeAsFormGroup.invalid | |
52 | - || !saveWidgetTypeAsFormGroup.dirty"> | |
53 | - {{ 'action.saveAs' | translate }} | |
54 | - </button> | |
55 | 49 | <button mat-button color="primary" |
56 | 50 | type="button" |
57 | 51 | [disabled]="(isLoading$ | async)" |
58 | 52 | (click)="cancel()" cdkFocusInitial> |
59 | 53 | {{ 'action.cancel' | translate }} |
60 | 54 | </button> |
55 | + <button mat-raised-button color="primary" | |
56 | + type="submit" | |
57 | + [disabled]="(isLoading$ | async) || saveWidgetTypeAsFormGroup.invalid | |
58 | + || !saveWidgetTypeAsFormGroup.dirty"> | |
59 | + {{ 'action.saveAs' | translate }} | |
60 | + </button> | |
61 | 61 | </div> |
62 | 62 | </form> | ... | ... |
... | ... | @@ -41,17 +41,16 @@ |
41 | 41 | </div> |
42 | 42 | <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> |
43 | 43 | <span fxFlex></span> |
44 | - <button mat-button mat-raised-button color="primary" | |
45 | - type="submit" | |
46 | - [disabled]="(isLoading$ | async) || jsonFormGroup.invalid || !jsonFormGroup.dirty"> | |
47 | - {{ 'action.save' | translate }} | |
48 | - </button> | |
49 | 44 | <button mat-button color="primary" |
50 | - style="margin-right: 20px;" | |
51 | 45 | type="button" |
52 | 46 | [disabled]="(isLoading$ | async)" |
53 | 47 | (click)="cancel()" cdkFocusInitial> |
54 | 48 | {{ 'action.cancel' | translate }} |
55 | 49 | </button> |
50 | + <button mat-button mat-raised-button color="primary" | |
51 | + type="submit" | |
52 | + [disabled]="(isLoading$ | async) || jsonFormGroup.invalid || !jsonFormGroup.dirty"> | |
53 | + {{ 'action.save' | translate }} | |
54 | + </button> | |
56 | 55 | </div> |
57 | 56 | </form> | ... | ... |
... | ... | @@ -109,18 +109,17 @@ |
109 | 109 | {{ 'rulenode.test' | translate }} |
110 | 110 | </button> |
111 | 111 | <span fxFlex></span> |
112 | - <button mat-button mat-raised-button color="primary" | |
113 | - type="submit" | |
114 | - [disabled]="(isLoading$ | async) || nodeScriptTestFormGroup.get('script').invalid || !nodeScriptTestFormGroup.get('script').dirty"> | |
115 | - {{ 'action.save' | translate }} | |
116 | - </button> | |
117 | 112 | <button mat-button color="primary" |
118 | - style="margin-right: 20px;" | |
119 | 113 | type="button" |
120 | 114 | cdkFocusInitial |
121 | 115 | [disabled]="(isLoading$ | async)" |
122 | 116 | (click)="cancel()"> |
123 | 117 | {{ 'action.cancel' | translate }} |
124 | 118 | </button> |
119 | + <button mat-button mat-raised-button color="primary" | |
120 | + type="submit" | |
121 | + [disabled]="(isLoading$ | async) || nodeScriptTestFormGroup.get('script').invalid || !nodeScriptTestFormGroup.get('script').dirty"> | |
122 | + {{ 'action.save' | translate }} | |
123 | + </button> | |
125 | 124 | </div> |
126 | 125 | </form> | ... | ... |
... | ... | @@ -140,19 +140,18 @@ |
140 | 140 | </tb-timeinterval> |
141 | 141 | </div> |
142 | 142 | <div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center"> |
143 | + <button type="button" | |
144 | + mat-button | |
145 | + [disabled]="(isLoading$ | async)" | |
146 | + (click)="cancel()"> | |
147 | + {{ 'action.cancel' | translate }} | |
148 | + </button> | |
143 | 149 | <button type="submit" |
144 | 150 | mat-raised-button |
145 | 151 | color="primary" |
146 | 152 | [disabled]="(isLoading$ | async) || timewindowForm.invalid || !timewindowForm.dirty"> |
147 | 153 | {{ 'action.update' | translate }} |
148 | 154 | </button> |
149 | - <button type="button" | |
150 | - mat-button | |
151 | - [disabled]="(isLoading$ | async)" | |
152 | - (click)="cancel()" | |
153 | - style="margin-right: 20px;"> | |
154 | - {{ 'action.cancel' | translate }} | |
155 | - </button> | |
156 | 155 | </div> |
157 | 156 | </div> |
158 | 157 | </fieldset> | ... | ... |
... | ... | @@ -26,7 +26,7 @@ import { EntityInfoData } from '@shared/models/entity.models'; |
26 | 26 | import { KeyFilter } from '@shared/models/query/query.models'; |
27 | 27 | import { TimeUnit } from '@shared/models/time/time.models'; |
28 | 28 | import * as _moment from 'moment-timezone'; |
29 | -import { AbstractControl, FormGroup } from '@angular/forms'; | |
29 | +import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms'; | |
30 | 30 | |
31 | 31 | export enum DeviceProfileType { |
32 | 32 | DEFAULT = 'DEFAULT' |
... | ... | @@ -87,7 +87,7 @@ export const deviceProvisionTypeTranslationMap = new Map<DeviceProvisionType, st |
87 | 87 | [DeviceProvisionType.ALLOW_CREATE_NEW_DEVICES, 'device-profile.provision-strategy-created-new'], |
88 | 88 | [DeviceProvisionType.CHECK_PRE_PROVISIONED_DEVICES, 'device-profile.provision-strategy-check-pre-provisioned'] |
89 | 89 | ] |
90 | -) | |
90 | +); | |
91 | 91 | |
92 | 92 | export const deviceTransportTypeHintMap = new Map<DeviceTransportType, string>( |
93 | 93 | [ |
... | ... | @@ -303,6 +303,18 @@ export interface AlarmRule { |
303 | 303 | schedule?: AlarmSchedule; |
304 | 304 | } |
305 | 305 | |
306 | +export function alarmRuleValidator(control: AbstractControl): ValidationErrors | null { | |
307 | + const alarmRule: AlarmRule = control.value; | |
308 | + return alarmRuleValid(alarmRule) ? null : {alarmRule: true}; | |
309 | +} | |
310 | + | |
311 | +function alarmRuleValid(alarmRule: AlarmRule): boolean { | |
312 | + if (!alarmRule || !alarmRule.condition || !alarmRule.condition.condition || !alarmRule.condition.condition.length) { | |
313 | + return false; | |
314 | + } | |
315 | + return true; | |
316 | +} | |
317 | + | |
306 | 318 | export interface DeviceProfileAlarm { |
307 | 319 | id: string; |
308 | 320 | alarmType: string; |
... | ... | @@ -312,6 +324,34 @@ export interface DeviceProfileAlarm { |
312 | 324 | propagateRelationTypes?: Array<string>; |
313 | 325 | } |
314 | 326 | |
327 | +export function deviceProfileAlarmValidator(control: AbstractControl): ValidationErrors | null { | |
328 | + const deviceProfileAlarm: DeviceProfileAlarm = control.value; | |
329 | + if (deviceProfileAlarm && deviceProfileAlarm.id && deviceProfileAlarm.alarmType && | |
330 | + deviceProfileAlarm.createRules) { | |
331 | + const severities = Object.keys(deviceProfileAlarm.createRules); | |
332 | + if (severities.length) { | |
333 | + let alarmRulesValid = true; | |
334 | + for (const severity of severities) { | |
335 | + const alarmRule = deviceProfileAlarm.createRules[severity]; | |
336 | + if (!alarmRuleValid(alarmRule)) { | |
337 | + alarmRulesValid = false; | |
338 | + break; | |
339 | + } | |
340 | + } | |
341 | + if (alarmRulesValid) { | |
342 | + if (deviceProfileAlarm.clearRule && !alarmRuleValid(deviceProfileAlarm.clearRule)) { | |
343 | + alarmRulesValid = false; | |
344 | + } | |
345 | + } | |
346 | + if (alarmRulesValid) { | |
347 | + return null; | |
348 | + } | |
349 | + } | |
350 | + } | |
351 | + return {deviceProfileAlarm: true}; | |
352 | +} | |
353 | + | |
354 | + | |
315 | 355 | export interface DeviceProfileData { |
316 | 356 | configuration: DeviceProfileConfiguration; |
317 | 357 | transportConfiguration: DeviceProfileTransportConfiguration; | ... | ... |
... | ... | @@ -908,6 +908,7 @@ |
908 | 908 | "create-alarm-pattern": "Create <b>{{alarmType}}</b> alarm", |
909 | 909 | "create-alarm-rules": "Create alarm rules", |
910 | 910 | "no-create-alarm-rules": "No create conditions configured", |
911 | + "add-create-alarm-rule-prompt": "Please add create alarm rule", | |
911 | 912 | "clear-alarm-rule": "Clear alarm rule", |
912 | 913 | "no-clear-alarm-rule": "No clear condition configured", |
913 | 914 | "add-create-alarm-rule": "Add create condition", | ... | ... |