import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { AbstractControl, ValidationErrors } from '@angular/forms'; import { Mask } from './models/mask'; import { Observable, combineLatestWith, map, of, startWith } from 'rxjs'; import { ChevronDown, DollarSign, X } from 'lucide-angular'; import { AbmList } from '../../interface'; @Component({ selector: 'abm-list-kit-input-currency', templateUrl: './abm-list-input-currency.component.html', }) export class AbmInputCurrencyComponent implements OnInit , OnChanges{ @Input() options: any[] = []; @Input() type: string = ''; @Input() placeholderType: string = ''; @Input() isLoading: boolean = false; @Input() label: string = ''; @Input() labelInput: string = ''; @Input() valueCurrency: AbstractControl | any; @Input() minlength?: number; @Input() maxlength?: number; @Input() onlyNumbers?: boolean; @Input() typeCurrency: AbstractControl | any; @Input() mask: Mask | any; @Input() iconClear:string =""; public filteredOptions$: Observable | undefined; readonly dollarSignI = DollarSign; readonly chevronDownI = ChevronDown; readonly xI = X; private _abmListInput!:AbmList; @Input() public set abmListInput(abmListInput:AbmList){ this._abmListInput = abmListInput; } public get abmListInput(){ return this._abmListInput; } ngOnInit(): void { this.setFilterObservable() } ngOnChanges(changes: SimpleChanges): void { if(changes['abmListInput']) { this.setFilterObservable() } } private setFilterObservable(){ this.filteredOptions$ = this.typeCurrency.valueChanges.pipe( startWith(this.typeCurrency.value || ''), combineLatestWith(of(this.abmListInput.values || [])), map(([inputValue, optionslist]) => { if(inputValue){ let filterValue: string; if (typeof inputValue === 'object' && inputValue) { filterValue = inputValue.value ? inputValue.value.toLowerCase() : ''; } else if (typeof inputValue === 'string') { filterValue = inputValue.toLowerCase(); } else { filterValue = ''; } if (!filterValue) { return optionslist; } return optionslist.filter((option: any) => option.value.toLowerCase().includes(filterValue) || // Filtra por value option.label.toLowerCase().includes(filterValue) // O por label ); } else { return optionslist; } }) ); if ( this.abmListInput?.values && this.abmListInput?.values?.length > 0 ) { const existingValidators = this.typeCurrency.validator ? [this.typeCurrency.validator] : []; this.typeCurrency.setValidators([this.validateOption.bind(this), ...existingValidators]) } } displayFn(option: any): string { return option && option.label ? option.label : ''; } clearSelection(){ this.typeCurrency.setValue(null); this.typeCurrency.markAsDirty(); this.typeCurrency.updateValueAndValidity(); } 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.valueCurrency && this.valueCurrency.validator && this.typeCurrency && this.typeCurrency.validator) { const validatorValue = this.valueCurrency.validator({} as any); const validatorType = this.typeCurrency.validator({} as any); return !!( (validatorValue && validatorValue.required) || (validatorType && validatorType.required) ); } return false } }