|
|
@ -33,13 +33,13 @@ import { |
|
|
import { |
|
|
import { |
|
|
AbstractControl, |
|
|
AbstractControl, |
|
|
ControlValueAccessor, |
|
|
ControlValueAccessor, |
|
|
FormGroupDirective, |
|
|
FormGroupDirective, NG_VALIDATORS, |
|
|
NG_VALUE_ACCESSOR, |
|
|
NG_VALUE_ACCESSOR, |
|
|
NgForm, |
|
|
NgForm, |
|
|
UntypedFormBuilder, |
|
|
UntypedFormBuilder, |
|
|
UntypedFormControl, |
|
|
UntypedFormControl, |
|
|
UntypedFormGroup, |
|
|
UntypedFormGroup, |
|
|
ValidationErrors |
|
|
ValidationErrors, Validator |
|
|
} from '@angular/forms'; |
|
|
} from '@angular/forms'; |
|
|
import { Observable, of } from 'rxjs'; |
|
|
import { Observable, of } from 'rxjs'; |
|
|
import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; |
|
|
import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; |
|
|
@ -62,7 +62,7 @@ import { |
|
|
DataKeyConfigDialogComponent, |
|
|
DataKeyConfigDialogComponent, |
|
|
DataKeyConfigDialogData |
|
|
DataKeyConfigDialogData |
|
|
} from '@home/components/widget/config/data-key-config-dialog.component'; |
|
|
} 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 { Dashboard } from '@shared/models/dashboard.models'; |
|
|
import { AggregationType } from '@shared/models/time/time.models'; |
|
|
import { AggregationType } from '@shared/models/time/time.models'; |
|
|
import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; |
|
|
import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; |
|
|
@ -81,15 +81,20 @@ import { TbPopoverService } from '@shared/components/popover.service'; |
|
|
provide: NG_VALUE_ACCESSOR, |
|
|
provide: NG_VALUE_ACCESSOR, |
|
|
useExisting: forwardRef(() => DataKeysComponent), |
|
|
useExisting: forwardRef(() => DataKeysComponent), |
|
|
multi: true |
|
|
multi: true |
|
|
} /*, |
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
provide: NG_VALIDATORS, |
|
|
|
|
|
useExisting: forwardRef(() => DataKeysComponent), |
|
|
|
|
|
multi: true, |
|
|
|
|
|
}, |
|
|
{ |
|
|
{ |
|
|
provide: ErrorStateMatcher, |
|
|
provide: ErrorStateMatcher, |
|
|
useExisting: DataKeysComponent |
|
|
useExisting: DataKeysComponent |
|
|
} */ |
|
|
} |
|
|
], |
|
|
], |
|
|
encapsulation: ViewEncapsulation.None |
|
|
encapsulation: ViewEncapsulation.None |
|
|
}) |
|
|
}) |
|
|
export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher { |
|
|
export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher, Validator { |
|
|
|
|
|
|
|
|
public get hideDataKeyLabel(): boolean { |
|
|
public get hideDataKeyLabel(): boolean { |
|
|
return this.datasourceComponent.hideDataKeyLabel; |
|
|
return this.datasourceComponent.hideDataKeyLabel; |
|
|
@ -205,6 +210,9 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
|
|
|
|
|
private propagateChange = (v: any) => { }; |
|
|
private propagateChange = (v: any) => { }; |
|
|
|
|
|
|
|
|
|
|
|
private keysRequired = this._keysRequired.bind(this); |
|
|
|
|
|
private keysValidator = this._keysValidator.bind(this); |
|
|
|
|
|
|
|
|
constructor(private store: Store<AppState>, |
|
|
constructor(private store: Store<AppState>, |
|
|
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, |
|
|
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, |
|
|
private datasourceComponent: DatasourceComponent, |
|
|
private datasourceComponent: DatasourceComponent, |
|
|
@ -220,12 +228,16 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
updateValidators() { |
|
|
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(); |
|
|
this.keysListFormGroup.get('keys').updateValueAndValidity(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
keysRequired(control: AbstractControl): ValidationErrors | null { |
|
|
private _keysRequired(control: AbstractControl): ValidationErrors | null { |
|
|
const value = control.value; |
|
|
const value = this.modelValue; |
|
|
if (value && Array.isArray(value) && value.length) { |
|
|
if (value && Array.isArray(value) && value.length) { |
|
|
return null; |
|
|
return null; |
|
|
} else { |
|
|
} else { |
|
|
@ -233,8 +245,23 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 { |
|
|
registerOnChange(fn: any): void { |
|
|
this.propagateChange = fn; |
|
|
this.propagateChange = fn; |
|
|
|
|
|
if (!this.keysListFormGroup.valid) { |
|
|
|
|
|
this.propagateChange(this.modelValue); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
registerOnTouched(fn: any): void { |
|
|
registerOnTouched(fn: any): void { |
|
|
@ -242,9 +269,12 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
|
|
|
|
|
ngOnInit() { |
|
|
ngOnInit() { |
|
|
this.keysListFormGroup = this.fb.group({ |
|
|
this.keysListFormGroup = this.fb.group({ |
|
|
keys: [null, this.required ? [this.keysRequired] : []], |
|
|
keys: [null, [this.keysValidator]], |
|
|
key: [null] |
|
|
key: [null] |
|
|
}); |
|
|
}); |
|
|
|
|
|
if (this.required) { |
|
|
|
|
|
this.keysListFormGroup.get('keys').addValidators(this.keysRequired); |
|
|
|
|
|
} |
|
|
this.alarmKeys = []; |
|
|
this.alarmKeys = []; |
|
|
for (const name of Object.keys(alarmFields)) { |
|
|
for (const name of Object.keys(alarmFields)) { |
|
|
this.alarmKeys.push({ |
|
|
this.alarmKeys.push({ |
|
|
@ -335,8 +365,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
} else { |
|
|
} else { |
|
|
this.keys = []; |
|
|
this.keys = []; |
|
|
} |
|
|
} |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
|
|
|
this.modelValue = this.keys.length ? [...this.keys] : null; |
|
|
this.modelValue = this.keys.length ? [...this.keys] : null; |
|
|
|
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
if (this.keyInput) { |
|
|
if (this.keyInput) { |
|
|
this.keyInput.nativeElement.value = ''; |
|
|
this.keyInput.nativeElement.value = ''; |
|
|
} |
|
|
} |
|
|
@ -374,7 +404,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
|
|
|
|
|
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { |
|
|
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { |
|
|
const originalErrorState = this.errorStateMatcher.isErrorState(control, form); |
|
|
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; |
|
|
return originalErrorState || customErrorState; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -395,12 +425,20 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
} else { |
|
|
} else { |
|
|
this.keys = []; |
|
|
this.keys = []; |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
|
|
|
this.modelValue = null; |
|
|
this.modelValue = null; |
|
|
|
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
} |
|
|
} |
|
|
this.dirty = true; |
|
|
this.dirty = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
validate(c: UntypedFormControl) { |
|
|
|
|
|
return (this.keysListFormGroup.get('keys').hasError('dataKey')) ? { |
|
|
|
|
|
dataKeys: { |
|
|
|
|
|
valid: false, |
|
|
|
|
|
}, |
|
|
|
|
|
} : null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
onFocus() { |
|
|
onFocus() { |
|
|
if (this.dirty) { |
|
|
if (this.dirty) { |
|
|
this.keysListFormGroup.get('key').updateValueAndValidity({onlySelf: true, emitEvent: true}); |
|
|
this.keysListFormGroup.get('key').updateValueAndValidity({onlySelf: true, emitEvent: true}); |
|
|
@ -441,8 +479,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
const index = this.keys.indexOf(key); |
|
|
const index = this.keys.indexOf(key); |
|
|
if (index >= 0) { |
|
|
if (index >= 0) { |
|
|
this.keys.splice(index, 1); |
|
|
this.keys.splice(index, 1); |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
|
|
|
this.modelValue.splice(index, 1); |
|
|
this.modelValue.splice(index, 1); |
|
|
|
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
if (!this.modelValue.length) { |
|
|
if (!this.modelValue.length) { |
|
|
this.modelValue = null; |
|
|
this.modelValue = null; |
|
|
} |
|
|
} |
|
|
@ -468,8 +506,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
index = this.keys.length; |
|
|
index = this.keys.length; |
|
|
} |
|
|
} |
|
|
moveItemInArray(this.keys, this.dragIndex, index); |
|
|
moveItemInArray(this.keys, this.dragIndex, index); |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
|
|
|
moveItemInArray(this.modelValue, this.dragIndex, index); |
|
|
moveItemInArray(this.modelValue, this.dragIndex, index); |
|
|
|
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
this.dragIndex = -1; |
|
|
this.dragIndex = -1; |
|
|
this.propagateChange(this.modelValue); |
|
|
this.propagateChange(this.modelValue); |
|
|
} |
|
|
} |
|
|
@ -525,8 +563,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
}).afterClosed().subscribe((updatedDataKey) => { |
|
|
}).afterClosed().subscribe((updatedDataKey) => { |
|
|
if (updatedDataKey) { |
|
|
if (updatedDataKey) { |
|
|
this.keys[index] = updatedDataKey; |
|
|
this.keys[index] = updatedDataKey; |
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
|
|
|
this.modelValue[index] = updatedDataKey; |
|
|
this.modelValue[index] = updatedDataKey; |
|
|
|
|
|
this.keysListFormGroup.get('keys').setValue(this.keys); |
|
|
this.propagateChange(this.modelValue); |
|
|
this.propagateChange(this.modelValue); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|