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,14 +88,20 @@
88 </fieldset> 88 </fieldset>
89 </div> 89 </div>
90 <div mat-dialog-actions fxLayout="row"> 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 <button *ngIf="allowAcknowledgment && (alarm.status === alarmStatuses.ACTIVE_UNACK || 99 <button *ngIf="allowAcknowledgment && (alarm.status === alarmStatuses.ACTIVE_UNACK ||
93 alarm.status === alarmStatuses.CLEARED_UNACK)" 100 alarm.status === alarmStatuses.CLEARED_UNACK)"
94 mat-raised-button 101 mat-raised-button
95 color="primary" 102 color="primary"
96 type="button" 103 type="button"
97 (click)="acknowledge()" 104 (click)="acknowledge()"
98 - style="margin-right: 20px;"  
99 [disabled]="(isLoading$ | async)"> 105 [disabled]="(isLoading$ | async)">
100 {{ 'alarm.acknowledge' | translate }} 106 {{ 'alarm.acknowledge' | translate }}
101 </button> 107 </button>
@@ -109,12 +115,5 @@ @@ -109,12 +115,5 @@
109 {{ 'alarm.clear' | translate }} 115 {{ 'alarm.clear' | translate }}
110 </button> 116 </button>
111 </div> 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 </div> 118 </div>
120 </form> 119 </form>
@@ -59,16 +59,16 @@ @@ -59,16 +59,16 @@
59 </fieldset> 59 </fieldset>
60 </div> 60 </div>
61 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 62 <button mat-button color="primary"
68 type="button" 63 type="button"
69 [disabled]="(isLoading$ | async)" 64 [disabled]="(isLoading$ | async)"
70 (click)="cancel()" cdkFocusInitial> 65 (click)="cancel()" cdkFocusInitial>
71 {{ 'action.cancel' | translate }} 66 {{ 'action.cancel' | translate }}
72 </button> 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 </div> 73 </div>
74 </form> 74 </form>
@@ -95,11 +95,6 @@ @@ -95,11 +95,6 @@
95 {{ 'alias.add' | translate }} 95 {{ 'alias.add' | translate }}
96 </button> 96 </button>
97 <span fxFlex></span> 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 <button mat-button color="primary" 98 <button mat-button color="primary"
104 type="button" 99 type="button"
105 [disabled]="(isLoading$ | async)" 100 [disabled]="(isLoading$ | async)"
@@ -107,5 +102,10 @@ @@ -107,5 +102,10 @@
107 cdkFocusInitial> 102 cdkFocusInitial>
108 {{ 'action.cancel' | translate }} 103 {{ 'action.cancel' | translate }}
109 </button> 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 </div> 110 </div>
111 </form> 111 </form>
@@ -44,16 +44,16 @@ @@ -44,16 +44,16 @@
44 </fieldset> 44 </fieldset>
45 </div> 45 </div>
46 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 47 <button mat-button color="primary"
53 type="button" 48 type="button"
54 [disabled]="(isLoading$ | async)" 49 [disabled]="(isLoading$ | async)"
55 (click)="cancel()" cdkFocusInitial> 50 (click)="cancel()" cdkFocusInitial>
56 {{ 'action.cancel' | translate }} 51 {{ 'action.cancel' | translate }}
57 </button> 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 </div> 58 </div>
59 </form> 59 </form>
@@ -55,21 +55,22 @@ @@ -55,21 +55,22 @@
55 </mat-radio-group> 55 </mat-radio-group>
56 </fieldset> 56 </fieldset>
57 </div> 57 </div>
58 - <div mat-dialog-actions fxLayoutAlign="end center"> 58 + <div mat-dialog-actions fxLayout="row">
59 <mat-checkbox formControlName="openDashboard" 59 <mat-checkbox formControlName="openDashboard"
60 - style="margin-bottom: 0; padding-right: 20px;"> 60 + style="margin-bottom: 0;">
61 {{ 'dashboard.open-dashboard' | translate }} 61 {{ 'dashboard.open-dashboard' | translate }}
62 </mat-checkbox> 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 <button mat-button color="primary" 64 <button mat-button color="primary"
69 type="button" 65 type="button"
70 [disabled]="(isLoading$ | async)" 66 [disabled]="(isLoading$ | async)"
71 (click)="cancel()" cdkFocusInitial> 67 (click)="cancel()" cdkFocusInitial>
72 {{ 'action.cancel' | translate }} 68 {{ 'action.cancel' | translate }}
73 </button> 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 </div> 75 </div>
75 </form> 76 </form>
@@ -26,7 +26,6 @@ @@ -26,7 +26,6 @@
26 <div fxLayout="row" class="tb-panel-actions"> 26 <div fxLayout="row" class="tb-panel-actions">
27 <span fxFlex></span> 27 <span fxFlex></span>
28 <button mat-button color="primary" 28 <button mat-button color="primary"
29 - style="margin-right: 20px;"  
30 type="button" 29 type="button"
31 [disabled]="(isLoading$ | async)" 30 [disabled]="(isLoading$ | async)"
32 (click)="cancel()" cdkFocusInitial> 31 (click)="cancel()" cdkFocusInitial>
@@ -40,11 +40,6 @@ @@ -40,11 +40,6 @@
40 </fieldset> 40 </fieldset>
41 </div> 41 </div>
42 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 43 <button mat-button color="primary"
49 type="button" 44 type="button"
50 [disabled]="(isLoading$ | async)" 45 [disabled]="(isLoading$ | async)"
@@ -52,5 +47,10 @@ @@ -52,5 +47,10 @@
52 cdkFocusInitial> 47 cdkFocusInitial>
53 {{ 'action.cancel' | translate }} 48 {{ 'action.cancel' | translate }}
54 </button> 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 </div> 55 </div>
56 </form> 56 </form>
@@ -31,7 +31,6 @@ @@ -31,7 +31,6 @@
31 <div mat-dialog-actions fxLayout="row"> 31 <div mat-dialog-actions fxLayout="row">
32 <span fxFlex></span> 32 <span fxFlex></span>
33 <button mat-button color="primary" 33 <button mat-button color="primary"
34 - style="margin-right: 20px;"  
35 type="button" 34 type="button"
36 [disabled]="(isLoading$ | async)" 35 [disabled]="(isLoading$ | async)"
37 [mat-dialog-close]="false" cdkFocusInitial> 36 [mat-dialog-close]="false" cdkFocusInitial>
@@ -46,12 +46,6 @@ @@ -46,12 +46,6 @@
46 </fieldset> 46 </fieldset>
47 </div> 47 </div>
48 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 49 <button mat-button color="primary"
56 type="button" 50 type="button"
57 [disabled]="(isLoading$ | async)" 51 [disabled]="(isLoading$ | async)"
@@ -59,5 +53,11 @@ @@ -59,5 +53,11 @@
59 cdkFocusInitial> 53 cdkFocusInitial>
60 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} 54 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }}
61 </button> 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 </div> 62 </div>
63 </form> 63 </form>
@@ -55,16 +55,16 @@ @@ -55,16 +55,16 @@
55 </fieldset> 55 </fieldset>
56 </div> 56 </div>
57 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 58 <button mat-button color="primary"
64 type="button" 59 type="button"
65 [disabled]="(isLoading$ | async)" 60 [disabled]="(isLoading$ | async)"
66 (click)="cancel()" cdkFocusInitial> 61 (click)="cancel()" cdkFocusInitial>
67 {{ 'action.cancel' | translate }} 62 {{ 'action.cancel' | translate }}
68 </button> 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 </div> 69 </div>
70 </form> 70 </form>
@@ -46,12 +46,6 @@ @@ -46,12 +46,6 @@
46 </fieldset> 46 </fieldset>
47 </div> 47 </div>
48 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 49 <button mat-button color="primary"
56 type="button" 50 type="button"
57 [disabled]="(isLoading$ | async)" 51 [disabled]="(isLoading$ | async)"
@@ -59,5 +53,11 @@ @@ -59,5 +53,11 @@
59 cdkFocusInitial> 53 cdkFocusInitial>
60 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} 54 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }}
61 </button> 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 </div> 62 </div>
63 </form> 63 </form>
@@ -88,11 +88,6 @@ @@ -88,11 +88,6 @@
88 {{ 'filter.add' | translate }} 88 {{ 'filter.add' | translate }}
89 </button> 89 </button>
90 <span fxFlex></span> 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 <button mat-button color="primary" 91 <button mat-button color="primary"
97 type="button" 92 type="button"
98 [disabled]="(isLoading$ | async)" 93 [disabled]="(isLoading$ | async)"
@@ -100,5 +95,10 @@ @@ -100,5 +95,10 @@
100 cdkFocusInitial> 95 cdkFocusInitial>
101 {{ 'action.cancel' | translate }} 96 {{ 'action.cancel' | translate }}
102 </button> 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 </div> 103 </div>
104 </form> 104 </form>
@@ -79,12 +79,6 @@ @@ -79,12 +79,6 @@
79 </fieldset> 79 </fieldset>
80 </div> 80 </div>
81 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 82 <button mat-button color="primary"
89 type="button" 83 type="button"
90 [disabled]="(isLoading$ | async)" 84 [disabled]="(isLoading$ | async)"
@@ -92,5 +86,11 @@ @@ -92,5 +86,11 @@
92 cdkFocusInitial> 86 cdkFocusInitial>
93 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }} 87 {{ (data.readonly ? 'action.close' : 'action.cancel') | translate }}
94 </button> 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 </div> 95 </div>
96 </form> 96 </form>
@@ -65,16 +65,16 @@ @@ -65,16 +65,16 @@
65 </fieldset> 65 </fieldset>
66 </div> 66 </div>
67 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 68 <button mat-button color="primary"
74 type="button" 69 type="button"
75 [disabled]="(isLoading$ | async)" 70 [disabled]="(isLoading$ | async)"
76 (click)="cancel()" cdkFocusInitial> 71 (click)="cancel()" cdkFocusInitial>
77 {{ 'action.cancel' | translate }} 72 {{ 'action.cancel' | translate }}
78 </button> 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 </div> 79 </div>
80 </form> 80 </form>
@@ -43,16 +43,16 @@ @@ -43,16 +43,16 @@
43 </fieldset> 43 </fieldset>
44 </div> 44 </div>
45 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 46 <button mat-button color="primary"
52 type="button" 47 type="button"
53 [disabled]="(isLoading$ | async)" 48 [disabled]="(isLoading$ | async)"
54 (click)="cancel()" cdkFocusInitial> 49 (click)="cancel()" cdkFocusInitial>
55 {{ 'action.cancel' | translate }} 50 {{ 'action.cancel' | translate }}
56 </button> 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 </div> 57 </div>
58 </form> 58 </form>
@@ -108,17 +108,17 @@ @@ -108,17 +108,17 @@
108 </fieldset> 108 </fieldset>
109 </div> 109 </div>
110 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 111 <button mat-button color="primary"
118 type="button" 112 type="button"
119 [disabled]="(isLoading$ | async)" 113 [disabled]="(isLoading$ | async)"
120 (click)="cancel()" cdkFocusInitial> 114 (click)="cancel()" cdkFocusInitial>
121 {{ (readonly ? 'action.close' : 'action.cancel') | translate }} 115 {{ (readonly ? 'action.close' : 'action.cancel') | translate }}
122 </button> 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 </div> 123 </div>
124 </form> 124 </form>
@@ -37,17 +37,17 @@ @@ -37,17 +37,17 @@
37 </fieldset> 37 </fieldset>
38 </div> 38 </div>
39 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 40 <button mat-button color="primary"
47 type="button" 41 type="button"
48 [disabled]="(isLoading$ | async)" 42 [disabled]="(isLoading$ | async)"
49 (click)="cancel()" cdkFocusInitial> 43 (click)="cancel()" cdkFocusInitial>
50 {{ (readonly ? 'action.close' : 'action.cancel') | translate }} 44 {{ (readonly ? 'action.close' : 'action.cancel') | translate }}
51 </button> 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 </div> 52 </div>
53 </form> 53 </form>
@@ -47,9 +47,9 @@ @@ -47,9 +47,9 @@
47 <mat-icon>remove_circle_outline</mat-icon> 47 <mat-icon>remove_circle_outline</mat-icon>
48 </button> 48 </button>
49 </div> 49 </div>
50 - <div *ngIf="!createAlarmRulesFormArray().controls.length"> 50 + <div *ngIf="!createAlarmRulesFormArray().controls.length && !disabled">
51 <span translate fxLayoutAlign="center center" style="margin: 16px 0" 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 </div> 53 </div>
54 <div fxLayout="row" *ngIf="!disabled"> 54 <div fxLayout="row" *ngIf="!disabled">
55 <button mat-stroked-button color="primary" 55 <button mat-stroked-button color="primary"
@@ -23,11 +23,11 @@ import { @@ -23,11 +23,11 @@ import {
23 FormControl, 23 FormControl,
24 FormGroup, 24 FormGroup,
25 NG_VALIDATORS, 25 NG_VALIDATORS,
26 - NG_VALUE_ACCESSOR, 26 + NG_VALUE_ACCESSOR, ValidationErrors,
27 Validator, 27 Validator,
28 Validators 28 Validators
29 } from '@angular/forms'; 29 } from '@angular/forms';
30 -import { AlarmRule } from '@shared/models/device.models'; 30 +import { AlarmRule, alarmRuleValidator } from '@shared/models/device.models';
31 import { MatDialog } from '@angular/material/dialog'; 31 import { MatDialog } from '@angular/material/dialog';
32 import { Subscription } from 'rxjs'; 32 import { Subscription } from 'rxjs';
33 import { AlarmSeverity, alarmSeverityTranslations } from '../../../../../shared/models/alarm.models'; 33 import { AlarmSeverity, alarmSeverityTranslations } from '../../../../../shared/models/alarm.models';
@@ -141,10 +141,23 @@ export class CreateAlarmRulesComponent implements ControlValueAccessor, OnInit, @@ -141,10 +141,23 @@ export class CreateAlarmRulesComponent implements ControlValueAccessor, OnInit,
141 }; 141 };
142 const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray; 142 const createAlarmRulesArray = this.createAlarmRulesFormGroup.get('createAlarmRules') as FormArray;
143 createAlarmRulesArray.push(this.fb.group({ 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 this.createAlarmRulesFormGroup.updateValueAndValidity(); 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 public validate(c: FormControl) { 163 public validate(c: FormControl) {
@@ -25,7 +25,7 @@ import { @@ -25,7 +25,7 @@ import {
25 Validator, 25 Validator,
26 Validators 26 Validators
27 } from '@angular/forms'; 27 } from '@angular/forms';
28 -import { AlarmRule, DeviceProfileAlarm } from '@shared/models/device.models'; 28 +import { AlarmRule, DeviceProfileAlarm, deviceProfileAlarmValidator } from '@shared/models/device.models';
29 import { MatDialog } from '@angular/material/dialog'; 29 import { MatDialog } from '@angular/material/dialog';
30 import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; 30 import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
31 import { MatChipInputEvent } from '@angular/material/chips'; 31 import { MatChipInputEvent } from '@angular/material/chips';
@@ -92,7 +92,7 @@ export class DeviceProfileAlarmComponent implements ControlValueAccessor, OnInit @@ -92,7 +92,7 @@ export class DeviceProfileAlarmComponent implements ControlValueAccessor, OnInit
92 clearRule: [null], 92 clearRule: [null],
93 propagate: [null], 93 propagate: [null],
94 propagateRelationTypes: [null] 94 propagateRelationTypes: [null]
95 - }); 95 + }, { validators: deviceProfileAlarmValidator });
96 this.alarmFormGroup.valueChanges.subscribe(() => { 96 this.alarmFormGroup.valueChanges.subscribe(() => {
97 this.updateModel(); 97 this.updateModel();
98 }); 98 });
@@ -30,7 +30,7 @@ import { @@ -30,7 +30,7 @@ import {
30 import { Store } from '@ngrx/store'; 30 import { Store } from '@ngrx/store';
31 import { AppState } from '@app/core/core.state'; 31 import { AppState } from '@app/core/core.state';
32 import { coerceBooleanProperty } from '@angular/cdk/coercion'; 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 import { guid } from '@core/utils'; 34 import { guid } from '@core/utils';
35 import { Subscription } from 'rxjs'; 35 import { Subscription } from 'rxjs';
36 import { MatDialog } from '@angular/material/dialog'; 36 import { MatDialog } from '@angular/material/dialog';
@@ -141,7 +141,7 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni @@ -141,7 +141,7 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni
141 id: guid(), 141 id: guid(),
142 alarmType: '', 142 alarmType: '',
143 createRules: { 143 createRules: {
144 - empty: { 144 + CRITICAL: {
145 condition: { 145 condition: {
146 condition: [] 146 condition: []
147 } 147 }
@@ -149,8 +149,11 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni @@ -149,8 +149,11 @@ export class DeviceProfileAlarmsComponent implements ControlValueAccessor, OnIni
149 } 149 }
150 }; 150 };
151 const alarmsArray = this.deviceProfileAlarmsFormGroup.get('alarms') as FormArray; 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 this.deviceProfileAlarmsFormGroup.updateValueAndValidity(); 153 this.deviceProfileAlarmsFormGroup.updateValueAndValidity();
  154 + if (!this.deviceProfileAlarmsFormGroup.valid) {
  155 + this.updateModel();
  156 + }
154 } 157 }
155 158
156 public validate(c: FormControl) { 159 public validate(c: FormControl) {
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 limitations under the License. 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 <mat-toolbar color="primary"> 19 <mat-toolbar color="primary">
20 <h2>{{ (isAdd ? 'device-profile.add' : 'device-profile.edit' ) | translate }}</h2> 20 <h2>{{ (isAdd ? 'device-profile.add' : 'device-profile.edit' ) | translate }}</h2>
21 <span fxFlex></span> 21 <span fxFlex></span>
@@ -37,11 +37,6 @@ @@ -37,11 +37,6 @@
37 </tb-device-profile> 37 </tb-device-profile>
38 </div> 38 </div>
39 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 40 <button mat-button color="primary"
46 type="button" 41 type="button"
47 cdkFocusInitial 42 cdkFocusInitial
@@ -49,5 +44,10 @@ @@ -49,5 +44,10 @@
49 (click)="cancel()"> 44 (click)="cancel()">
50 {{ 'action.cancel' | translate }} 45 {{ 'action.cancel' | translate }}
51 </button> 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 </div> 52 </div>
53 </form> 53 </form>
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 </div> 41 </div>
42 <div class="mat-padding" fxLayout="column"> 42 <div class="mat-padding" fxLayout="column">
43 <form [formGroup]="entityForm"> 43 <form [formGroup]="entityForm">
44 - <fieldset [disabled]="(isLoading$ | async) || !isEdit"> 44 + <fieldset [disabled]="(isLoading$ | async) || !isEdit" style="min-width: 0;">
45 <mat-form-field class="mat-block"> 45 <mat-form-field class="mat-block">
46 <mat-label translate>device-profile.name</mat-label> 46 <mat-label translate>device-profile.name</mat-label>
47 <input matInput formControlName="name" required/> 47 <input matInput formControlName="name" required/>
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 limitations under the License. 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 <mat-toolbar color="primary"> 19 <mat-toolbar color="primary">
20 <h2>{{ (isAdd ? 'tenant-profile.add' : 'tenant-profile.edit' ) | translate }}</h2> 20 <h2>{{ (isAdd ? 'tenant-profile.add' : 'tenant-profile.edit' ) | translate }}</h2>
21 <span fxFlex></span> 21 <span fxFlex></span>
@@ -37,11 +37,6 @@ @@ -37,11 +37,6 @@
37 </tb-tenant-profile> 37 </tb-tenant-profile>
38 </div> 38 </div>
39 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 40 <button mat-button color="primary"
46 type="button" 41 type="button"
47 cdkFocusInitial 42 cdkFocusInitial
@@ -49,5 +44,10 @@ @@ -49,5 +44,10 @@
49 (click)="cancel()"> 44 (click)="cancel()">
50 {{ 'action.cancel' | translate }} 45 {{ 'action.cancel' | translate }}
51 </button> 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 </div> 52 </div>
53 </form> 53 </form>
@@ -53,17 +53,16 @@ @@ -53,17 +53,16 @@
53 </div> 53 </div>
54 <div mat-dialog-actions fxLayout="row"> 54 <div mat-dialog-actions fxLayout="row">
55 <span fxFlex></span> 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 <button mat-button color="primary" 56 <button mat-button color="primary"
62 - style="margin-right: 20px;"  
63 type="button" 57 type="button"
64 [disabled]="(isLoading$ | async)" 58 [disabled]="(isLoading$ | async)"
65 (click)="cancel()" cdkFocusInitial> 59 (click)="cancel()" cdkFocusInitial>
66 {{ 'action.cancel' | translate }} 60 {{ 'action.cancel' | translate }}
67 </button> 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 </div> 67 </div>
69 </form> 68 </form>
@@ -147,16 +147,16 @@ @@ -147,16 +147,16 @@
147 </fieldset> 147 </fieldset>
148 </div> 148 </div>
149 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 150 <button mat-button color="primary"
156 type="button" 151 type="button"
157 [disabled]="(isLoading$ | async)" 152 [disabled]="(isLoading$ | async)"
158 (click)="cancel()" cdkFocusInitial> 153 (click)="cancel()" cdkFocusInitial>
159 {{ 'action.cancel' | translate }} 154 {{ 'action.cancel' | translate }}
160 </button> 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 </div> 161 </div>
162 </form> 162 </form>
@@ -38,16 +38,16 @@ @@ -38,16 +38,16 @@
38 </tb-data-key-config> 38 </tb-data-key-config>
39 </div> 39 </div>
40 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 41 <button mat-button color="primary"
47 type="button" 42 type="button"
48 [disabled]="(isLoading$ | async)" 43 [disabled]="(isLoading$ | async)"
49 (click)="cancel()" cdkFocusInitial> 44 (click)="cancel()" cdkFocusInitial>
50 {{ 'action.cancel' | translate }} 45 {{ 'action.cancel' | translate }}
51 </button> 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 </div> 52 </div>
53 </form> 53 </form>
@@ -50,17 +50,16 @@ @@ -50,17 +50,16 @@
50 </mat-chip-list> 50 </mat-chip-list>
51 </mat-form-field> 51 </mat-form-field>
52 <div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center"> 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 <button type="submit" 58 <button type="submit"
54 mat-raised-button 59 mat-raised-button
55 color="primary" 60 color="primary"
56 [disabled]="alarmFilterFormGroup.invalid || !alarmFilterFormGroup.dirty"> 61 [disabled]="alarmFilterFormGroup.invalid || !alarmFilterFormGroup.dirty">
57 {{ 'action.update' | translate }} 62 {{ 'action.update' | translate }}
58 </button> 63 </button>
59 - <button type="button"  
60 - mat-button  
61 - (click)="cancel()"  
62 - style="margin-right: 20px;">  
63 - {{ 'action.cancel' | translate }}  
64 - </button>  
65 </div> 64 </div>
66 </form> 65 </form>
@@ -28,7 +28,6 @@ @@ -28,7 +28,6 @@
28 <div class="tb-panel-actions" fxLayout="row" *ngIf="!settings.autoConfirm"> 28 <div class="tb-panel-actions" fxLayout="row" *ngIf="!settings.autoConfirm">
29 <span fxFlex></span> 29 <span fxFlex></span>
30 <button mat-button mat-raised-button color="primary" 30 <button mat-button mat-raised-button color="primary"
31 - style="margin-right: 20px;"  
32 type="button" (click)="apply()"> 31 type="button" (click)="apply()">
33 {{ 'action.ok' | translate }} 32 {{ 'action.ok' | translate }}
34 </button> 33 </button>
@@ -40,17 +40,17 @@ @@ -40,17 +40,17 @@
40 </fieldset> 40 </fieldset>
41 </div> 41 </div>
42 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 43 <button mat-button color="primary"
50 type="button" 44 type="button"
51 [disabled]="(isLoading$ | async)" 45 [disabled]="(isLoading$ | async)"
52 (click)="cancel()" cdkFocusInitial> 46 (click)="cancel()" cdkFocusInitial>
53 {{ 'action.cancel' | translate }} 47 {{ 'action.cancel' | translate }}
54 </button> 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 </div> 55 </div>
56 </form> 56 </form>
@@ -39,17 +39,17 @@ @@ -39,17 +39,17 @@
39 </fieldset> 39 </fieldset>
40 </div> 40 </div>
41 <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> 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 <button mat-button color="primary" 42 <button mat-button color="primary"
49 type="button" 43 type="button"
50 [disabled]="(isLoading$ | async)" 44 [disabled]="(isLoading$ | async)"
51 (click)="cancel()" cdkFocusInitial> 45 (click)="cancel()" cdkFocusInitial>
52 {{ 'action.cancel' | translate }} 46 {{ 'action.cancel' | translate }}
53 </button> 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 </div> 54 </div>
55 </form> 55 </form>
@@ -41,11 +41,6 @@ @@ -41,11 +41,6 @@
41 </fieldset> 41 </fieldset>
42 </div> 42 </div>
43 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 44 <button mat-button color="primary"
50 type="button" 45 type="button"
51 [disabled]="(isLoading$ | async)" 46 [disabled]="(isLoading$ | async)"
@@ -53,5 +48,10 @@ @@ -53,5 +48,10 @@
53 cdkFocusInitial> 48 cdkFocusInitial>
54 {{ 'action.cancel' | translate }} 49 {{ 'action.cancel' | translate }}
55 </button> 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 </div> 56 </div>
57 </form> 57 </form>
@@ -152,17 +152,17 @@ @@ -152,17 +152,17 @@
152 </fieldset> 152 </fieldset>
153 </div> 153 </div>
154 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 155 <button mat-button color="primary"
162 type="button" 156 type="button"
163 [disabled]="(isLoading$ | async)" 157 [disabled]="(isLoading$ | async)"
164 (click)="cancel()" cdkFocusInitial> 158 (click)="cancel()" cdkFocusInitial>
165 {{ 'action.cancel' | translate }} 159 {{ 'action.cancel' | translate }}
166 </button> 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 </div> 167 </div>
168 </form> 168 </form>
@@ -54,11 +54,6 @@ @@ -54,11 +54,6 @@
54 </fieldset> 54 </fieldset>
55 </div> 55 </div>
56 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button 57 <button mat-button
63 color="primary" 58 color="primary"
64 type="button" 59 type="button"
@@ -66,5 +61,10 @@ @@ -66,5 +61,10 @@
66 (click)="cancel()" cdkFocusInitial> 61 (click)="cancel()" cdkFocusInitial>
67 {{ 'action.cancel' | translate }} 62 {{ 'action.cancel' | translate }}
68 </button> 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 </div> 69 </div>
70 </form> 70 </form>
@@ -54,7 +54,6 @@ @@ -54,7 +54,6 @@
54 <div mat-dialog-actions fxLayout="row"> 54 <div mat-dialog-actions fxLayout="row">
55 <span fxFlex></span> 55 <span fxFlex></span>
56 <button mat-button color="primary" 56 <button mat-button color="primary"
57 - style="margin-right: 20px;"  
58 type="button" 57 type="button"
59 [disabled]="(isLoading$ | async)" 58 [disabled]="(isLoading$ | async)"
60 (click)="close()" cdkFocusInitial> 59 (click)="close()" cdkFocusInitial>
@@ -41,18 +41,17 @@ @@ -41,18 +41,17 @@
41 </div> 41 </div>
42 <div mat-dialog-actions fxLayout="row"> 42 <div mat-dialog-actions fxLayout="row">
43 <span fxFlex></span> 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 <button mat-button color="primary" 44 <button mat-button color="primary"
51 - style="margin-right: 20px;"  
52 type="button" 45 type="button"
53 [disabled]="(isLoading$ | async)" 46 [disabled]="(isLoading$ | async)"
54 (click)="cancel()" cdkFocusInitial> 47 (click)="cancel()" cdkFocusInitial>
55 {{ 'action.cancel' | translate }} 48 {{ 'action.cancel' | translate }}
56 </button> 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 </div> 56 </div>
58 </form> 57 </form>
@@ -52,16 +52,16 @@ @@ -52,16 +52,16 @@
52 </fieldset> 52 </fieldset>
53 </div> 53 </div>
54 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 55 <button mat-button color="primary"
61 type="button" 56 type="button"
62 [disabled]="(isLoading$ | async)" 57 [disabled]="(isLoading$ | async)"
63 (click)="cancel()" cdkFocusInitial> 58 (click)="cancel()" cdkFocusInitial>
64 {{ 'action.cancel' | translate }} 59 {{ 'action.cancel' | translate }}
65 </button> 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 </div> 66 </div>
67 </form> 67 </form>
@@ -136,16 +136,16 @@ @@ -136,16 +136,16 @@
136 </fieldset> 136 </fieldset>
137 </div> 137 </div>
138 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 139 <button mat-button color="primary"
145 type="button" 140 type="button"
146 [disabled]="(isLoading$ | async)" 141 [disabled]="(isLoading$ | async)"
147 (click)="cancel()" cdkFocusInitial> 142 (click)="cancel()" cdkFocusInitial>
148 {{ 'action.cancel' | translate }} 143 {{ 'action.cancel' | translate }}
149 </button> 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 </div> 150 </div>
151 </form> 151 </form>
@@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
70 </div> 70 </div>
71 </div> 71 </div>
72 </mat-tab> 72 </mat-tab>
73 -<mat-tab *ngIf="entity" 73 +<mat-tab *ngIf="entity && !isEdit"
74 label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab"> 74 label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
75 <tb-audit-log-table detailsMode="true" [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id"></tb-audit-log-table> 75 <tb-audit-log-table detailsMode="true" [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id"></tb-audit-log-table>
76 </mat-tab> 76 </mat-tab>
@@ -36,17 +36,17 @@ @@ -36,17 +36,17 @@
36 </fieldset> 36 </fieldset>
37 </div> 37 </div>
38 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 39 <button mat-button color="primary"
46 type="button" 40 type="button"
47 [disabled]="(isLoading$ | async)" 41 [disabled]="(isLoading$ | async)"
48 (click)="cancel()" cdkFocusInitial> 42 (click)="cancel()" cdkFocusInitial>
49 {{ (isReadOnly ? 'action.close' : 'action.cancel') | translate }} 43 {{ (isReadOnly ? 'action.close' : 'action.cancel') | translate }}
50 </button> 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 </div> 51 </div>
52 </form> 52 </form>
@@ -46,16 +46,16 @@ @@ -46,16 +46,16 @@
46 </mat-form-field> 46 </mat-form-field>
47 </div> 47 </div>
48 <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> 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 <button mat-button color="primary" 49 <button mat-button color="primary"
55 type="button" 50 type="button"
56 [disabled]="(isLoading$ | async)" 51 [disabled]="(isLoading$ | async)"
57 [mat-dialog-close]="false" cdkFocusInitial> 52 [mat-dialog-close]="false" cdkFocusInitial>
58 {{ 'action.cancel' | translate }} 53 {{ 'action.cancel' | translate }}
59 </button> 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 </div> 60 </div>
61 </form> 61 </form>
@@ -40,16 +40,16 @@ @@ -40,16 +40,16 @@
40 </fieldset> 40 </fieldset>
41 </div> 41 </div>
42 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 43 <button mat-button color="primary"
49 type="button" 44 type="button"
50 [disabled]="(isLoading$ | async)" 45 [disabled]="(isLoading$ | async)"
51 (click)="cancel()" cdkFocusInitial> 46 (click)="cancel()" cdkFocusInitial>
52 {{ 'action.cancel' | translate }} 47 {{ 'action.cancel' | translate }}
53 </button> 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 </div> 54 </div>
55 </form> 55 </form>
@@ -39,16 +39,16 @@ @@ -39,16 +39,16 @@
39 </fieldset> 39 </fieldset>
40 </div> 40 </div>
41 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 42 <button mat-button color="primary"
48 type="button" 43 type="button"
49 [disabled]="(isLoading$ | async)" 44 [disabled]="(isLoading$ | async)"
50 (click)="cancel()" cdkFocusInitial> 45 (click)="cancel()" cdkFocusInitial>
51 {{ 'action.cancel' | translate }} 46 {{ 'action.cancel' | translate }}
52 </button> 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 </div> 53 </div>
54 </form> 54 </form>
@@ -41,11 +41,6 @@ @@ -41,11 +41,6 @@
41 </mat-form-field> 41 </mat-form-field>
42 </div> 42 </div>
43 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 44 <button mat-button color="primary"
50 type="button" 45 type="button"
51 cdkFocusInitial 46 cdkFocusInitial
@@ -53,5 +48,10 @@ @@ -53,5 +48,10 @@
53 (click)="cancel()"> 48 (click)="cancel()">
54 {{ 'action.cancel' | translate }} 49 {{ 'action.cancel' | translate }}
55 </button> 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 </div> 56 </div>
57 </form> 57 </form>
@@ -46,17 +46,17 @@ @@ -46,17 +46,17 @@
46 </fieldset> 46 </fieldset>
47 </div> 47 </div>
48 <div mat-dialog-actions fxLayoutAlign="end center"> 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 <button mat-button color="primary" 49 <button mat-button color="primary"
56 type="button" 50 type="button"
57 [disabled]="(isLoading$ | async)" 51 [disabled]="(isLoading$ | async)"
58 (click)="cancel()" cdkFocusInitial> 52 (click)="cancel()" cdkFocusInitial>
59 {{ 'action.cancel' | translate }} 53 {{ 'action.cancel' | translate }}
60 </button> 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 </div> 61 </div>
62 </form> 62 </form>
@@ -34,7 +34,6 @@ @@ -34,7 +34,6 @@
34 </button> 34 </button>
35 <button mat-button 35 <button mat-button
36 type="submit" 36 type="submit"
37 - style="margin-right: 20px;"  
38 [disabled]="(isLoading$ | async) || colorPickerFormGroup.invalid || !colorPickerFormGroup.dirty"> 37 [disabled]="(isLoading$ | async) || colorPickerFormGroup.invalid || !colorPickerFormGroup.dirty">
39 {{ 'action.select' | translate }} 38 {{ 'action.select' | translate }}
40 </button> 39 </button>
@@ -41,17 +41,16 @@ @@ -41,17 +41,16 @@
41 </div> 41 </div>
42 <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> 42 <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center">
43 <span fxFlex></span> 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 <button mat-button color="primary" 44 <button mat-button color="primary"
50 - style="margin-right: 20px;"  
51 type="button" 45 type="button"
52 [disabled]="(isLoading$ | async)" 46 [disabled]="(isLoading$ | async)"
53 (click)="cancel()" cdkFocusInitial> 47 (click)="cancel()" cdkFocusInitial>
54 {{ 'action.cancel' | translate }} 48 {{ 'action.cancel' | translate }}
55 </button> 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 </div> 55 </div>
57 </form> 56 </form>
@@ -109,18 +109,17 @@ @@ -109,18 +109,17 @@
109 {{ 'rulenode.test' | translate }} 109 {{ 'rulenode.test' | translate }}
110 </button> 110 </button>
111 <span fxFlex></span> 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 <button mat-button color="primary" 112 <button mat-button color="primary"
118 - style="margin-right: 20px;"  
119 type="button" 113 type="button"
120 cdkFocusInitial 114 cdkFocusInitial
121 [disabled]="(isLoading$ | async)" 115 [disabled]="(isLoading$ | async)"
122 (click)="cancel()"> 116 (click)="cancel()">
123 {{ 'action.cancel' | translate }} 117 {{ 'action.cancel' | translate }}
124 </button> 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 </div> 124 </div>
126 </form> 125 </form>
@@ -140,19 +140,18 @@ @@ -140,19 +140,18 @@
140 </tb-timeinterval> 140 </tb-timeinterval>
141 </div> 141 </div>
142 <div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center"> 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 <button type="submit" 149 <button type="submit"
144 mat-raised-button 150 mat-raised-button
145 color="primary" 151 color="primary"
146 [disabled]="(isLoading$ | async) || timewindowForm.invalid || !timewindowForm.dirty"> 152 [disabled]="(isLoading$ | async) || timewindowForm.invalid || !timewindowForm.dirty">
147 {{ 'action.update' | translate }} 153 {{ 'action.update' | translate }}
148 </button> 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 </div> 155 </div>
157 </div> 156 </div>
158 </fieldset> 157 </fieldset>
@@ -26,7 +26,7 @@ import { EntityInfoData } from '@shared/models/entity.models'; @@ -26,7 +26,7 @@ import { EntityInfoData } from '@shared/models/entity.models';
26 import { KeyFilter } from '@shared/models/query/query.models'; 26 import { KeyFilter } from '@shared/models/query/query.models';
27 import { TimeUnit } from '@shared/models/time/time.models'; 27 import { TimeUnit } from '@shared/models/time/time.models';
28 import * as _moment from 'moment-timezone'; 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 export enum DeviceProfileType { 31 export enum DeviceProfileType {
32 DEFAULT = 'DEFAULT' 32 DEFAULT = 'DEFAULT'
@@ -87,7 +87,7 @@ export const deviceProvisionTypeTranslationMap = new Map<DeviceProvisionType, st @@ -87,7 +87,7 @@ export const deviceProvisionTypeTranslationMap = new Map<DeviceProvisionType, st
87 [DeviceProvisionType.ALLOW_CREATE_NEW_DEVICES, 'device-profile.provision-strategy-created-new'], 87 [DeviceProvisionType.ALLOW_CREATE_NEW_DEVICES, 'device-profile.provision-strategy-created-new'],
88 [DeviceProvisionType.CHECK_PRE_PROVISIONED_DEVICES, 'device-profile.provision-strategy-check-pre-provisioned'] 88 [DeviceProvisionType.CHECK_PRE_PROVISIONED_DEVICES, 'device-profile.provision-strategy-check-pre-provisioned']
89 ] 89 ]
90 -) 90 +);
91 91
92 export const deviceTransportTypeHintMap = new Map<DeviceTransportType, string>( 92 export const deviceTransportTypeHintMap = new Map<DeviceTransportType, string>(
93 [ 93 [
@@ -303,6 +303,18 @@ export interface AlarmRule { @@ -303,6 +303,18 @@ export interface AlarmRule {
303 schedule?: AlarmSchedule; 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 export interface DeviceProfileAlarm { 318 export interface DeviceProfileAlarm {
307 id: string; 319 id: string;
308 alarmType: string; 320 alarmType: string;
@@ -312,6 +324,34 @@ export interface DeviceProfileAlarm { @@ -312,6 +324,34 @@ export interface DeviceProfileAlarm {
312 propagateRelationTypes?: Array<string>; 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 export interface DeviceProfileData { 355 export interface DeviceProfileData {
316 configuration: DeviceProfileConfiguration; 356 configuration: DeviceProfileConfiguration;
317 transportConfiguration: DeviceProfileTransportConfiguration; 357 transportConfiguration: DeviceProfileTransportConfiguration;
@@ -908,6 +908,7 @@ @@ -908,6 +908,7 @@
908 "create-alarm-pattern": "Create <b>{{alarmType}}</b> alarm", 908 "create-alarm-pattern": "Create <b>{{alarmType}}</b> alarm",
909 "create-alarm-rules": "Create alarm rules", 909 "create-alarm-rules": "Create alarm rules",
910 "no-create-alarm-rules": "No create conditions configured", 910 "no-create-alarm-rules": "No create conditions configured",
  911 + "add-create-alarm-rule-prompt": "Please add create alarm rule",
911 "clear-alarm-rule": "Clear alarm rule", 912 "clear-alarm-rule": "Clear alarm rule",
912 "no-clear-alarm-rule": "No clear condition configured", 913 "no-clear-alarm-rule": "No clear condition configured",
913 "add-create-alarm-rule": "Add create condition", 914 "add-create-alarm-rule": "Add create condition",
@@ -331,6 +331,9 @@ pre.tb-highlight { @@ -331,6 +331,9 @@ pre.tb-highlight {
331 font-weight: 400; 331 font-weight: 400;
332 line-height: 18px; 332 line-height: 18px;
333 color: rgba(0, 0, 0, .38); 333 color: rgba(0, 0, 0, .38);
  334 + &.required {
  335 + color: rgb(221, 44, 0);
  336 + }
334 } 337 }
335 338
336 .tb-fullscreen { 339 .tb-fullscreen {