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,11 +15,21 @@
15 /// 15 ///
16 16
17 import { Component, forwardRef, Input, OnInit } from '@angular/core'; 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 import { 28 import {
20 BooleanFilterPredicate, 29 BooleanFilterPredicate,
21 BooleanOperation, 30 BooleanOperation,
22 - booleanOperationTranslationMap, EntityKeyValueType, 31 + booleanOperationTranslationMap,
  32 + EntityKeyValueType,
23 FilterPredicateType 33 FilterPredicateType
24 } from '@shared/models/query/query.models'; 34 } from '@shared/models/query/query.models';
25 35
@@ -32,10 +42,15 @@ import { @@ -32,10 +42,15 @@ import {
32 provide: NG_VALUE_ACCESSOR, 42 provide: NG_VALUE_ACCESSOR,
33 useExisting: forwardRef(() => BooleanFilterPredicateComponent), 43 useExisting: forwardRef(() => BooleanFilterPredicateComponent),
34 multi: true 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 @Input() disabled: boolean; 55 @Input() disabled: boolean;
41 56
@@ -73,7 +88,7 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On @@ -73,7 +88,7 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
73 registerOnTouched(fn: any): void { 88 registerOnTouched(fn: any): void {
74 } 89 }
75 90
76 - setDisabledState?(isDisabled: boolean): void { 91 + setDisabledState(isDisabled: boolean): void {
77 this.disabled = isDisabled; 92 this.disabled = isDisabled;
78 if (this.disabled) { 93 if (this.disabled) {
79 this.booleanFilterPredicateFormGroup.disable({emitEvent: false}); 94 this.booleanFilterPredicateFormGroup.disable({emitEvent: false});
@@ -82,17 +97,20 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On @@ -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 writeValue(predicate: BooleanFilterPredicate): void { 106 writeValue(predicate: BooleanFilterPredicate): void {
86 this.booleanFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false}); 107 this.booleanFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
87 this.booleanFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false}); 108 this.booleanFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
88 } 109 }
89 110
90 private updateModel() { 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 this.propagateChange(predicate); 114 this.propagateChange(predicate);
97 } 115 }
98 116
@@ -16,11 +16,7 @@ @@ -16,11 +16,7 @@
16 16
17 import { Component, forwardRef, Input, OnInit } from '@angular/core'; 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18 import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 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 import { MatDialog } from '@angular/material/dialog'; 20 import { MatDialog } from '@angular/material/dialog';
25 import { 21 import {
26 ComplexFilterPredicateDialogComponent, 22 ComplexFilterPredicateDialogComponent,
@@ -71,7 +67,7 @@ export class ComplexFilterPredicateComponent implements ControlValueAccessor, On @@ -71,7 +67,7 @@ export class ComplexFilterPredicateComponent implements ControlValueAccessor, On
71 registerOnTouched(fn: any): void { 67 registerOnTouched(fn: any): void {
72 } 68 }
73 69
74 - setDisabledState?(isDisabled: boolean): void { 70 + setDisabledState(isDisabled: boolean): void {
75 this.disabled = isDisabled; 71 this.disabled = isDisabled;
76 } 72 }
77 73
@@ -21,7 +21,10 @@ import { @@ -21,7 +21,10 @@ import {
21 FormArray, 21 FormArray,
22 FormBuilder, 22 FormBuilder,
23 FormGroup, 23 FormGroup,
  24 + NG_VALIDATORS,
24 NG_VALUE_ACCESSOR, 25 NG_VALUE_ACCESSOR,
  26 + ValidationErrors,
  27 + Validator,
25 Validators 28 Validators
26 } from '@angular/forms'; 29 } from '@angular/forms';
27 import { Observable, of, Subscription } from 'rxjs'; 30 import { Observable, of, Subscription } from 'rxjs';
@@ -49,10 +52,15 @@ import { map } from 'rxjs/operators'; @@ -49,10 +52,15 @@ import { map } from 'rxjs/operators';
49 provide: NG_VALUE_ACCESSOR, 52 provide: NG_VALUE_ACCESSOR,
50 useExisting: forwardRef(() => FilterPredicateListComponent), 53 useExisting: forwardRef(() => FilterPredicateListComponent),
51 multi: true 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 @Input() disabled: boolean; 65 @Input() disabled: boolean;
58 66
@@ -108,6 +116,12 @@ export class FilterPredicateListComponent implements ControlValueAccessor, OnIni @@ -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 writeValue(predicates: Array<KeyFilterPredicateInfo>): void { 125 writeValue(predicates: Array<KeyFilterPredicateInfo>): void {
112 if (this.valueChangeSubscription) { 126 if (this.valueChangeSubscription) {
113 this.valueChangeSubscription.unsubscribe(); 127 this.valueChangeSubscription.unsubscribe();
@@ -178,7 +192,7 @@ export class FilterPredicateListComponent implements ControlValueAccessor, OnIni @@ -178,7 +192,7 @@ export class FilterPredicateListComponent implements ControlValueAccessor, OnIni
178 192
179 private updateModel() { 193 private updateModel() {
180 const predicates: Array<KeyFilterPredicateInfo> = this.filterListFormGroup.getRawValue().predicates; 194 const predicates: Array<KeyFilterPredicateInfo> = this.filterListFormGroup.getRawValue().predicates;
181 - if (this.filterListFormGroup.valid && predicates.length) { 195 + if (predicates.length) {
182 this.propagateChange(predicates); 196 this.propagateChange(predicates);
183 } else { 197 } else {
184 this.propagateChange(null); 198 this.propagateChange(null);
@@ -19,7 +19,10 @@ import { @@ -19,7 +19,10 @@ import {
19 ControlValueAccessor, 19 ControlValueAccessor,
20 FormBuilder, 20 FormBuilder,
21 FormGroup, 21 FormGroup,
  22 + NG_VALIDATORS,
22 NG_VALUE_ACCESSOR, 23 NG_VALUE_ACCESSOR,
  24 + ValidationErrors,
  25 + Validator,
23 ValidatorFn, 26 ValidatorFn,
24 Validators 27 Validators
25 } from '@angular/forms'; 28 } from '@angular/forms';
@@ -39,10 +42,15 @@ import { @@ -39,10 +42,15 @@ import {
39 provide: NG_VALUE_ACCESSOR, 42 provide: NG_VALUE_ACCESSOR,
40 useExisting: forwardRef(() => FilterPredicateValueComponent), 43 useExisting: forwardRef(() => FilterPredicateValueComponent),
41 multi: true 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 private readonly inheritModeForSources: DynamicValueSourceType[] = [ 55 private readonly inheritModeForSources: DynamicValueSourceType[] = [
48 DynamicValueSourceType.CURRENT_CUSTOMER, 56 DynamicValueSourceType.CURRENT_CUSTOMER,
@@ -62,7 +70,22 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -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 @Input() 90 @Input()
68 valueType: EntityKeyValueType; 91 valueType: EntityKeyValueType;
@@ -83,6 +106,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -83,6 +106,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
83 allow = true; 106 allow = true;
84 107
85 private propagateChange = null; 108 private propagateChange = null;
  109 + private propagateChangePending = false;
86 110
87 constructor(private fb: FormBuilder) { 111 constructor(private fb: FormBuilder) {
88 } 112 }
@@ -126,6 +150,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -126,6 +150,7 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
126 this.updateShowInheritMode(sourceType); 150 this.updateShowInheritMode(sourceType);
127 } 151 }
128 ); 152 );
  153 + this.updateValidationDynamicMode();
129 this.filterPredicateValueFormGroup.valueChanges.subscribe(() => { 154 this.filterPredicateValueFormGroup.valueChanges.subscribe(() => {
130 this.updateModel(); 155 this.updateModel();
131 }); 156 });
@@ -133,12 +158,18 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -133,12 +158,18 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
133 158
134 registerOnChange(fn: any): void { 159 registerOnChange(fn: any): void {
135 this.propagateChange = fn; 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 registerOnTouched(fn: any): void { 169 registerOnTouched(fn: any): void {
139 } 170 }
140 171
141 - setDisabledState?(isDisabled: boolean): void { 172 + setDisabledState(isDisabled: boolean): void {
142 this.disabled = isDisabled; 173 this.disabled = isDisabled;
143 if (this.disabled) { 174 if (this.disabled) {
144 this.filterPredicateValueFormGroup.disable({emitEvent: false}); 175 this.filterPredicateValueFormGroup.disable({emitEvent: false});
@@ -147,28 +178,35 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -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 writeValue(predicateValue: FilterPredicateValue<string | number | boolean>): void { 187 writeValue(predicateValue: FilterPredicateValue<string | number | boolean>): void {
  188 + this.propagateChangePending = false;
151 this.filterPredicateValueFormGroup.get('defaultValue').patchValue(predicateValue.defaultValue, {emitEvent: false}); 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 this.updateShowInheritMode(predicateValue?.dynamicValue?.sourceType); 195 this.updateShowInheritMode(predicateValue?.dynamicValue?.sourceType);
159 } 196 }
160 197
161 private updateModel() { 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 private updateShowInheritMode(sourceType: DynamicValueSourceType) { 212 private updateShowInheritMode(sourceType: DynamicValueSourceType) {
@@ -179,4 +217,16 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn @@ -179,4 +217,16 @@ export class FilterPredicateValueComponent implements ControlValueAccessor, OnIn
179 this.inheritMode = false; 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,11 +15,17 @@
15 /// 15 ///
16 16
17 import { Component, forwardRef, Input, OnInit } from '@angular/core'; 17 import { Component, forwardRef, Input, OnInit } from '@angular/core';
18 -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';  
19 import { 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 @Component({ 30 @Component({
25 selector: 'tb-filter-predicate', 31 selector: 'tb-filter-predicate',
@@ -30,10 +36,15 @@ import { @@ -30,10 +36,15 @@ import {
30 provide: NG_VALUE_ACCESSOR, 36 provide: NG_VALUE_ACCESSOR,
31 useExisting: forwardRef(() => FilterPredicateComponent), 37 useExisting: forwardRef(() => FilterPredicateComponent),
32 multi: true 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 @Input() disabled: boolean; 49 @Input() disabled: boolean;
39 50
@@ -75,7 +86,7 @@ export class FilterPredicateComponent implements ControlValueAccessor, OnInit { @@ -75,7 +86,7 @@ export class FilterPredicateComponent implements ControlValueAccessor, OnInit {
75 registerOnTouched(fn: any): void { 86 registerOnTouched(fn: any): void {
76 } 87 }
77 88
78 - setDisabledState?(isDisabled: boolean): void { 89 + setDisabledState(isDisabled: boolean): void {
79 this.disabled = isDisabled; 90 this.disabled = isDisabled;
80 if (this.disabled) { 91 if (this.disabled) {
81 this.filterPredicateFormGroup.disable({emitEvent: false}); 92 this.filterPredicateFormGroup.disable({emitEvent: false});
@@ -84,6 +95,12 @@ export class FilterPredicateComponent implements ControlValueAccessor, OnInit { @@ -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 writeValue(predicate: KeyFilterPredicateInfo): void { 104 writeValue(predicate: KeyFilterPredicateInfo): void {
88 this.type = predicate.keyFilterPredicate.type; 105 this.type = predicate.keyFilterPredicate.type;
89 this.filterPredicateFormGroup.get('predicate').patchValue(predicate.keyFilterPredicate, {emitEvent: false}); 106 this.filterPredicateFormGroup.get('predicate').patchValue(predicate.keyFilterPredicate, {emitEvent: false});
@@ -22,7 +22,10 @@ import { @@ -22,7 +22,10 @@ import {
22 FormBuilder, 22 FormBuilder,
23 FormControl, 23 FormControl,
24 FormGroup, 24 FormGroup,
  25 + NG_VALIDATORS,
25 NG_VALUE_ACCESSOR, 26 NG_VALUE_ACCESSOR,
  27 + ValidationErrors,
  28 + Validator,
26 Validators 29 Validators
27 } from '@angular/forms'; 30 } from '@angular/forms';
28 import { Observable, Subscription } from 'rxjs'; 31 import { Observable, Subscription } from 'rxjs';
@@ -46,10 +49,15 @@ import { EntityId } from '@shared/models/id/entity-id'; @@ -46,10 +49,15 @@ import { EntityId } from '@shared/models/id/entity-id';
46 provide: NG_VALUE_ACCESSOR, 49 provide: NG_VALUE_ACCESSOR,
47 useExisting: forwardRef(() => KeyFilterListComponent), 50 useExisting: forwardRef(() => KeyFilterListComponent),
48 multi: true 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 @Input() disabled: boolean; 62 @Input() disabled: boolean;
55 63
@@ -104,6 +112,12 @@ export class KeyFilterListComponent implements ControlValueAccessor, OnInit { @@ -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 writeValue(keyFilters: Array<KeyFilterInfo>): void { 121 writeValue(keyFilters: Array<KeyFilterInfo>): void {
108 if (this.valueChangeSubscription) { 122 if (this.valueChangeSubscription) {
109 this.valueChangeSubscription.unsubscribe(); 123 this.valueChangeSubscription.unsubscribe();
@@ -15,7 +15,16 @@ @@ -15,7 +15,16 @@
15 /// 15 ///
16 16
17 import { Component, forwardRef, Input, OnInit } from '@angular/core'; 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 import { 28 import {
20 EntityKeyValueType, 29 EntityKeyValueType,
21 FilterPredicateType, 30 FilterPredicateType,
@@ -33,10 +42,15 @@ import { @@ -33,10 +42,15 @@ import {
33 provide: NG_VALUE_ACCESSOR, 42 provide: NG_VALUE_ACCESSOR,
34 useExisting: forwardRef(() => NumericFilterPredicateComponent), 43 useExisting: forwardRef(() => NumericFilterPredicateComponent),
35 multi: true 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 @Input() disabled: boolean; 55 @Input() disabled: boolean;
42 56
@@ -76,7 +90,7 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On @@ -76,7 +90,7 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On
76 registerOnTouched(fn: any): void { 90 registerOnTouched(fn: any): void {
77 } 91 }
78 92
79 - setDisabledState?(isDisabled: boolean): void { 93 + setDisabledState(isDisabled: boolean): void {
80 this.disabled = isDisabled; 94 this.disabled = isDisabled;
81 if (this.disabled) { 95 if (this.disabled) {
82 this.numericFilterPredicateFormGroup.disable({emitEvent: false}); 96 this.numericFilterPredicateFormGroup.disable({emitEvent: false});
@@ -85,17 +99,20 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On @@ -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 writeValue(predicate: NumericFilterPredicate): void { 108 writeValue(predicate: NumericFilterPredicate): void {
89 this.numericFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false}); 109 this.numericFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
90 this.numericFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false}); 110 this.numericFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
91 } 111 }
92 112
93 private updateModel() { 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 this.propagateChange(predicate); 116 this.propagateChange(predicate);
100 } 117 }
101 118
@@ -15,7 +15,16 @@ @@ -15,7 +15,16 @@
15 /// 15 ///
16 16
17 import { Component, forwardRef, Input, OnInit } from '@angular/core'; 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 import { 28 import {
20 EntityKeyValueType, 29 EntityKeyValueType,
21 FilterPredicateType, 30 FilterPredicateType,
@@ -33,10 +42,15 @@ import { @@ -33,10 +42,15 @@ import {
33 provide: NG_VALUE_ACCESSOR, 42 provide: NG_VALUE_ACCESSOR,
34 useExisting: forwardRef(() => StringFilterPredicateComponent), 43 useExisting: forwardRef(() => StringFilterPredicateComponent),
35 multi: true 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 @Input() disabled: boolean; 55 @Input() disabled: boolean;
42 56
@@ -90,12 +104,15 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI @@ -90,12 +104,15 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
90 this.stringFilterPredicateFormGroup.get('ignoreCase').patchValue(predicate.ignoreCase, {emitEvent: false}); 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 private updateModel() { 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 this.propagateChange(predicate); 116 this.propagateChange(predicate);
100 } 117 }
101 118