|
|
|
@ -14,7 +14,16 @@ |
|
|
|
/// limitations under the License.
|
|
|
|
///
|
|
|
|
|
|
|
|
import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; |
|
|
|
import { |
|
|
|
Component, |
|
|
|
DestroyRef, |
|
|
|
ElementRef, |
|
|
|
forwardRef, |
|
|
|
Input, |
|
|
|
OnInit, |
|
|
|
ViewChild, |
|
|
|
ViewEncapsulation |
|
|
|
} from '@angular/core'; |
|
|
|
import { |
|
|
|
AbstractControl, |
|
|
|
ControlValueAccessor, |
|
|
|
@ -31,6 +40,7 @@ import { Observable, of } from 'rxjs'; |
|
|
|
import { filter, mergeMap, share, tap } from 'rxjs/operators'; |
|
|
|
import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; |
|
|
|
import { isDefined } from '@core/utils'; |
|
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
|
|
|
|
|
export interface StringItemsOption { |
|
|
|
name: string; |
|
|
|
@ -120,6 +130,10 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit { |
|
|
|
@Input() |
|
|
|
fetchOptionsFn: (searchText?: string) => Observable<Array<StringItemsOption>>; |
|
|
|
|
|
|
|
@Input() |
|
|
|
@coerceBoolean() |
|
|
|
allowUserValue = false; |
|
|
|
|
|
|
|
get itemsControl(): AbstractControl { |
|
|
|
return this.stringItemsForm.get('items'); |
|
|
|
} |
|
|
|
@ -132,7 +146,8 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit { |
|
|
|
private propagateChange: (value: any) => void = () => {}; |
|
|
|
private dirty = false; |
|
|
|
|
|
|
|
constructor(private fb: FormBuilder) { |
|
|
|
constructor(private fb: FormBuilder, |
|
|
|
private destroyRef: DestroyRef) { |
|
|
|
this.stringItemsForm = this.fb.group({ |
|
|
|
item: [null], |
|
|
|
items: [null] |
|
|
|
@ -151,6 +166,7 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit { |
|
|
|
} |
|
|
|
}), |
|
|
|
filter((value) => typeof value === 'string'), |
|
|
|
tap(name => this.searchText = name), |
|
|
|
mergeMap(name => this.fetchOptionsFn ? this.fetchOptionsFn(name) : this.fetchValues(name)), |
|
|
|
share() |
|
|
|
); |
|
|
|
@ -243,12 +259,20 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit { |
|
|
|
private addItem(value: string) { |
|
|
|
const item = value.trim(); |
|
|
|
if (item) { |
|
|
|
if (this.predefinedValues) { |
|
|
|
if (this.predefinedValues && !this.allowUserValue) { |
|
|
|
const findItems = this.predefinedValues |
|
|
|
.filter(value => value.name.toLowerCase().includes(item.toLowerCase())); |
|
|
|
if (findItems.length === 1) { |
|
|
|
this.add(findItems[0]); |
|
|
|
} |
|
|
|
} else if (isDefined(this.fetchOptionsFn) && !this.allowUserValue) { |
|
|
|
this.fetchOptionsFn(item).pipe( |
|
|
|
takeUntilDestroyed(this.destroyRef) |
|
|
|
).subscribe((findItems) => { |
|
|
|
if (findItems.length === 1) { |
|
|
|
this.add(findItems[0]); |
|
|
|
} |
|
|
|
}) |
|
|
|
} else { |
|
|
|
this.add({value: item, name: item}); |
|
|
|
} |
|
|
|
@ -272,7 +296,6 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit { |
|
|
|
if (!this.predefinedValues?.length) { |
|
|
|
return of([]); |
|
|
|
} |
|
|
|
this.searchText = searchText; |
|
|
|
let result = this.predefinedValues; |
|
|
|
if (searchText && searchText.length) { |
|
|
|
result = this.predefinedValues.filter(option => option.name.toLowerCase().includes(searchText.toLowerCase())); |
|
|
|
|