Commit 59b5f7352ef4ff9c5633ec193376bc85534a2912

Authored by Igor Kulikov
Committed by GitHub
2 parents 477d640e 903a8fdc

Merge pull request #4327 from vvlladd28/bug/validator/alarm-rule

UI: Fixed alarm rules validation in change keyType or valueType
... ... @@ -15,11 +15,21 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
19 28 import {
20 29 BooleanFilterPredicate,
21 30 BooleanOperation,
22   - booleanOperationTranslationMap, EntityKeyValueType,
  31 + booleanOperationTranslationMap,
  32 + EntityKeyValueType,
23 33 FilterPredicateType
24 34 } from '@shared/models/query/query.models';
25 35
... ... @@ -32,10 +42,15 @@ import {
32 42 provide: NG_VALUE_ACCESSOR,
33 43 useExisting: forwardRef(() => BooleanFilterPredicateComponent),
34 44 multi: true
  45 + },
  46 + {
  47 + provide: NG_VALIDATORS,
  48 + useExisting: forwardRef(() => BooleanFilterPredicateComponent),
  49 + multi: true
35 50 }
36 51 ]
37 52 })
38   -export class BooleanFilterPredicateComponent implements ControlValueAccessor, OnInit {
  53 +export class BooleanFilterPredicateComponent implements ControlValueAccessor, Validator, OnInit {
39 54
40 55 @Input() disabled: boolean;
41 56
... ... @@ -73,7 +88,7 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
73 88 registerOnTouched(fn: any): void {
74 89 }
75 90
76   - setDisabledState?(isDisabled: boolean): void {
  91 + setDisabledState(isDisabled: boolean): void {
77 92 this.disabled = isDisabled;
78 93 if (this.disabled) {
79 94 this.booleanFilterPredicateFormGroup.disable({emitEvent: false});
... ... @@ -82,17 +97,20 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
82 97 }
83 98 }
84 99
  100 + validate(): ValidationErrors | null {
  101 + return this.booleanFilterPredicateFormGroup ? null : {
  102 + booleanFilterPredicate: {valid: false}
  103 + };
  104 + }
  105 +
85 106 writeValue(predicate: BooleanFilterPredicate): void {
86 107 this.booleanFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
87 108 this.booleanFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
88 109 }
89 110
90 111 private updateModel() {
91   - let predicate: BooleanFilterPredicate = null;
92   - if (this.booleanFilterPredicateFormGroup.valid) {
93   - predicate = this.booleanFilterPredicateFormGroup.getRawValue();
94   - predicate.type = FilterPredicateType.BOOLEAN;
95   - }
  112 + const predicate: BooleanFilterPredicate = this.booleanFilterPredicateFormGroup.getRawValue();
  113 + predicate.type = FilterPredicateType.BOOLEAN;
96 114 this.propagateChange(predicate);
97 115 }
98 116
... ...
... ... @@ -16,11 +16,7 @@
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18 18 import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
19   -import {
20   - ComplexFilterPredicate,
21   - ComplexFilterPredicateInfo,
22   - EntityKeyValueType
23   -} from '@shared/models/query/query.models';
  19 +import { ComplexFilterPredicateInfo, EntityKeyValueType } from '@shared/models/query/query.models';
24 20 import { MatDialog } from '@angular/material/dialog';
25 21 import {
26 22 ComplexFilterPredicateDialogComponent,
... ... @@ -71,7 +67,7 @@ export class ComplexFilterPredicateComponent implements ControlValueAccessor, On
71 67 registerOnTouched(fn: any): void {
72 68 }
73 69
74   - setDisabledState?(isDisabled: boolean): void {
  70 + setDisabledState(isDisabled: boolean): void {
75 71 this.disabled = isDisabled;
76 72 }
77 73
... ...
... ... @@ -21,7 +21,10 @@ import {
21 21 FormArray,
22 22 FormBuilder,
23 23 FormGroup,
  24 + NG_VALIDATORS,
24 25 NG_VALUE_ACCESSOR,
  26 + ValidationErrors,
  27 + Validator,
25 28 Validators
26 29 } from '@angular/forms';
27 30 import { Observable, of, Subscription } from 'rxjs';
... ... @@ -49,10 +52,15 @@ import { map } from 'rxjs/operators';
49 52 provide: NG_VALUE_ACCESSOR,
50 53 useExisting: forwardRef(() => FilterPredicateListComponent),
51 54 multi: true
  55 + },
  56 + {
  57 + provide: NG_VALIDATORS,
  58 + useExisting: forwardRef(() => FilterPredicateListComponent),
  59 + multi: true
52 60 }
53 61 ]
54 62 })
55   -export class FilterPredicateListComponent implements ControlValueAccessor, OnInit {
  63 +export class FilterPredicateListComponent implements ControlValueAccessor, Validator, OnInit {
56 64
57 65 @Input() disabled: boolean;
58 66
... ... @@ -108,6 +116,12 @@ export class FilterPredicateListComponent implements ControlValueAccessor, OnIni
108 116 }
109 117 }
110 118
  119 + validate(control: AbstractControl): ValidationErrors | null {
  120 + return this.filterListFormGroup.valid ? null : {
  121 + filterList: {valid: false}
  122 + };
  123 + }
  124 +
111 125 writeValue(predicates: Array<KeyFilterPredicateInfo>): void {
112 126 if (this.valueChangeSubscription) {
113 127 this.valueChangeSubscription.unsubscribe();
... ... @@ -178,7 +192,7 @@ export class FilterPredicateListComponent implements ControlValueAccessor, OnIni
178 192
179 193 private updateModel() {
180 194 const predicates: Array<KeyFilterPredicateInfo> = this.filterListFormGroup.getRawValue().predicates;
181   - if (this.filterListFormGroup.valid && predicates.length) {
  195 + if (predicates.length) {
182 196 this.propagateChange(predicates);
183 197 } else {
184 198 this.propagateChange(null);
... ...
... ... @@ -19,7 +19,10 @@ import {
19 19 ControlValueAccessor,
20 20 FormBuilder,
21 21 FormGroup,
  22 + NG_VALIDATORS,
22 23 NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
23 26 ValidatorFn,
24 27 Validators
25 28 } from '@angular/forms';
... ... @@ -39,10 +42,15 @@ import {
39 42 provide: NG_VALUE_ACCESSOR,
40 43 useExisting: forwardRef(() => FilterPredicateValueComponent),
41 44 multi: true
  45 + },
  46 + {
  47 + provide: NG_VALIDATORS,
  48 + useExisting: forwardRef(() => FilterPredicateValueComponent),
  49 + multi: true
42 50 }
43 51 ]
44 52 })
45   -export class FilterPredicateValueComponent implements ControlValueAccessor, OnInit {
  53 +export class FilterPredicateValueComponent implements ControlValueAccessor, Validator, OnInit {
46 54
47 55 private readonly inheritModeForSources: DynamicValueSourceType[] = [
48 56 DynamicValueSourceType.CURRENT_CUSTOMER,
... ... @@ -62,7 +70,22 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
62 70 }
63 71 }
64 72
65   - @Input() onlyUserDynamicSource = false;
  73 + private onlyUserDynamicSourceValue = false;
  74 +
  75 + @Input()
  76 + set onlyUserDynamicSource(dynamicMode: boolean) {
  77 + this.onlyUserDynamicSourceValue = dynamicMode;
  78 + if (this.filterPredicateValueFormGroup) {
  79 + this.updateValidationDynamicMode();
  80 + setTimeout(() => {
  81 + this.updateModel();
  82 + }, 0);
  83 + }
  84 + }
  85 +
  86 + get onlyUserDynamicSource(): boolean {
  87 + return this.onlyUserDynamicSourceValue;
  88 + }
66 89
67 90 @Input()
68 91 valueType: EntityKeyValueType;
... ... @@ -83,6 +106,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
83 106 allow = true;
84 107
85 108 private propagateChange = null;
  109 + private propagateChangePending = false;
86 110
87 111 constructor(private fb: FormBuilder) {
88 112 }
... ... @@ -126,6 +150,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
126 150 this.updateShowInheritMode(sourceType);
127 151 }
128 152 );
  153 + this.updateValidationDynamicMode();
129 154 this.filterPredicateValueFormGroup.valueChanges.subscribe(() => {
130 155 this.updateModel();
131 156 });
... ... @@ -133,12 +158,18 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
133 158
134 159 registerOnChange(fn: any): void {
135 160 this.propagateChange = fn;
  161 + if (this.propagateChangePending) {
  162 + this.propagateChangePending = false;
  163 + setTimeout(() => {
  164 + this.updateModel();
  165 + }, 0);
  166 + }
136 167 }
137 168
138 169 registerOnTouched(fn: any): void {
139 170 }
140 171
141   - setDisabledState?(isDisabled: boolean): void {
  172 + setDisabledState(isDisabled: boolean): void {
142 173 this.disabled = isDisabled;
143 174 if (this.disabled) {
144 175 this.filterPredicateValueFormGroup.disable({emitEvent: false});
... ... @@ -147,28 +178,35 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
147 178 }
148 179 }
149 180
  181 + validate(): ValidationErrors | null {
  182 + return this.filterPredicateValueFormGroup.valid ? null : {
  183 + filterPredicateValue: {valid: false}
  184 + };
  185 + }
  186 +
150 187 writeValue(predicateValue: FilterPredicateValue<string | number | boolean>): void {
  188 + this.propagateChangePending = false;
151 189 this.filterPredicateValueFormGroup.get('defaultValue').patchValue(predicateValue.defaultValue, {emitEvent: false});
152   - this.filterPredicateValueFormGroup.get('dynamicValue.sourceType').patchValue(predicateValue.dynamicValue ?
153   - predicateValue.dynamicValue.sourceType : null, {emitEvent: false});
154   - this.filterPredicateValueFormGroup.get('dynamicValue.sourceAttribute').patchValue(predicateValue.dynamicValue ?
155   - predicateValue.dynamicValue.sourceAttribute : null, {emitEvent: false});
156   - this.filterPredicateValueFormGroup.get('dynamicValue.inherit').patchValue(predicateValue.dynamicValue ?
157   - predicateValue.dynamicValue.inherit : false, {emitEvent: false});
  190 + this.filterPredicateValueFormGroup.get('dynamicValue').patchValue({
  191 + sourceType: predicateValue.dynamicValue ? predicateValue.dynamicValue.sourceType : null,
  192 + sourceAttribute: predicateValue.dynamicValue ? predicateValue.dynamicValue.sourceAttribute : null,
  193 + inherit: predicateValue.dynamicValue ? predicateValue.dynamicValue.inherit : false
  194 + }, {emitEvent: this.onlyUserDynamicSource});
158 195 this.updateShowInheritMode(predicateValue?.dynamicValue?.sourceType);
159 196 }
160 197
161 198 private updateModel() {
162   - let predicateValue: FilterPredicateValue<string | number | boolean> = null;
163   - if (this.filterPredicateValueFormGroup.valid) {
164   - predicateValue = this.filterPredicateValueFormGroup.getRawValue();
165   - if (predicateValue.dynamicValue) {
166   - if (!predicateValue.dynamicValue.sourceType || !predicateValue.dynamicValue.sourceAttribute) {
167   - predicateValue.dynamicValue = null;
168   - }
  199 + const predicateValue: FilterPredicateValue<string | number | boolean> = this.filterPredicateValueFormGroup.getRawValue();
  200 + if (predicateValue.dynamicValue) {
  201 + if (!predicateValue.dynamicValue.sourceType || !predicateValue.dynamicValue.sourceAttribute) {
  202 + predicateValue.dynamicValue = null;
169 203 }
170 204 }
171   - this.propagateChange(predicateValue);
  205 + if (this.propagateChange) {
  206 + this.propagateChange(predicateValue);
  207 + } else {
  208 + this.propagateChangePending = true;
  209 + }
172 210 }
173 211
174 212 private updateShowInheritMode(sourceType: DynamicValueSourceType) {
... ... @@ -179,4 +217,16 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
179 217 this.inheritMode = false;
180 218 }
181 219 }
  220 +
  221 + private updateValidationDynamicMode() {
  222 + if (this.onlyUserDynamicSource) {
  223 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceType').setValidators(Validators.required);
  224 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceAttribute').setValidators(Validators.required);
  225 + } else {
  226 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceType').clearValidators();
  227 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceAttribute').clearValidators();
  228 + }
  229 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceType').updateValueAndValidity({emitEvent: false});
  230 + this.filterPredicateValueFormGroup.get('dynamicValue.sourceAttribute').updateValueAndValidity({emitEvent: false});
  231 + }
182 232 }
... ...
... ... @@ -15,11 +15,17 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
19 18 import {
20   - EntityKeyValueType,
21   - FilterPredicateType, KeyFilterPredicate, KeyFilterPredicateInfo
22   -} from '@shared/models/query/query.models';
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
  28 +import { EntityKeyValueType, FilterPredicateType, KeyFilterPredicateInfo } from '@shared/models/query/query.models';
23 29
24 30 @Component({
25 31 selector: 'tb-filter-predicate',
... ... @@ -30,10 +36,15 @@ import {
30 36 provide: NG_VALUE_ACCESSOR,
31 37 useExisting: forwardRef(() => FilterPredicateComponent),
32 38 multi: true
  39 + },
  40 + {
  41 + provide: NG_VALIDATORS,
  42 + useExisting: forwardRef(() => FilterPredicateComponent),
  43 + multi: true
33 44 }
34 45 ]
35 46 })
36   -export class FilterPredicateComponent implements ControlValueAccessor, OnInit {
  47 +export class FilterPredicateComponent implements ControlValueAccessor, Validator, OnInit {
37 48
38 49 @Input() disabled: boolean;
39 50
... ... @@ -75,7 +86,7 @@ export class FilterPredicateComponent implements ControlValueAccessor, OnInit {
75 86 registerOnTouched(fn: any): void {
76 87 }
77 88
78   - setDisabledState?(isDisabled: boolean): void {
  89 + setDisabledState(isDisabled: boolean): void {
79 90 this.disabled = isDisabled;
80 91 if (this.disabled) {
81 92 this.filterPredicateFormGroup.disable({emitEvent: false});
... ... @@ -84,6 +95,12 @@ export class FilterPredicateComponent implements ControlValueAccessor, OnInit {
84 95 }
85 96 }
86 97
  98 + validate(): ValidationErrors | null {
  99 + return this.filterPredicateFormGroup.valid ? null : {
  100 + filterPredicate: {valid: false}
  101 + };
  102 + }
  103 +
87 104 writeValue(predicate: KeyFilterPredicateInfo): void {
88 105 this.type = predicate.keyFilterPredicate.type;
89 106 this.filterPredicateFormGroup.get('predicate').patchValue(predicate.keyFilterPredicate, {emitEvent: false});
... ...
... ... @@ -22,7 +22,10 @@ import {
22 22 FormBuilder,
23 23 FormControl,
24 24 FormGroup,
  25 + NG_VALIDATORS,
25 26 NG_VALUE_ACCESSOR,
  27 + ValidationErrors,
  28 + Validator,
26 29 Validators
27 30 } from '@angular/forms';
28 31 import { Observable, Subscription } from 'rxjs';
... ... @@ -46,10 +49,15 @@ import { EntityId } from '@shared/models/id/entity-id';
46 49 provide: NG_VALUE_ACCESSOR,
47 50 useExisting: forwardRef(() => KeyFilterListComponent),
48 51 multi: true
  52 + },
  53 + {
  54 + provide: NG_VALIDATORS,
  55 + useExisting: forwardRef(() => KeyFilterListComponent),
  56 + multi: true
49 57 }
50 58 ]
51 59 })
52   -export class KeyFilterListComponent implements ControlValueAccessor, OnInit {
  60 +export class KeyFilterListComponent implements ControlValueAccessor, Validator, OnInit {
53 61
54 62 @Input() disabled: boolean;
55 63
... ... @@ -104,6 +112,12 @@ export class KeyFilterListComponent implements ControlValueAccessor, OnInit {
104 112 }
105 113 }
106 114
  115 + validate(): ValidationErrors | null {
  116 + return this.keyFilterListFormGroup.valid && this.keyFiltersControl.valid ? null : {
  117 + keyFilterList: {valid: false}
  118 + };
  119 + }
  120 +
107 121 writeValue(keyFilters: Array<KeyFilterInfo>): void {
108 122 if (this.valueChangeSubscription) {
109 123 this.valueChangeSubscription.unsubscribe();
... ...
... ... @@ -15,7 +15,16 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
19 28 import {
20 29 EntityKeyValueType,
21 30 FilterPredicateType,
... ... @@ -33,10 +42,15 @@ import {
33 42 provide: NG_VALUE_ACCESSOR,
34 43 useExisting: forwardRef(() => NumericFilterPredicateComponent),
35 44 multi: true
  45 + },
  46 + {
  47 + provide: NG_VALIDATORS,
  48 + useExisting: forwardRef(() => NumericFilterPredicateComponent),
  49 + multi: true
36 50 }
37 51 ]
38 52 })
39   -export class NumericFilterPredicateComponent implements ControlValueAccessor, OnInit {
  53 +export class NumericFilterPredicateComponent implements ControlValueAccessor, Validator, OnInit {
40 54
41 55 @Input() disabled: boolean;
42 56
... ... @@ -76,7 +90,7 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On
76 90 registerOnTouched(fn: any): void {
77 91 }
78 92
79   - setDisabledState?(isDisabled: boolean): void {
  93 + setDisabledState(isDisabled: boolean): void {
80 94 this.disabled = isDisabled;
81 95 if (this.disabled) {
82 96 this.numericFilterPredicateFormGroup.disable({emitEvent: false});
... ... @@ -85,17 +99,20 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On
85 99 }
86 100 }
87 101
  102 + validate(): ValidationErrors | null {
  103 + return this.numericFilterPredicateFormGroup.valid ? null : {
  104 + numericFilterPredicate: {valid: false}
  105 + };
  106 + }
  107 +
88 108 writeValue(predicate: NumericFilterPredicate): void {
89 109 this.numericFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
90 110 this.numericFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
91 111 }
92 112
93 113 private updateModel() {
94   - let predicate: NumericFilterPredicate = null;
95   - if (this.numericFilterPredicateFormGroup.valid) {
96   - predicate = this.numericFilterPredicateFormGroup.getRawValue();
97   - predicate.type = FilterPredicateType.NUMERIC;
98   - }
  114 + const predicate: NumericFilterPredicate = this.numericFilterPredicateFormGroup.getRawValue();
  115 + predicate.type = FilterPredicateType.NUMERIC;
99 116 this.propagateChange(predicate);
100 117 }
101 118
... ...
... ... @@ -15,7 +15,16 @@
15 15 ///
16 16
17 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18   -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormGroup,
  22 + NG_VALIDATORS,
  23 + NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
  26 + Validators
  27 +} from '@angular/forms';
19 28 import {
20 29 EntityKeyValueType,
21 30 FilterPredicateType,
... ... @@ -33,10 +42,15 @@ import {
33 42 provide: NG_VALUE_ACCESSOR,
34 43 useExisting: forwardRef(() => StringFilterPredicateComponent),
35 44 multi: true
  45 + },
  46 + {
  47 + provide: NG_VALIDATORS,
  48 + useExisting: forwardRef(() => StringFilterPredicateComponent),
  49 + multi: true
36 50 }
37 51 ]
38 52 })
39   -export class StringFilterPredicateComponent implements ControlValueAccessor, OnInit {
  53 +export class StringFilterPredicateComponent implements ControlValueAccessor, Validator, OnInit {
40 54
41 55 @Input() disabled: boolean;
42 56
... ... @@ -90,12 +104,15 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
90 104 this.stringFilterPredicateFormGroup.get('ignoreCase').patchValue(predicate.ignoreCase, {emitEvent: false});
91 105 }
92 106
  107 + validate(c): ValidationErrors {
  108 + return this.stringFilterPredicateFormGroup.valid ? null : {
  109 + stringFilterPredicate: {valid: false}
  110 + };
  111 + }
  112 +
93 113 private updateModel() {
94   - let predicate: StringFilterPredicate = null;
95   - if (this.stringFilterPredicateFormGroup.valid) {
96   - predicate = this.stringFilterPredicateFormGroup.getRawValue();
97   - predicate.type = FilterPredicateType.STRING;
98   - }
  114 + const predicate: StringFilterPredicate = this.stringFilterPredicateFormGroup.getRawValue();
  115 + predicate.type = FilterPredicateType.STRING;
99 116 this.propagateChange(predicate);
100 117 }
101 118
... ...