Commit ed090b3e6cedb5b1ecdb0a283c9b616740641c31

Authored by Igor Kulikov
1 parent 52e6e76a

UI: Improve dialog actions style

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>
... ...
... ... @@ -26,7 +26,6 @@
26 26 <div fxLayout="row" class="tb-panel-actions">
27 27 <span fxFlex></span>
28 28 <button mat-button color="primary"
29   - style="margin-right: 20px;"
30 29 type="button"
31 30 [disabled]="(isLoading$ | async)"
32 31 (click)="cancel()" cdkFocusInitial>
... ...
... ... @@ -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>
... ...
... ... @@ -31,7 +31,6 @@
31 31 <div mat-dialog-actions fxLayout="row">
32 32 <span fxFlex></span>
33 33 <button mat-button color="primary"
34   - style="margin-right: 20px;"
35 34 type="button"
36 35 [disabled]="(isLoading$ | async)"
37 36 [mat-dialog-close]="false" cdkFocusInitial>
... ...
... ... @@ -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>
... ...
... ... @@ -54,7 +54,6 @@
54 54 <div mat-dialog-actions fxLayout="row">
55 55 <span fxFlex></span>
56 56 <button mat-button color="primary"
57   - style="margin-right: 20px;"
58 57 type="button"
59 58 [disabled]="(isLoading$ | async)"
60 59 (click)="close()" cdkFocusInitial>
... ...
... ... @@ -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>
... ...
... ... @@ -34,7 +34,6 @@
34 34 </button>
35 35 <button mat-button
36 36 type="submit"
37   - style="margin-right: 20px;"
38 37 [disabled]="(isLoading$ | async) || colorPickerFormGroup.invalid || !colorPickerFormGroup.dirty">
39 38 {{ 'action.select' | translate }}
40 39 </button>
... ...
... ... @@ -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",
... ...
... ... @@ -331,6 +331,9 @@ pre.tb-highlight {
331 331 font-weight: 400;
332 332 line-height: 18px;
333 333 color: rgba(0, 0, 0, .38);
  334 + &.required {
  335 + color: rgb(221, 44, 0);
  336 + }
334 337 }
335 338
336 339 .tb-fullscreen {
... ...