import { Component, Input } from '@angular/core'; import { Observable, combineLatest, of } from 'rxjs'; import { OptionSelect } from '../../interface/option-select.interface'; import { AbmList } from '../../interface/abm-list.interface'; import { AbstractControl, FormControl, ValidationErrors } from '@angular/forms'; import { map, startWith } from 'rxjs/operators'; import { Search } from 'lucide-angular'; @Component({ selector: 'kit-abm-list-autocomplete', templateUrl: './abm-list-autocomplete.component.html', styleUrls: ['./abm-list-autocomplete.scss'] }) export class AbmListAutocompleteComponent { @Input() formControl!: FormControl; @Input() iconArrow: boolean = true; readonly searchI = Search; public abmListInputOptions: Observable | undefined; private _abmListInput!: AbmList; public constructor() { } @Input() public set abmListInput(abmListInput: AbmList) { this._abmListInput = abmListInput; this.setFilteredOptions() } public get abmListInput() { return this._abmListInput; } displayFn(option: any): string { return option && option.label ? option.label : ''; } setFilteredOptions() { const existingValidators = this.formControl.validator ? [this.formControl.validator] : []; this.formControl.setValidators([this.validateOption.bind(this), ...existingValidators]) if (this.formControl && this._abmListInput) { this.abmListInputOptions = combineLatest([ this.formControl.valueChanges.pipe(startWith(this.formControl.value || '')), of(this._abmListInput.values || []) ]).pipe( map(([inputValue, options]) => { if (inputValue) { const filterValue = typeof inputValue === 'object' && inputValue && inputValue.value ? inputValue.value.toLowerCase() : inputValue.toLowerCase(); if (!filterValue) { return options; } return options.filter(option => option.label.toLowerCase().includes(filterValue) ) } else { return options; } } ) ); } } clearSelection() { this.formControl.setValue(null); this.abmListInput.value = undefined } private validateOption(control: AbstractControl): ValidationErrors | null { const value = control.value; // Valida si el valor es un objeto o un primitivo y si está en las opciones if (this.abmListInput.values && value) { const isValid = this.abmListInput.values?.some(option => typeof value === 'object' ? option.value === value.value : option.value === value ); return isValid ? null : { invalidOption: true }; } return null } isControlRequired(): boolean { if (this.formControl && this.formControl.validator) { const validator = this.formControl.validator({} as any); return !!(validator && validator['required']); } return false; } }