Skip to content

Commit

Permalink
UI: Fix data keys chips validation.
Browse files Browse the repository at this point in the history
  • Loading branch information
ikulikov committed Oct 10, 2023
1 parent 7699e49 commit 3ab6b0e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ import {
import {
AbstractControl,
ControlValueAccessor,
FormGroupDirective,
FormGroupDirective, NG_VALIDATORS,
NG_VALUE_ACCESSOR,
NgForm,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
ValidationErrors
ValidationErrors, Validator
} from '@angular/forms';
import { Observable, of } from 'rxjs';
import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators';
Expand All @@ -62,7 +62,7 @@ import {
DataKeyConfigDialogComponent,
DataKeyConfigDialogData
} from '@home/components/widget/config/data-key-config-dialog.component';
import { deepClone, guid, isDefinedAndNotNull, isUndefined } from '@core/utils';
import { deepClone, guid, isDefinedAndNotNull, isObject, isUndefined } from '@core/utils';
import { Dashboard } from '@shared/models/dashboard.models';
import { AggregationType } from '@shared/models/time/time.models';
import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive';
Expand All @@ -81,15 +81,20 @@ import { TbPopoverService } from '@shared/components/popover.service';
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DataKeysComponent),
multi: true
} /*,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DataKeysComponent),
multi: true,
},
{
provide: ErrorStateMatcher,
useExisting: DataKeysComponent
} */
}
],
encapsulation: ViewEncapsulation.None
})
export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher {
export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher, Validator {

public get hideDataKeyLabel(): boolean {
return this.datasourceComponent.hideDataKeyLabel;
Expand Down Expand Up @@ -205,6 +210,9 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange

private propagateChange = (v: any) => { };

private keysRequired = this._keysRequired.bind(this);
private keysValidator = this._keysValidator.bind(this);

constructor(private store: Store<AppState>,
@SkipSelf() private errorStateMatcher: ErrorStateMatcher,
private datasourceComponent: DatasourceComponent,
Expand All @@ -220,31 +228,53 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
}

updateValidators() {
this.keysListFormGroup.get('keys').setValidators(this.required ? [this.keysRequired] : []);
if (this.required) {
this.keysListFormGroup.get('keys').addValidators(this.keysRequired);
} else {
this.keysListFormGroup.get('keys').removeValidators(this.keysRequired);
}
this.keysListFormGroup.get('keys').updateValueAndValidity();
}

keysRequired(control: AbstractControl): ValidationErrors | null {
const value = control.value;
private _keysRequired(control: AbstractControl): ValidationErrors | null {
const value = this.modelValue;
if (value && Array.isArray(value) && value.length) {
return null;
} else {
return {required: true};
}
}

private _keysValidator(control: AbstractControl): ValidationErrors | null {
const value = this.modelValue;
if (value && Array.isArray(value)) {
if (value.some(v => isObject(v) && (!v.type || !v.name))) {
return {
dataKey: true
};
}
}
return null;
}

registerOnChange(fn: any): void {
this.propagateChange = fn;
if (!this.keysListFormGroup.valid) {
this.propagateChange(this.modelValue);
}
}

registerOnTouched(fn: any): void {
}

ngOnInit() {
this.keysListFormGroup = this.fb.group({
keys: [null, this.required ? [this.keysRequired] : []],
keys: [null, [this.keysValidator]],
key: [null]
});
if (this.required) {
this.keysListFormGroup.get('keys').addValidators(this.keysRequired);
}
this.alarmKeys = [];
for (const name of Object.keys(alarmFields)) {
this.alarmKeys.push({
Expand Down Expand Up @@ -335,8 +365,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
} else {
this.keys = [];
}
this.keysListFormGroup.get('keys').setValue(this.keys);
this.modelValue = this.keys.length ? [...this.keys] : null;
this.keysListFormGroup.get('keys').setValue(this.keys);
if (this.keyInput) {
this.keyInput.nativeElement.value = '';
}
Expand Down Expand Up @@ -374,7 +404,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange

isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
const customErrorState = this.required && (!this.modelValue || !this.modelValue.length);
const customErrorState = this.keysListFormGroup.get('keys').hasError('dataKey');
return originalErrorState || customErrorState;
}

Expand All @@ -395,12 +425,20 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
this.keysListFormGroup.get('keys').setValue(this.keys);
} else {
this.keys = [];
this.keysListFormGroup.get('keys').setValue(this.keys);
this.modelValue = null;
this.keysListFormGroup.get('keys').setValue(this.keys);
}
this.dirty = true;
}

validate(c: UntypedFormControl) {
return (this.keysListFormGroup.get('keys').hasError('dataKey')) ? {
dataKeys: {
valid: false,
},
} : null;
}

onFocus() {
if (this.dirty) {
this.keysListFormGroup.get('key').updateValueAndValidity({onlySelf: true, emitEvent: true});
Expand Down Expand Up @@ -441,8 +479,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
const index = this.keys.indexOf(key);
if (index >= 0) {
this.keys.splice(index, 1);
this.keysListFormGroup.get('keys').setValue(this.keys);
this.modelValue.splice(index, 1);
this.keysListFormGroup.get('keys').setValue(this.keys);
if (!this.modelValue.length) {
this.modelValue = null;
}
Expand All @@ -468,8 +506,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
index = this.keys.length;
}
moveItemInArray(this.keys, this.dragIndex, index);
this.keysListFormGroup.get('keys').setValue(this.keys);
moveItemInArray(this.modelValue, this.dragIndex, index);
this.keysListFormGroup.get('keys').setValue(this.keys);
this.dragIndex = -1;
this.propagateChange(this.modelValue);
}
Expand Down Expand Up @@ -525,8 +563,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
}).afterClosed().subscribe((updatedDataKey) => {
if (updatedDataKey) {
this.keys[index] = updatedDataKey;
this.keysListFormGroup.get('keys').setValue(this.keys);
this.modelValue[index] = updatedDataKey;
this.keysListFormGroup.get('keys').setValue(this.keys);
this.propagateChange(this.modelValue);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
this.basicModeComponentChangeSubscription = this.basicModeComponent.widgetConfigChanged.subscribe((data) => {
this.modelValue = data;
this.propagateChange(this.modelValue);
this.cd.markForCheck();
});
this.cd.markForCheck();
}, 0);
Expand Down

0 comments on commit 3ab6b0e

Please sign in to comment.