|
|
|
@ -16,8 +16,8 @@ |
|
|
|
|
|
|
|
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; |
|
|
|
import { |
|
|
|
ChangeDetectorRef, |
|
|
|
Component, |
|
|
|
DestroyRef, |
|
|
|
ElementRef, |
|
|
|
forwardRef, |
|
|
|
Input, |
|
|
|
@ -33,20 +33,18 @@ import { |
|
|
|
import { |
|
|
|
AbstractControl, |
|
|
|
ControlValueAccessor, |
|
|
|
FormBuilder, |
|
|
|
FormControl, |
|
|
|
FormGroup, |
|
|
|
FormGroupDirective, |
|
|
|
NG_VALIDATORS, |
|
|
|
NG_VALUE_ACCESSOR, |
|
|
|
NgForm, |
|
|
|
UntypedFormBuilder, |
|
|
|
UntypedFormControl, |
|
|
|
UntypedFormGroup, |
|
|
|
ValidationErrors, |
|
|
|
Validator |
|
|
|
} from '@angular/forms'; |
|
|
|
import { Observable, of } from 'rxjs'; |
|
|
|
import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; |
|
|
|
import { Store } from '@ngrx/store'; |
|
|
|
import { AppState } from '@app/core/core.state'; |
|
|
|
import { Observable, of, ReplaySubject } from 'rxjs'; |
|
|
|
import { filter, map, mergeMap, share, tap } from 'rxjs/operators'; |
|
|
|
import { TranslateService } from '@ngx-translate/core'; |
|
|
|
import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete'; |
|
|
|
import { MatChipGrid, MatChipInputEvent, MatChipRow } from '@angular/material/chips'; |
|
|
|
@ -58,7 +56,6 @@ import { DataKeySettingsFunction } from './data-keys.component.models'; |
|
|
|
import { alarmFields } from '@shared/models/alarm.models'; |
|
|
|
import { UtilsService } from '@core/services/utils.service'; |
|
|
|
import { ErrorStateMatcher } from '@angular/material/core'; |
|
|
|
import { TruncatePipe } from '@shared/pipe/truncate.pipe'; |
|
|
|
import { MatDialog } from '@angular/material/dialog'; |
|
|
|
import { |
|
|
|
DataKeyConfigDialogComponent, |
|
|
|
@ -74,6 +71,7 @@ import { DatasourceComponent } from '@home/components/widget/config/datasource.c |
|
|
|
import { ColorPickerPanelComponent } from '@shared/components/color-picker/color-picker-panel.component'; |
|
|
|
import { TbPopoverService } from '@shared/components/popover.service'; |
|
|
|
import { WidgetConfigCallbacks } from '@home/components/widget/config/widget-config.component.models'; |
|
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
selector: 'tb-data-keys', |
|
|
|
@ -115,11 +113,10 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
return this.datasourceComponent.hideDataKeyDecimals; |
|
|
|
} |
|
|
|
|
|
|
|
datasourceTypes = DatasourceType; |
|
|
|
widgetTypes = widgetType; |
|
|
|
dataKeyTypes = DataKeyType; |
|
|
|
|
|
|
|
keysListFormGroup: UntypedFormGroup; |
|
|
|
keysListFormGroup: FormGroup; |
|
|
|
|
|
|
|
modelValue: Array<DataKey> | null; |
|
|
|
|
|
|
|
@ -218,23 +215,21 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
|
|
|
|
private dirty = false; |
|
|
|
|
|
|
|
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>, |
|
|
|
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, |
|
|
|
constructor(@SkipSelf() private errorStateMatcher: ErrorStateMatcher, |
|
|
|
private datasourceComponent: DatasourceComponent, |
|
|
|
public translate: TranslateService, |
|
|
|
private translate: TranslateService, |
|
|
|
private utils: UtilsService, |
|
|
|
private dialog: MatDialog, |
|
|
|
private fb: UntypedFormBuilder, |
|
|
|
private cd: ChangeDetectorRef, |
|
|
|
private fb: FormBuilder, |
|
|
|
private popoverService: TbPopoverService, |
|
|
|
private viewContainerRef: ViewContainerRef, |
|
|
|
private renderer: Renderer2, |
|
|
|
public truncate: TruncatePipe) { |
|
|
|
private destroyRef: DestroyRef) { |
|
|
|
} |
|
|
|
|
|
|
|
updateValidators() { |
|
|
|
@ -246,7 +241,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
this.keysListFormGroup.get('keys').updateValueAndValidity(); |
|
|
|
} |
|
|
|
|
|
|
|
private _keysRequired(control: AbstractControl): ValidationErrors | null { |
|
|
|
private _keysRequired(_control: AbstractControl): ValidationErrors | null { |
|
|
|
const value = this.modelValue; |
|
|
|
if (value && Array.isArray(value) && value.length) { |
|
|
|
return null; |
|
|
|
@ -255,7 +250,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private _keysValidator(control: AbstractControl): ValidationErrors | null { |
|
|
|
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))) { |
|
|
|
@ -274,7 +269,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
registerOnTouched(fn: any): void { |
|
|
|
registerOnTouched(_fn: any): void { |
|
|
|
} |
|
|
|
|
|
|
|
ngOnInit() { |
|
|
|
@ -314,6 +309,15 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
mergeMap(name => this.fetchKeys(name) ), |
|
|
|
share() |
|
|
|
); |
|
|
|
|
|
|
|
this.aliasController.entityAliasesChanged.pipe( |
|
|
|
takeUntilDestroyed(this.destroyRef) |
|
|
|
).subscribe(aliasIds => { |
|
|
|
if (aliasIds.includes(this.entityAliasId)) { |
|
|
|
this.clearSearchCache(); |
|
|
|
this.dirty = true; |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
public maxDataKeysText(): string { |
|
|
|
@ -413,7 +417,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { |
|
|
|
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { |
|
|
|
const originalErrorState = this.errorStateMatcher.isErrorState(control, form); |
|
|
|
const customErrorState = this.keysListFormGroup.get('keys').hasError('dataKey'); |
|
|
|
return originalErrorState || customErrorState; |
|
|
|
@ -442,7 +446,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
this.dirty = true; |
|
|
|
} |
|
|
|
|
|
|
|
validate(c: UntypedFormControl) { |
|
|
|
validate(_c: FormControl) { |
|
|
|
return (this.keysListFormGroup.get('keys').hasError('dataKey')) ? { |
|
|
|
dataKeys: { |
|
|
|
valid: false, |
|
|
|
@ -637,8 +641,12 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
fetchObservable = of([]); |
|
|
|
} |
|
|
|
this.fetchObservable$ = fetchObservable.pipe( |
|
|
|
publishReplay(1), |
|
|
|
refCount() |
|
|
|
share({ |
|
|
|
connector: () => new ReplaySubject(1), |
|
|
|
resetOnError: false, |
|
|
|
resetOnComplete: false, |
|
|
|
resetOnRefCountZero: false |
|
|
|
}) |
|
|
|
); |
|
|
|
} |
|
|
|
return this.fetchObservable$; |
|
|
|
@ -650,7 +658,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange |
|
|
|
} |
|
|
|
|
|
|
|
textIsNotEmpty(text: string): boolean { |
|
|
|
return text && text.length > 0; |
|
|
|
return text?.length > 0; |
|
|
|
} |
|
|
|
|
|
|
|
clear(value: string = '', focus = true) { |
|
|
|
|