// autocomplete-checkbox.component.ts import { Component, Input, OnChanges, OnInit, SimpleChanges, Output, EventEmitter } from '@angular/core'; import { Observable, map, startWith, of } from 'rxjs'; import { Search, CircleAlert } from 'lucide-angular'; @Component({ selector: 'kit-autocomplete-checkbox', templateUrl: './autocomplete-checkbox.component.html', }) export class AutocompleteCheckboxComponent implements OnInit, OnChanges { @Input() options?: any[] = []; @Input() placeholderText: string = ''; @Input() control?: any; @Input() label: string = ''; @Input() minlength?: number; @Input() maxlength?: number; @Input() messageErrorCustom: string = ''; @Input() deselectOption?: any; @Input() allowDeselect: boolean = true; @Input() descriptionTooltip: string = ''; @Output() optionSelected = new EventEmitter(); filteredOptions: Observable | undefined; selectedValues: Set = new Set(); readonly searchI = Search; readonly infoCircle = CircleAlert; ngOnInit() { this.setupFilteredOptions(); } ngOnChanges(changes: SimpleChanges): void { if (changes['options']) { this.setupFilteredOptions(); } if (changes['deselectOption'] && changes['deselectOption'].currentValue) { this.deselectFromParent(changes['deselectOption'].currentValue); } } private setupFilteredOptions(): void { if (!this.control) { this.filteredOptions = of(this.options?.slice() || []); return; } this.filteredOptions = this.control.valueChanges.pipe( startWith(''), map((value: any) => { if (!value || value === '') { return this.options?.slice() || []; } const label = typeof value === 'string' ? value : value?.label; return label ? this._filter(label as string) : this.options?.slice() || []; }), ); } getDisplayValue(): string { return ''; } isSpecialtySelected(value: any): boolean { return this.selectedValues.has(value); } toggleSpecialty(value: any): void { const isCurrentlySelected = this.isSpecialtySelected(value); if (isCurrentlySelected && !this.allowDeselect) { return; } if (isCurrentlySelected) { this.selectedValues.delete(value); this.optionSelected.emit({ option: value, selectedOptions: Array.from(this.selectedValues), action: 'removed' }); } else { this.selectedValues.add(value); this.control?.setValue(''); this.optionSelected.emit({ option: value, selectedOptions: Array.from(this.selectedValues), action: 'added' }); } } private deselectFromParent(valueToDeselect: any): void { if (this.isSpecialtySelected(valueToDeselect)) { this.selectedValues.delete(valueToDeselect); this.optionSelected.emit({ option: valueToDeselect, selectedOptions: Array.from(this.selectedValues), action: 'removed' }); } } private _filter(label: string): any[] { const filterValue = label.toLowerCase(); return this.options?.filter(option => option.label.toLowerCase().includes(filterValue)) || []; } isControlRequired(): boolean { if (this.control && this.control.validator) { const validator = this.control.validator({} as any); return !!(validator && validator.required); } return false; } }