@guajiritos/general-autocomplete 19.0.3 → 19.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -186,10 +186,9 @@ class GuajiritosGeneralAutocomplete {
|
|
186
186
|
.pipe(takeUntilDestroyed(this._destroyRef))
|
187
187
|
.subscribe({
|
188
188
|
next: () => {
|
189
|
-
this.
|
190
|
-
|
191
|
-
|
192
|
-
this.selectElement.emit(null);
|
189
|
+
this.clearInternalState();
|
190
|
+
// No es necesario llamar a setValue(null) o propagateChange(null) aquí
|
191
|
+
// porque clearInternalState ya lo hace.
|
193
192
|
},
|
194
193
|
});
|
195
194
|
}
|
@@ -249,11 +248,8 @@ class GuajiritosGeneralAutocomplete {
|
|
249
248
|
this._zone.run(() => {
|
250
249
|
setTimeout(() => {
|
251
250
|
this.inputText?.nativeElement?.focus();
|
252
|
-
|
253
|
-
|
254
|
-
this.inputText?.nativeElement?.dispatchEvent(new Event("input"));
|
255
|
-
// Abrir explícitamente el panel usando el MatAutocompleteTrigger
|
256
|
-
this.autocompleteTrigger?.openPanel(); // <--- EL CAMBIO ES AQUÍ
|
251
|
+
this.inputText?.nativeElement?.dispatchEvent(new Event("input")); // Simular input para disparar valueChanges
|
252
|
+
this.autocompleteTrigger?.openPanel();
|
257
253
|
}, 50); // Un pequeño retraso para asegurar el foco y la apertura
|
258
254
|
});
|
259
255
|
},
|
@@ -274,8 +270,6 @@ class GuajiritosGeneralAutocomplete {
|
|
274
270
|
this.originalOptions.set([]);
|
275
271
|
this.filteredOptions.set([]);
|
276
272
|
this.hasMore.set(true);
|
277
|
-
// IMPORTANTE: _selectedElement NO se resetea aquí, solo si se borra explícitamente
|
278
|
-
// _lastSearchText se actualiza en writeValue y optionSelected
|
279
273
|
console.log("Autocomplete state reset (pagination/options).");
|
280
274
|
}
|
281
275
|
/**
|
@@ -284,47 +278,66 @@ class GuajiritosGeneralAutocomplete {
|
|
284
278
|
subscribeToComponentChanges() {
|
285
279
|
this.component.valueChanges
|
286
280
|
.pipe(
|
287
|
-
//
|
281
|
+
// TAP se ejecuta inmediatamente ANTES del debounce.
|
282
|
+
// Esto es crucial para detectar borrados de texto en tiempo real.
|
288
283
|
tap((value) => {
|
289
|
-
|
290
|
-
//
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
284
|
+
const currentInputText = this.getAutocompleteSearchText();
|
285
|
+
// Si el valor actual del control es un STRING (usuario escribiendo/borrando)
|
286
|
+
// Y previamente había un objeto seleccionado (_selectedElement)
|
287
|
+
// Y el texto en el input ya no coincide con el displayFn del _selectedElement,
|
288
|
+
// entonces desvinculamos el _selectedElement y marcamos que no hay selección.
|
289
|
+
if (typeof value === "string" &&
|
290
|
+
this._selectedElement &&
|
291
|
+
currentInputText !== this.displayFn(this._selectedElement)) {
|
292
|
+
console.log("TAP: User is editing/clearing text of a selected item. Deselecting internally.");
|
293
|
+
this._selectedElement = null; // Quitar la referencia al objeto seleccionado
|
294
|
+
this._isOptionSelected = false; // Marcar que no hay una opción seleccionada
|
295
|
+
// IMPORTANTE: NO LLAMAR a `this.propagateChange(null);` ni `this.component.setValue(null);` aquí.
|
296
|
+
// Queremos que el texto escrito/borrado permanezca en el input.
|
297
|
+
// La limpieza total (propagateChange(null)) ocurrirá después del debounce o al cerrar el panel.
|
298
|
+
}
|
299
|
+
else if (typeof value === "string") {
|
300
|
+
// Si el valor es un string, simplemente marcamos que no hay opción seleccionada.
|
301
|
+
// Esto cubre los casos donde el usuario escribe por primera vez o borra sin haber seleccionado.
|
296
302
|
this._isOptionSelected = false;
|
297
|
-
return; // Salir del tap, el debounce/switchMap no se ejecutará para este valor.
|
298
303
|
}
|
299
|
-
}), debounceTime(this.debounceTimeValue),
|
304
|
+
}), debounceTime(this.debounceTimeValue), // El debounce se aplica después de la lógica del tap
|
305
|
+
takeUntilDestroyed(this._destroyRef))
|
300
306
|
.subscribe({
|
301
307
|
next: (value) => {
|
302
308
|
const currentSearchText = this.getAutocompleteSearchText();
|
303
|
-
//
|
304
|
-
//
|
305
|
-
if (typeof value === "object" &&
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
309
|
+
// Caso 1: El valor es un objeto y coincide con el elemento seleccionado.
|
310
|
+
// Esto ocurre si el usuario seleccionó un elemento y el debounce pasó sin más ediciones.
|
311
|
+
if (typeof value === "object" &&
|
312
|
+
value !== null &&
|
313
|
+
this._selectedElement === value) {
|
314
|
+
console.log("Value is selected object (after debounce), skipping search.");
|
315
|
+
// Aseguramos que el _lastSearchText esté correcto para este objeto.
|
316
|
+
this._lastSearchText = this.displayFn(value);
|
317
|
+
return;
|
312
318
|
}
|
313
|
-
//
|
314
|
-
//
|
315
|
-
// O si el texto está vacío (para cargar las opciones iniciales si se borra)
|
319
|
+
// Caso 2: El usuario ha terminado de escribir o borrar texto.
|
320
|
+
// Si el texto actual ha cambiado con respecto al último buscado, o se ha vaciado.
|
316
321
|
if ((typeof value === "string" &&
|
317
322
|
currentSearchText !== this._lastSearchText) ||
|
318
|
-
(currentSearchText === "" && this._lastSearchText !== "")
|
319
|
-
) {
|
323
|
+
(currentSearchText === "" && this._lastSearchText !== "")) {
|
320
324
|
this.resetAutocompleteState(); // Reiniciar paginación y opciones
|
321
325
|
this._lastSearchText = currentSearchText; // Actualizar el último texto buscado
|
322
|
-
console.log("Value changed, initiating new search for:", currentSearchText);
|
326
|
+
console.log("Value changed (after debounce), initiating new search for:", currentSearchText);
|
323
327
|
this.getAutocompleteByTextHandler(currentSearchText);
|
328
|
+
// Si _selectedElement es null (porque se desvinculó en el tap)
|
329
|
+
// y el texto actual no es vacío, propagar el string.
|
330
|
+
// Si es vacío y no hay selección, propagamos null.
|
331
|
+
if (!this._selectedElement && currentSearchText !== "") {
|
332
|
+
this.propagateChange(currentSearchText);
|
333
|
+
}
|
334
|
+
else if (!this._selectedElement && currentSearchText === "") {
|
335
|
+
this.propagateChange(null);
|
336
|
+
}
|
324
337
|
}
|
325
338
|
else if (currentSearchText === "" && this._lastSearchText === "") {
|
326
|
-
// Si el input está vacío y ya lo estaba, y el
|
327
|
-
//
|
339
|
+
// Si el input está vacío y ya lo estaba, y el panel está abierto sin opciones,
|
340
|
+
// cargar las opciones iniciales.
|
328
341
|
if (this.matAutocomplete._isOpen &&
|
329
342
|
this.originalOptions().length === 0 &&
|
330
343
|
!this.loading()) {
|
@@ -367,67 +380,75 @@ class GuajiritosGeneralAutocomplete {
|
|
367
380
|
// Lógica para manejar el borrado del input si no hay una selección válida
|
368
381
|
// o si el texto no coincide con el elemento seleccionado.
|
369
382
|
if (typeof currentInputValue === "string") {
|
370
|
-
// Si el
|
371
|
-
if (this.
|
372
|
-
|
373
|
-
//
|
374
|
-
if (!this._selectedElement ||
|
375
|
-
currentInputText !== this.displayFn(this._selectedElement)) {
|
376
|
-
console.warn("Autocomplete closed: Input cleared because selection is required and no valid match found.");
|
377
|
-
this.clearInternalState(); // Usa un método para limpiar
|
378
|
-
}
|
383
|
+
// Si el input está vacío Y no hay un elemento seleccionado
|
384
|
+
if (currentInputText === "" && !this._selectedElement) {
|
385
|
+
console.log("Autocomplete closed: Input empty and no selection. Clearing internal state.");
|
386
|
+
this.clearInternalState(); // Usa un método para limpiar
|
379
387
|
}
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
currentInputText !== this.displayFn(this._selectedElement)) {
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
}
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
}
|
388
|
+
// Si se requiere selección y el texto no coincide con el elemento seleccionado,
|
389
|
+
// o no hay ningún elemento seleccionado, entonces se borra.
|
390
|
+
else if (this.requireSelection &&
|
391
|
+
(!this._selectedElement ||
|
392
|
+
currentInputText !== this.displayFn(this._selectedElement))) {
|
393
|
+
console.warn("Autocomplete closed: Selection required and no valid match found. Clearing input.");
|
394
|
+
this.clearInternalState(); // Usa un método para limpiar
|
395
|
+
}
|
396
|
+
// Si NO se requiere selección, pero el usuario ha editado el texto de un elemento previamente seleccionado.
|
397
|
+
// En este caso, NO borramos, sino que revertimos al texto del elemento seleccionado si existe.
|
398
|
+
else if (this._selectedElement &&
|
399
|
+
currentInputText !== this.displayFn(this._selectedElement) &&
|
400
|
+
!this.requireSelection) {
|
401
|
+
console.log("Autocomplete closed: Text edited for a selected item, reverting to original.");
|
402
|
+
// Revertir al texto del elemento seleccionado.
|
403
|
+
this.component.setValue(this._selectedElement, {
|
404
|
+
emitEvent: false,
|
405
|
+
});
|
406
|
+
this._lastSearchText = this.displayFn(this._selectedElement);
|
407
|
+
this.propagateChange(this._selectedElement); // Propagar el valor original si se revierte
|
408
|
+
}
|
409
|
+
// Si el texto del input es un string y no se requiere selección,
|
410
|
+
// y no hay _selectedElement (porque se deseleccionó en el tap o nunca hubo),
|
411
|
+
// asumimos que el usuario quiere el texto libre.
|
412
|
+
// No hacemos nada, el texto permanece.
|
413
|
+
else if (typeof currentInputValue === "string" &&
|
414
|
+
!this.requireSelection &&
|
415
|
+
!this._selectedElement &&
|
416
|
+
currentInputText !== "") {
|
417
|
+
// Si no hay un elemento seleccionado pero el usuario escribió algo
|
418
|
+
// y no se requiere selección, dejamos el texto tal cual.
|
419
|
+
// Aseguramos que _lastSearchText se actualice para evitar re-búsquedas innecesarias.
|
420
|
+
this._lastSearchText = currentInputText;
|
421
|
+
this.propagateChange(currentInputText);
|
415
422
|
}
|
416
423
|
}
|
417
|
-
// Si el valor ya es un objeto (porque se seleccionó)
|
418
|
-
//
|
419
|
-
|
424
|
+
// Si el valor ya es un objeto (porque se seleccionó) pero el texto del input fue borrado
|
425
|
+
// y el _selectedElement es null (ya se desvinculó en el tap), significa que debe limpiarse.
|
426
|
+
else if (typeof currentInputValue === "object" &&
|
427
|
+
currentInputText === "" &&
|
428
|
+
!this._selectedElement) {
|
429
|
+
console.log("Autocomplete closed: Object value but input cleared by user. Deselecting.");
|
430
|
+
this.clearInternalState();
|
431
|
+
}
|
420
432
|
});
|
421
433
|
}
|
422
434
|
/**
|
423
435
|
* Helper method to clear the internal state of the autocomplete.
|
436
|
+
* Este método ahora se encarga de la limpieza profunda, incluyendo el valor del FormControl y la propagación.
|
437
|
+
* @param resetLastSearchText - If true, resets _lastSearchText to an empty string. Defaults to true.
|
424
438
|
*/
|
425
|
-
clearInternalState() {
|
426
|
-
|
439
|
+
clearInternalState(resetLastSearchText = true) {
|
440
|
+
// Solo si el valor del control NO es null, lo seteamos a null para evitar bucles.
|
441
|
+
// Esto es importante porque en el tap, solo desvinculamos `_selectedElement` pero no el control.
|
442
|
+
if (this.component.value !== null) {
|
443
|
+
this.component.setValue(null, { emitEvent: false });
|
444
|
+
}
|
427
445
|
this.propagateChange(null);
|
428
446
|
this.selectElement.emit(null);
|
429
|
-
this._selectedElement = null;
|
430
|
-
this.
|
447
|
+
this._selectedElement = null; // Asegurar que el objeto seleccionado esté a null
|
448
|
+
this._isOptionSelected = false; // Asegurar que la bandera de selección esté a false
|
449
|
+
if (resetLastSearchText) {
|
450
|
+
this._lastSearchText = "";
|
451
|
+
}
|
431
452
|
this.resetAutocompleteState(); // Resetear opciones y paginación
|
432
453
|
console.log("Internal autocomplete state cleared.");
|
433
454
|
}
|
@@ -568,6 +589,7 @@ class GuajiritosGeneralAutocomplete {
|
|
568
589
|
: value
|
569
590
|
: null;
|
570
591
|
// Actualizar _lastSearchText basado en el valor que se está escribiendo.
|
592
|
+
// Si el valor es nulo, _lastSearchText también debe ser nulo o vacío
|
571
593
|
if (value) {
|
572
594
|
this._lastSearchText = this.displayFn(value);
|
573
595
|
console.log("writeValue: Last search text set to:", this._lastSearchText);
|
@@ -592,11 +614,6 @@ class GuajiritosGeneralAutocomplete {
|
|
592
614
|
clear(trigger) {
|
593
615
|
this.clearElement.emit(this.component.value);
|
594
616
|
this.clearInternalState(); // Usa el método auxiliar para limpiar
|
595
|
-
// this.component.setValue(null); // Ya se llama dentro de clearInternalState
|
596
|
-
// this.propagateChange(null);
|
597
|
-
// this.selectElement.emit(null);
|
598
|
-
// this._selectedElement = null;
|
599
|
-
// this._lastSearchText = "";
|
600
617
|
this._zone.run(() => {
|
601
618
|
setTimeout(() => {
|
602
619
|
trigger.openPanel(); // Reabrir el panel después de borrar
|
@@ -643,12 +660,9 @@ class GuajiritosGeneralAutocomplete {
|
|
643
660
|
}
|
644
661
|
else {
|
645
662
|
// Si se deselecciona o selecciona nulo
|
646
|
-
// Esto rara vez debería ocurrir si se selecciona una opción válida, pero es un fallback.
|
647
663
|
console.log("Option selected is null or undefined, clearing state.");
|
648
664
|
this.clearInternalState();
|
649
665
|
}
|
650
|
-
// Después de la selección, el panel se cierra automáticamente en la mayoría de los casos de MatAutocomplete.
|
651
|
-
// this.matAutocomplete.closePanel(); // Descomentar si el panel no se cierra automáticamente
|
652
666
|
}
|
653
667
|
/**
|
654
668
|
* Handles the scroll event in the autocomplete panel to load more data.
|
@@ -658,14 +672,6 @@ class GuajiritosGeneralAutocomplete {
|
|
658
672
|
const scrollPosition = element.scrollTop + element.clientHeight;
|
659
673
|
const scrollHeight = element.scrollHeight;
|
660
674
|
const threshold = 50; // Pixels before the end to load more
|
661
|
-
// console.log("--- Scroll Event ---");
|
662
|
-
// console.log("Scroll Top:", element.scrollTop);
|
663
|
-
// console.log("Client Height:", element.clientHeight);
|
664
|
-
// console.log("Scroll Position (Top + Client):", scrollPosition);
|
665
|
-
// console.log("Scroll Height (Total):", scrollHeight);
|
666
|
-
// console.log("Remaining distance to bottom:", scrollHeight - scrollPosition);
|
667
|
-
// console.log("Is Loading:", this.loading());
|
668
|
-
// console.log("Has More:", this.hasMore());
|
669
675
|
if (scrollHeight - scrollPosition <= threshold &&
|
670
676
|
!this.loading() &&
|
671
677
|
this.hasMore()) {
|
@@ -681,7 +687,7 @@ class GuajiritosGeneralAutocomplete {
|
|
681
687
|
useExisting: forwardRef(() => GuajiritosGeneralAutocomplete),
|
682
688
|
multi: true,
|
683
689
|
},
|
684
|
-
], viewQueries: [{ propertyName: "inputText", first: true, predicate: ["inputText"], descendants: true, static: true }, { propertyName: "matAutocomplete", first: true, predicate: ["auto"], descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], ngImport: i0, template: "<mat-form-field
|
690
|
+
], viewQueries: [{ propertyName: "inputText", first: true, predicate: ["inputText"], descendants: true, static: true }, { propertyName: "matAutocomplete", first: true, predicate: ["auto"], descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], ngImport: i0, template: "<mat-form-field\n [floatLabel]=\"floatLabel\"\n class=\"w-100\"\n [appearance]=\"appearance\"\n [color]=\"color\"\n [subscriptSizing]=\"subscriptSizing\"\n>\n @if (showLabel) {\n <mat-label>{{ label | translate }}</mat-label>\n } @if (showSuffix) {\n <mat-icon matSuffix>{{ suffixIcon ?? \"search\" }}</mat-icon>\n }\n <input\n #inputText\n #trigger=\"matAutocompleteTrigger\"\n (focus)=\"onFocus()\"\n [formControl]=\"component\"\n type=\"text\"\n [matAutocomplete]=\"auto\"\n [placeholder]=\"placeholder | translate\"\n aria-label=\"autocomplete\"\n autocomplete=\"off\"\n matInput\n [required]=\"required()\"\n />\n @if (!loading() && component.value) {\n <button\n (click)=\"clear(trigger)\"\n [disabled]=\"disabled()\"\n aria-label=\"Clear\"\n mat-icon-button\n matSuffix\n >\n <mat-icon>close</mat-icon>\n </button>\n } @if (loading()) {\n <button aria-label=\"search\" mat-icon-button matSuffix>\n <mat-spinner [value]=\"90\" color=\"accent\" diameter=\"25\"></mat-spinner>\n </button>\n }\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [displayWith]=\"displayFn\"\n [requireSelection]=\"requireSelection\"\n (optionSelected)=\"optionSelected($event)\"\n >\n @for (option of filteredOptions(); track option) {\n <mat-option [value]=\"option\">\n @if (!displayOptions && !detailsTemplate) {\n {{ option?.name | i18n: translateService.currentLang }}\n } @if (!detailsTemplate) {\n <div class=\"display-options\">\n <span [ngStyle]=\"{'line-height': displayOptions?.secondLabel ? '16px' : ''}\">\n {{\n option | resolvePropertyPath : displayOptions.firthLabel\n | i18n : translateService.currentLang\n }}\n </span>\n @if (displayOptions?.secondLabel) {\n <span class=\"mat-caption\">\n {{\n option | resolvePropertyPath : displayOptions.secondLabel\n | i18n : translateService.currentLang\n }}\n </span>\n }\n </div>\n } @if (detailsTemplate) {\n <ng-container\n *ngTemplateOutlet=\"detailsTemplate; context: { $implicit: option }\"\n ></ng-container>\n }\n </mat-option>\n }\n </mat-autocomplete>\n\n @if (component.invalid && component.touched) {\n <mat-error>\n {{ 'Este campo es requerido.' | translate }}\n </mat-error>\n }\n</mat-form-field>\n", styles: [".w-100{width:100%}.display-options{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i9.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i10.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i10.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "pipe", type: I18nPipe, name: "i18n" }, { kind: "pipe", type: ResolvePropertyPath, name: "resolvePropertyPath" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
685
691
|
}
|
686
692
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: GuajiritosGeneralAutocomplete, decorators: [{
|
687
693
|
type: Component,
|
@@ -703,7 +709,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImpo
|
|
703
709
|
useExisting: forwardRef(() => GuajiritosGeneralAutocomplete),
|
704
710
|
multi: true,
|
705
711
|
},
|
706
|
-
], template: "<mat-form-field
|
712
|
+
], template: "<mat-form-field\n [floatLabel]=\"floatLabel\"\n class=\"w-100\"\n [appearance]=\"appearance\"\n [color]=\"color\"\n [subscriptSizing]=\"subscriptSizing\"\n>\n @if (showLabel) {\n <mat-label>{{ label | translate }}</mat-label>\n } @if (showSuffix) {\n <mat-icon matSuffix>{{ suffixIcon ?? \"search\" }}</mat-icon>\n }\n <input\n #inputText\n #trigger=\"matAutocompleteTrigger\"\n (focus)=\"onFocus()\"\n [formControl]=\"component\"\n type=\"text\"\n [matAutocomplete]=\"auto\"\n [placeholder]=\"placeholder | translate\"\n aria-label=\"autocomplete\"\n autocomplete=\"off\"\n matInput\n [required]=\"required()\"\n />\n @if (!loading() && component.value) {\n <button\n (click)=\"clear(trigger)\"\n [disabled]=\"disabled()\"\n aria-label=\"Clear\"\n mat-icon-button\n matSuffix\n >\n <mat-icon>close</mat-icon>\n </button>\n } @if (loading()) {\n <button aria-label=\"search\" mat-icon-button matSuffix>\n <mat-spinner [value]=\"90\" color=\"accent\" diameter=\"25\"></mat-spinner>\n </button>\n }\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [displayWith]=\"displayFn\"\n [requireSelection]=\"requireSelection\"\n (optionSelected)=\"optionSelected($event)\"\n >\n @for (option of filteredOptions(); track option) {\n <mat-option [value]=\"option\">\n @if (!displayOptions && !detailsTemplate) {\n {{ option?.name | i18n: translateService.currentLang }}\n } @if (!detailsTemplate) {\n <div class=\"display-options\">\n <span [ngStyle]=\"{'line-height': displayOptions?.secondLabel ? '16px' : ''}\">\n {{\n option | resolvePropertyPath : displayOptions.firthLabel\n | i18n : translateService.currentLang\n }}\n </span>\n @if (displayOptions?.secondLabel) {\n <span class=\"mat-caption\">\n {{\n option | resolvePropertyPath : displayOptions.secondLabel\n | i18n : translateService.currentLang\n }}\n </span>\n }\n </div>\n } @if (detailsTemplate) {\n <ng-container\n *ngTemplateOutlet=\"detailsTemplate; context: { $implicit: option }\"\n ></ng-container>\n }\n </mat-option>\n }\n </mat-autocomplete>\n\n @if (component.invalid && component.touched) {\n <mat-error>\n {{ 'Este campo es requerido.' | translate }}\n </mat-error>\n }\n</mat-form-field>\n", styles: [".w-100{width:100%}.display-options{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}\n"] }]
|
707
713
|
}], ctorParameters: () => [{ type: i1.AutocompleteService }, { type: i0.NgZone }, { type: i0.DestroyRef }, { type: i2.TranslateService }], propDecorators: { inputText: [{
|
708
714
|
type: ViewChild,
|
709
715
|
args: ["inputText", { static: true }]
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"guajiritos-general-autocomplete.mjs","sources":["../../../projects/guachos-general-autocomplete/src/utils/constants/constants.ts","../../../projects/guachos-general-autocomplete/src/utils/services/utils.service.ts","../../../projects/guachos-general-autocomplete/src/utils/pipes/resolve-property-path.pipe.ts","../../../projects/guachos-general-autocomplete/src/lib/guachos-general-autocomplete.component.ts","../../../projects/guachos-general-autocomplete/src/lib/guachos-general-autocomplete.component.html","../../../projects/guachos-general-autocomplete/src/public-api.ts","../../../projects/guachos-general-autocomplete/src/guajiritos-general-autocomplete.ts"],"sourcesContent":["import { DisplayOption, DisplayOptionItemType } from '@guajiritos/services';\nimport {DisplayOptionItem} from \"@guajiritos/services/lib/interfaces/interfaces\";\n\n\nexport const GENERAL_DISPLAY_OPTIONS: DisplayOption = {\n firthLabel: [\n {\n type: DisplayOptionItemType.PATH,\n path: ['name']\n }\n ],\n applyTranslate: true\n};\n\nexport interface ServiceConfig {\n service: any;\n method: string;\n postBody: any;\n searchProperty: string;\n}\n","import {Injectable} from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class UtilsService {\n /**\n * Resolves the value of a property in an object by providing a path.\n *\n * @param {any} obj - The object to traverse.\n * @param {string[]} path - An array of strings representing the path to the desired property.\n * @return {any} The value of the property at the given path, or null if the path is invalid.\n */\n public static resolvePropertyByPath(obj: any, path: string[]): any {\n return path.reduce((prev, curr: string) => {\n return prev ? prev[curr] : null;\n }, obj || self);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { DisplayOptionItem, DisplayOptionItemType } from '@guajiritos/services';\n\nimport { UtilsService } from '../services/utils.service';\n\n@Pipe({\n name: 'resolvePropertyPath',\n standalone: true\n})\nexport class ResolvePropertyPath implements PipeTransform {\n /**\n * Transforms the given object based on the provided path and returns the transformed string.\n *\n * @param {any} obj - The object to be transformed.\n * @param {DisplayOptionItem[]} path - The array of display option items used for transformation.\n * @return {string} The transformed string.\n */\n transform(obj: any, path: DisplayOptionItem[]): string {\n let result: string = '';\n\n path?.forEach((item: DisplayOptionItem): void => {\n if (item?.type === DisplayOptionItemType.DIVIDER) {\n result += item?.divider;\n } else {\n if (item?.path) {\n result += UtilsService.resolvePropertyByPath(obj, item.path);\n }\n }\n });\n\n return result;\n }\n}\n","import { CommonModule } from \"@angular/common\";\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n EventEmitter,\n forwardRef,\n Input,\n NgZone,\n Output,\n signal,\n TemplateRef,\n ViewChild,\n WritableSignal,\n} from \"@angular/core\";\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALUE_ACCESSOR,\n ReactiveFormsModule,\n UntypedFormControl,\n ValidationErrors,\n ValidatorFn,\n Validators,\n} from \"@angular/forms\";\nimport {\n MatAutocomplete,\n MatAutocompleteModule,\n MatAutocompleteTrigger,\n} from \"@angular/material/autocomplete\";\nimport { MatButtonModule } from \"@angular/material/button\";\nimport { ThemePalette } from \"@angular/material/core\";\nimport {\n FloatLabelType,\n MatFormFieldAppearance,\n MatFormFieldModule,\n SubscriptSizing,\n} from \"@angular/material/form-field\";\nimport { MatIconModule } from \"@angular/material/icon\";\nimport { MatInputModule } from \"@angular/material/input\";\nimport { MatProgressSpinnerModule } from \"@angular/material/progress-spinner\";\nimport { TranslateModule, TranslateService } from \"@ngx-translate/core\";\nimport {\n debounceTime,\n finalize,\n Observable,\n Subject,\n from,\n switchMap,\n tap,\n} from \"rxjs\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\n\nimport {\n ApiFormData,\n AutocompleteService,\n DisplayOption,\n DisplayOptionItemType,\n I18nPipe,\n RestrictionFilter,\n} from \"@guajiritos/services\";\n\nimport {\n GENERAL_DISPLAY_OPTIONS,\n ServiceConfig,\n} from \"../utils/constants/constants\";\nimport { ResolvePropertyPath } from \"../utils/pipes/resolve-property-path.pipe\";\nimport { UtilsService } from \"../utils/services/utils.service\";\n\n@Component({\n selector: \"guajiritos-general-autocomplete\",\n templateUrl: \"./guachos-general-autocomplete.component.html\",\n styleUrls: [\"./guachos-general-autocomplete.component.scss\"],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n CommonModule,\n MatFormFieldModule,\n TranslateModule,\n MatIconModule,\n ReactiveFormsModule,\n MatInputModule,\n MatButtonModule,\n MatProgressSpinnerModule,\n MatAutocompleteModule,\n I18nPipe,\n ResolvePropertyPath,\n ],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => GuajiritosGeneralAutocomplete),\n multi: true,\n },\n ],\n})\nexport class GuajiritosGeneralAutocomplete\n implements ControlValueAccessor, AfterViewInit\n{\n constructor(\n private _autocompleteService: AutocompleteService,\n private _zone: NgZone,\n private _destroyRef: DestroyRef,\n public translateService: TranslateService,\n ) {}\n\n // --- Private Properties ---\n // Indica si la última actualización del input fue por una selección explícita desde el autocomplete\n private _isOptionSelected: boolean = false;\n private _clearDataSubject: Subject<void> = new Subject<void>();\n private _doFocusSubject: Subject<void> = new Subject<void>();\n private _selectedElement: any = null; // Almacena el objeto completo seleccionado\n private _url: string | null = null;\n private _limit: number = 20;\n private _offset: number = 0;\n private _restrictionsFilters: RestrictionFilter[] = [];\n private _lastSearchText: string = \"\"; // Almacena el texto usado en la última búsqueda de API\n\n // --- Public Signals ---\n public disabled: WritableSignal<boolean> = signal(false);\n public loading: WritableSignal<boolean> = signal(false);\n public required: WritableSignal<boolean> = signal(false);\n public filteredOptions: WritableSignal<any[]> = signal([]);\n public originalOptions: WritableSignal<any[]> = signal([]);\n public notAllowedOption: WritableSignal<any> = signal(null);\n public component: UntypedFormControl = new UntypedFormControl({\n value: null,\n disabled: false,\n });\n public hasMore: WritableSignal<boolean> = signal(true); // Indica si hay más datos para cargar\n\n // --- ViewChildren ---\n @ViewChild(\"inputText\", { static: true }) inputText!: ElementRef;\n @ViewChild(\"auto\") matAutocomplete!: MatAutocomplete;\n @ViewChild(MatAutocompleteTrigger)\n autocompleteTrigger!: MatAutocompleteTrigger;\n // --- Inputs ---\n @Input() floatLabel: FloatLabelType = \"auto\";\n @Input() color: ThemePalette = \"accent\";\n @Input() appearance: MatFormFieldAppearance = \"outline\";\n @Input() subscriptSizing: SubscriptSizing = \"dynamic\";\n @Input() bodyRequest?: ApiFormData;\n @Input() debounceTimeValue: number = 300;\n @Input() detailsTemplate?: TemplateRef<any>;\n @Input() label: string = \"Seleccione\";\n @Input() showLabel: boolean = true;\n @Input() placeholder: string = \"Seleccione un elemento\";\n @Input() field: string[] = [\"name\"];\n @Input() filterString: string[] | string = \"filter[$and][name][$like]\";\n @Input() displayOptions: DisplayOption = GENERAL_DISPLAY_OPTIONS;\n @Input() withoutPaddingBottom: boolean = true;\n @Input() valueId: boolean = false;\n @Input() showSuffix: boolean = false;\n @Input() requireSelection: boolean = false;\n @Input() order?: string;\n @Input() serviceConfig?: ServiceConfig;\n @Input() suffixIcon: string = \"search\";\n @Input() removeProperties: string[] = [];\n @Input() modifyResultFn: (options: any[]) => any[] = (options: any[]) =>\n options;\n\n // --- Outputs ---\n @Output() selectElement: EventEmitter<any> = new EventEmitter<any>();\n @Output() clearElement: EventEmitter<any> = new EventEmitter<any>();\n\n // --- Setters for Inputs ---\n @Input() set url(data: string) {\n if (data) {\n this._url = data;\n // Suscribirse a los cambios del componente una vez que la URL está disponible\n this.subscribeToComponentChanges();\n }\n }\n\n @Input() set limit(value: number) {\n if (value && !isNaN(value)) {\n this._limit = value;\n }\n }\n\n @Input() set clearData(value: Subject<void>) {\n this._clearDataSubject = value;\n this._clearDataSubject\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe({\n next: (): void => {\n this.resetAutocompleteState();\n this.component.setValue(null, { emitEvent: false }); // No emitir para evitar ciclo de valueChanges\n this.propagateChange(null);\n this.selectElement.emit(null);\n },\n });\n }\n\n @Input() set initialValue(value: any) {\n // Si el valor inicial es el mismo que el valor actual del control, no hacer nada para evitar bucles\n if (value === this.component.value) {\n return;\n }\n\n this._selectedElement = value;\n this._isOptionSelected = !!value; // Marcar como seleccionado si hay un valor inicial\n\n // Establecer el valor en el formControl sin emitir el evento\n // para evitar que subscribeToComponentChanges reaccione a esta carga inicial.\n this.component.setValue(value, { emitEvent: false });\n\n // Actualizar _lastSearchText basado en el valor inicial\n if (value) {\n this._lastSearchText = this.displayFn(value);\n console.log(\"initialValue set: _lastSearchText =\", this._lastSearchText);\n } else {\n this._lastSearchText = \"\";\n }\n }\n\n /**\n * Adds or removes search restrictions\n */\n @Input() set restrictions(restrictions: RestrictionFilter[]) {\n this._restrictionsFilters = restrictions?.length ? [...restrictions] : [];\n this.resetAutocompleteState();\n // Re-ejecutar búsqueda si el input tiene texto y hay restricciones\n const currentSearchText = this.getAutocompleteSearchText();\n if (currentSearchText) {\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n\n /**\n * Adds or removes required validation\n */\n @Input() set isRequired(required: boolean) {\n this.required.set(required);\n const validators: ValidatorFn[] = [autocompleteValidator];\n if (required) {\n validators.push(Validators.required);\n }\n this.component.setValidators(validators);\n this.component.updateValueAndValidity();\n }\n\n /**\n * Defines whether to perform a search when the element is in focus\n */\n @Input() set doFocus(focusSubject: Subject<void>) {\n this._doFocusSubject = focusSubject;\n this._doFocusSubject\n .pipe(\n debounceTime(this.debounceTimeValue), // Retrasar para evitar llamadas excesivas\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (): void => {\n this._zone.run((): void => {\n setTimeout((): void => {\n this.inputText?.nativeElement?.focus();\n // Forzar la apertura del panel y una posible carga si es necesario\n // Simular input para disparar valueChanges, lo que a menudo abre el panel si el texto cambia\n (\n this.inputText?.nativeElement as HTMLInputElement\n )?.dispatchEvent(new Event(\"input\"));\n // Abrir explícitamente el panel usando el MatAutocompleteTrigger\n this.autocompleteTrigger?.openPanel(); // <--- EL CAMBIO ES AQUÍ\n }, 50); // Un pequeño retraso para asegurar el foco y la apertura\n });\n },\n });\n }\n\n @Input() set notAllowedElements(element: any) {\n if (element) {\n this.notAllowedOption.set(element);\n this.filterOptionsBasedOnNotAllowed();\n }\n }\n\n /**\n * Resets the autocomplete pagination and options state.\n * Centralizes the logic to avoid duplication.\n */\n private resetAutocompleteState(): void {\n this._offset = 0;\n this.originalOptions.set([]);\n this.filteredOptions.set([]);\n this.hasMore.set(true);\n // IMPORTANTE: _selectedElement NO se resetea aquí, solo si se borra explícitamente\n // _lastSearchText se actualiza en writeValue y optionSelected\n console.log(\"Autocomplete state reset (pagination/options).\");\n }\n\n /**\n * Subscription to search input changes\n */\n private subscribeToComponentChanges(): void {\n this.component.valueChanges\n .pipe(\n // Utiliza tap para observar el valor antes del debounce y el switchMap\n tap((value) => {\n // Si el cambio viene de una selección programática (e.g., this.component.setValue(obj))\n // O de una selección del usuario en el autocomplete, marcamos que no necesitamos buscar.\n if (\n typeof value === \"object\" &&\n value !== null &&\n this._isOptionSelected\n ) {\n console.log(\n \"Value change detected: Object selected, skipping search.\",\n );\n // Resetear la bandera después de procesar\n this._isOptionSelected = false;\n return; // Salir del tap, el debounce/switchMap no se ejecutará para este valor.\n }\n }),\n debounceTime(this.debounceTimeValue),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (value: any): void => {\n const currentSearchText = this.getAutocompleteSearchText();\n\n // Si el valor actual es un objeto (ya seleccionado), no necesitamos buscar\n // A menos que el texto en el input haya sido modificado por el usuario\n if (typeof value === \"object\" && value !== null) {\n const displayText = this.displayFn(value);\n if (\n currentSearchText === displayText &&\n this._selectedElement === value\n ) {\n console.log(\n \"Value is selected object and matches display text, skipping search.\",\n );\n return;\n }\n }\n\n // Si el valor del input es un string (el usuario está escribiendo o borró)\n // Y el texto actual es diferente al último texto buscado\n // O si el texto está vacío (para cargar las opciones iniciales si se borra)\n if (\n (typeof value === \"string\" &&\n currentSearchText !== this._lastSearchText) ||\n (currentSearchText === \"\" && this._lastSearchText !== \"\") // Para cuando el usuario borra todo\n ) {\n this.resetAutocompleteState(); // Reiniciar paginación y opciones\n this._lastSearchText = currentSearchText; // Actualizar el último texto buscado\n console.log(\n \"Value changed, initiating new search for:\",\n currentSearchText,\n );\n this.getAutocompleteByTextHandler(currentSearchText);\n } else if (currentSearchText === \"\" && this._lastSearchText === \"\") {\n // Si el input está vacío y ya lo estaba, y el componente no tiene valor seleccionado,\n // podría ser un buen momento para recargar las opciones iniciales si el panel está abierto\n if (\n this.matAutocomplete._isOpen &&\n this.originalOptions().length === 0 &&\n !this.loading()\n ) {\n console.log(\n \"Input empty, no options, panel open. Loading initial set.\",\n );\n this.getAutocompleteByTextHandler(\"\");\n }\n }\n },\n });\n }\n\n ngAfterViewInit(): void {\n // Suscribirse a la apertura del panel para añadir el listener de scroll\n this.matAutocomplete.opened\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n if (this.matAutocomplete?.panel) {\n // Asegurarse de que el listener sea removido antes de añadirlo para prevenir duplicados\n this.matAutocomplete.panel.nativeElement.removeEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n this.matAutocomplete.panel.nativeElement.addEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n\n // Si el panel se abre y no hay opciones cargadas, o si el input está vacío\n // y no hay una selección activa, cargar las opciones iniciales.\n const currentSearchText = this.getAutocompleteSearchText();\n if (\n this.originalOptions().length === 0 ||\n (!this._selectedElement && currentSearchText === \"\")\n ) {\n console.log(\"Panel opened, loading initial set of options.\");\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n });\n\n // Suscribirse al cierre del panel para remover el listener de scroll y manejar la deselección\n this.matAutocomplete.closed\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n if (this.matAutocomplete?.panel) {\n this.matAutocomplete.panel.nativeElement.removeEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n }\n\n const currentInputValue = this.component.value;\n const currentInputText = this.getAutocompleteSearchText();\n\n console.log(\n \"Autocomplete closed. Current Input Value:\",\n currentInputValue,\n \"Selected Element:\",\n this._selectedElement,\n \"Current Input Text:\",\n currentInputText,\n );\n\n // Lógica para manejar el borrado del input si no hay una selección válida\n // o si el texto no coincide con el elemento seleccionado.\n if (typeof currentInputValue === \"string\") {\n // Si el valor del input es un string (el usuario está escribiendo o ha modificado)\n if (this.requireSelection) {\n // Si se requiere selección y el texto no coincide con un elemento seleccionado,\n // o no hay ningún elemento seleccionado, entonces se borra.\n if (\n !this._selectedElement ||\n currentInputText !== this.displayFn(this._selectedElement)\n ) {\n console.warn(\n \"Autocomplete closed: Input cleared because selection is required and no valid match found.\",\n );\n this.clearInternalState(); // Usa un método para limpiar\n }\n } else {\n // Si NO se requiere selección, pero el usuario ha editado el texto de un elemento previamente seleccionado.\n // En este caso, NO borramos, sino que revertimos al texto del elemento seleccionado si existe.\n if (\n this._selectedElement &&\n currentInputText !== this.displayFn(this._selectedElement)\n ) {\n console.log(\n \"Autocomplete closed: Text edited for a selected item, reverting to original.\",\n );\n // Revertir al texto del elemento seleccionado.\n this.component.setValue(this._selectedElement, {\n emitEvent: false,\n });\n this._lastSearchText = this.displayFn(this._selectedElement);\n this.propagateChange(this._selectedElement); // Propagar el valor original si se revierte\n } else if (currentInputText === \"\" && this._selectedElement) {\n // Si el input está vacío pero había un elemento seleccionado, deseleccionar\n console.log(\n \"Autocomplete closed: Input cleared by user, deselecting element.\",\n );\n this.clearInternalState();\n } else if (currentInputText === \"\" && !this._selectedElement) {\n // Si el input está vacío y no había selección, simplemente asegúrate de que el estado interno refleje esto.\n console.log(\"Autocomplete closed: Input empty, no selection.\");\n this.clearInternalState(); // Asegura el estado\n }\n // Si el texto del input es un string y no se requiere selección,\n // y no hay _selectedElement, asumimos que el usuario quiere el texto libre.\n // No hacemos nada, el texto permanece.\n if (\n typeof currentInputValue === \"string\" &&\n !this.requireSelection &&\n !this._selectedElement\n ) {\n // Si no hay un elemento seleccionado pero el usuario escribió algo\n // y no se requiere selección, dejamos el texto tal cual.\n // Aseguramos que _lastSearchText se actualice para evitar re-búsquedas innecesarias.\n this._lastSearchText = currentInputText;\n this.propagateChange(currentInputText);\n }\n }\n }\n // Si el valor ya es un objeto (porque se seleccionó), no hacemos nada aquí\n // a menos que el usuario haya borrado manualmente el texto del input.\n // Esa última parte se cubre con la condición currentInputText === \"\"\n });\n }\n\n /**\n * Helper method to clear the internal state of the autocomplete.\n */\n private clearInternalState(): void {\n this.component.setValue(null, { emitEvent: false }); // Evitar bucle con valueChanges\n this.propagateChange(null);\n this.selectElement.emit(null);\n this._selectedElement = null;\n this._lastSearchText = \"\";\n this.resetAutocompleteState(); // Resetear opciones y paginación\n console.log(\"Internal autocomplete state cleared.\");\n }\n\n /**\n * Searches for elements to display in the autocomplete component.\n * Now supports pagination.\n * @param text - Text to search\n */\n private getAutocompleteByTextHandler(text?: string): void {\n // Si no hay más datos Y ya cargamos algo (offset > 0) Y el texto de búsqueda no ha cambiado,\n // y no estamos actualmente cargando, salir.\n if (\n !this.hasMore() &&\n this._offset > 0 &&\n text === this._lastSearchText && // Verificar que el texto de búsqueda actual sea el mismo\n !this.loading()\n ) {\n console.log(\n \"No more data for current search text, stopping further loads.\",\n );\n return;\n }\n\n if (this.loading()) {\n console.log(\"Already loading, exiting getAutocompleteByTextHandler.\");\n return;\n }\n\n this.loading.set(true);\n\n const currentOffset = this._offset; // Capturar el offset actual antes de la llamada\n const currentSearchTextForApi = text; // Usar el texto pasado, no el global _lastSearchText\n\n if (!this._url && !this.serviceConfig) {\n console.warn(\"Autocomplete: 'url' or 'serviceConfig' input is required.\");\n this.loading.set(false);\n this.hasMore.set(false);\n return;\n }\n\n let apiCall: Observable<any>;\n\n if (this._url) {\n apiCall = from(\n this._autocompleteService.getAutocompleteByText(\n this._url,\n currentSearchTextForApi, // Usar el texto de búsqueda actual\n this.filterString,\n this._restrictionsFilters,\n this.removeProperties,\n this.order,\n this.bodyRequest,\n { limit: this._limit, offset: currentOffset },\n ),\n ).pipe(switchMap((innerObservable) => innerObservable));\n } else if (this.serviceConfig) {\n let body: any = { ...this.serviceConfig };\n body[this.serviceConfig.searchProperty] = currentSearchTextForApi; // Usar el texto de búsqueda actual\n body[\"limit\"] = this._limit;\n body[\"offset\"] = currentOffset;\n apiCall = this.serviceConfig.service[this.serviceConfig.method](body);\n } else {\n this.loading.set(false);\n this.hasMore.set(false);\n return;\n }\n\n // Guardar la posición de scroll antes de la actualización\n let panelScrollTop = 0;\n if (this.matAutocomplete?.panel) {\n panelScrollTop = this.matAutocomplete.panel.nativeElement.scrollTop;\n }\n\n apiCall\n .pipe(\n finalize((): void => {\n this.loading.set(false);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (result: any): void => {\n const newData = result?.payload?.data ?? result?.data ?? [];\n console.log(\n \"New Data received:\",\n newData.length,\n \"items. Current offset before update:\",\n this._offset,\n );\n\n this._offset += newData.length; // Actualizar offset con la cantidad de nuevos ítems\n\n if (newData.length < this._limit) {\n this.hasMore.set(false);\n console.log(\"No more data, hasMore = false\");\n } else {\n this.hasMore.set(true);\n console.log(\"Potentially more data, hasMore = true\");\n }\n\n // Actualizar las opciones originales\n this.originalOptions.update((currentOptions) => {\n const updatedOptions = [...currentOptions, ...newData];\n console.log(\"Total options after merge:\", updatedOptions.length);\n return updatedOptions;\n });\n this.filterOptionsBasedOnNotAllowed();\n\n // Restaurar la posición de scroll después de que Angular haya actualizado el DOM\n // Esto debe hacerse fuera de la zona de Angular o con un pequeño retardo.\n if (this.matAutocomplete?.panel && panelScrollTop > 0) {\n this._zone.runOutsideAngular(() => {\n setTimeout(() => {\n this.matAutocomplete.panel.nativeElement.scrollTop =\n panelScrollTop;\n console.log(\"Scroll position restored to:\", panelScrollTop);\n }, 0); // Un pequeño retardo para asegurar que el DOM se haya renderizado\n });\n }\n },\n error: (error) => {\n console.error(\"Error fetching autocomplete data:\", error);\n this.loading.set(false);\n this.hasMore.set(false);\n },\n });\n }\n\n private filterOptionsBasedOnNotAllowed(): void {\n let currentOptions = this.originalOptions();\n const modifiedOptions = this.modifyResultFn(currentOptions);\n if (modifiedOptions !== null && modifiedOptions !== undefined) {\n currentOptions = modifiedOptions;\n }\n\n if (this.notAllowedOption()) {\n this.filteredOptions.set(\n currentOptions.filter(\n (option: any): boolean =>\n JSON.stringify(option) !== JSON.stringify(this.notAllowedOption()),\n ),\n );\n } else {\n this.filteredOptions.set(currentOptions);\n }\n }\n\n /**\n * Defines the text to be used for the search\n */\n private getAutocompleteSearchText(): string {\n const value = this.component.value;\n if (typeof value === \"object\" && value !== null) {\n // Si el valor es un objeto, usa displayFn para obtener el texto\n return this.displayFn(value);\n } else if (typeof value === \"string\") {\n return value;\n }\n return \"\";\n }\n\n // --- ControlValueAccessor methods ---\n propagateChange = (_: any): void => {};\n\n registerOnChange(fn: (_: any) => void): void {\n this.propagateChange = fn;\n }\n\n registerOnTouched(): void {}\n\n /**\n * Recibe el valor desde el FormControl externo.\n */\n writeValue(value: any): void {\n // Establecer la bandera para indicar que el cambio viene de un setValue programático\n this._isOptionSelected = typeof value === \"object\" && value !== null;\n this.component.setValue(value, { emitEvent: false }); // No emitir evento para evitar bucles.\n\n this._selectedElement = value\n ? this.valueId && typeof value === \"object\"\n ? value?.id\n : value\n : null;\n\n // Actualizar _lastSearchText basado en el valor que se está escribiendo.\n if (value) {\n this._lastSearchText = this.displayFn(value);\n console.log(\"writeValue: Last search text set to:\", this._lastSearchText);\n } else {\n this._lastSearchText = \"\";\n console.log(\"writeValue: Last search text cleared.\");\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n if (isDisabled) {\n this.component.disable();\n } else {\n this.component.enable();\n }\n }\n\n /**\n * Function to display selected elements\n */\n public displayFn = (value: any): string => {\n if (!value) {\n return \"\";\n }\n // Si el valor ya es una cadena, devuélvelo directamente\n if (typeof value === \"string\") {\n return value;\n }\n\n let displayText: string = \"\";\n const options = this.displayOptions || GENERAL_DISPLAY_OPTIONS;\n\n options?.firthLabel?.forEach((field: any): void => {\n if (field?.type === DisplayOptionItemType.PATH) {\n displayText +=\n UtilsService.resolvePropertyByPath(value, field?.path) || \"\";\n } else {\n displayText += field?.divider || \"\";\n }\n });\n\n return displayText;\n };\n\n /**\n * Action on clearing the input value\n */\n public clear(trigger: MatAutocompleteTrigger): void {\n this.clearElement.emit(this.component.value);\n this.clearInternalState(); // Usa el método auxiliar para limpiar\n // this.component.setValue(null); // Ya se llama dentro de clearInternalState\n // this.propagateChange(null);\n // this.selectElement.emit(null);\n // this._selectedElement = null;\n // this._lastSearchText = \"\";\n\n this._zone.run((): void => {\n setTimeout((): void => {\n trigger.openPanel(); // Reabrir el panel después de borrar\n this.getAutocompleteByTextHandler(\"\"); // Cargar opciones iniciales (o todas) después de borrar\n }, 100);\n });\n }\n\n /**\n * Action on element Focus\n */\n public onFocus(): void {\n const currentSearchText = this.getAutocompleteSearchText();\n // Si no hay opciones cargadas O el input está vacío y no hay un elemento seleccionado\n if (\n this.originalOptions().length === 0 ||\n (currentSearchText === \"\" && !this._selectedElement)\n ) {\n this.resetAutocompleteState(); // Reiniciar estado antes de una nueva búsqueda\n this._lastSearchText = currentSearchText;\n console.log(\"On focus, initiating search for:\", currentSearchText);\n this.getAutocompleteByTextHandler(currentSearchText);\n } else if (\n this.matAutocomplete._isOpen &&\n currentSearchText === this._lastSearchText\n ) {\n // Si el panel ya está abierto y el texto no ha cambiado, no hacer nada para evitar re-cargas innecesarias.\n // Si el panel no estaba abierto, la apertura de `matAutocomplete.opened` se encargará de la carga.\n console.log(\n \"On focus, panel already open with same text, skipping search.\",\n );\n }\n }\n\n public optionSelected($event: any): void {\n const selectedValue = $event?.option?.value;\n if (selectedValue) {\n this._isOptionSelected = true; // Establecer la bandera de selección\n this._selectedElement = selectedValue;\n this.selectElement.emit(selectedValue);\n\n if (this.valueId && typeof selectedValue === \"object\") {\n this.propagateChange(selectedValue?.id);\n } else {\n this.propagateChange(selectedValue);\n }\n // Cuando un ítem es seleccionado, actualizar _lastSearchText con su valor de display.\n // Esto es crucial para que el valueChanges no vuelva a disparar una búsqueda para este valor.\n this._lastSearchText = this.displayFn(selectedValue);\n console.log(\n \"Option selected. Last search text set to:\",\n this._lastSearchText,\n );\n } else {\n // Si se deselecciona o selecciona nulo\n // Esto rara vez debería ocurrir si se selecciona una opción válida, pero es un fallback.\n console.log(\"Option selected is null or undefined, clearing state.\");\n this.clearInternalState();\n }\n // Después de la selección, el panel se cierra automáticamente en la mayoría de los casos de MatAutocomplete.\n // this.matAutocomplete.closePanel(); // Descomentar si el panel no se cierra automáticamente\n }\n\n /**\n * Handles the scroll event in the autocomplete panel to load more data.\n */\n onScroll(event: Event): void {\n const element = event.target as HTMLElement;\n const scrollPosition = element.scrollTop + element.clientHeight;\n const scrollHeight = element.scrollHeight;\n const threshold = 50; // Pixels before the end to load more\n\n // console.log(\"--- Scroll Event ---\");\n // console.log(\"Scroll Top:\", element.scrollTop);\n // console.log(\"Client Height:\", element.clientHeight);\n // console.log(\"Scroll Position (Top + Client):\", scrollPosition);\n // console.log(\"Scroll Height (Total):\", scrollHeight);\n // console.log(\"Remaining distance to bottom:\", scrollHeight - scrollPosition);\n // console.log(\"Is Loading:\", this.loading());\n // console.log(\"Has More:\", this.hasMore());\n\n if (\n scrollHeight - scrollPosition <= threshold &&\n !this.loading() &&\n this.hasMore()\n ) {\n console.log(\"Loading more data for infinity scroll...\");\n // Usar el texto de búsqueda actual (que puede ser el texto del ítem seleccionado o lo que el usuario escribió)\n this.getAutocompleteByTextHandler(this.getAutocompleteSearchText());\n }\n }\n}\n\n/**\n * Custom validation for element selection\n */\nexport function autocompleteValidator(\n control: AbstractControl,\n): ValidationErrors | null {\n // Un valor válido es un objeto no nulo que tiene una propiedad 'id'.\n // Esto asegura que realmente se ha seleccionado un objeto del autocomplete, no solo texto libre.\n if (\n typeof control?.value === \"object\" &&\n control?.value !== null &&\n \"id\" in control.value\n ) {\n return null;\n }\n return { invalidSelection: true };\n}\n","<mat-form-field [floatLabel]=\"floatLabel\" class=\"w-100\" [appearance]=\"appearance\" [color]=\"color\"\n [subscriptSizing]=\"subscriptSizing\">\n\n @if (showLabel) {\n <mat-label>{{ label | translate }}</mat-label>\n }\n @if (showSuffix) {\n <mat-icon matSuffix>{{ suffixIcon ?? \"search\" }}</mat-icon>\n }\n <input #inputText #trigger=\"matAutocompleteTrigger\" (focus)=\"onFocus()\" [formControl]=\"component\" type=\"text\"\n [matAutocomplete]=\"auto\" [placeholder]=\"placeholder | translate\" aria-label=\"autocomplete\"\n autocomplete=\"off\" matInput [required]=\"required()\">\n @if (!loading() && component.value) {\n <button (click)=\"clear(trigger)\" [disabled]=\"disabled()\"\n aria-label=\"Clear\" mat-icon-button matSuffix>\n <mat-icon>close</mat-icon>\n </button>\n }\n @if (loading()) {\n <button aria-label=\"search\" mat-icon-button matSuffix>\n <mat-spinner [value]=\"90\" color=\"accent\" diameter=\"25\"></mat-spinner>\n </button>\n }\n <mat-autocomplete #auto=\"matAutocomplete\" [displayWith]=\"displayFn\" [requireSelection]=\"requireSelection\"\n (optionSelected)=\"optionSelected($event)\">\n @for (option of filteredOptions(); track option) {\n <mat-option [value]=\"option\">\n @if (!displayOptions && !detailsTemplate) {\n {{ option?.name | i18n: translateService.currentLang }}\n }\n @if (!detailsTemplate) {\n <div class=\"display-options\">\n <span [ngStyle]=\"{'line-height': displayOptions?.secondLabel ? '16px' : ''}\">\n {{ option | resolvePropertyPath:displayOptions.firthLabel | i18n: translateService.currentLang }}\n </span>\n @if (displayOptions?.secondLabel) {\n <span class=\"mat-caption\">\n {{ option | resolvePropertyPath: displayOptions.secondLabel | i18n: translateService.currentLang }}\n </span>\n }\n </div>\n }\n @if (detailsTemplate) {\n <ng-container *ngTemplateOutlet=\"detailsTemplate;context:{$implicit: option }\"></ng-container>\n }\n </mat-option>\n }\n </mat-autocomplete>\n\n @if (component.invalid) {\n <mat-error>\n {{ 'Este campo es requerido.' | translate }}\n </mat-error>\n }\n</mat-form-field>\n","/*\n * Public API Surface of guachos-general-autocomplete\n */\n\nexport * from './utils/constants/constants';\nexport * from './lib/guachos-general-autocomplete.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"guajiritos-general-autocomplete.mjs","sources":["../../../projects/guachos-general-autocomplete/src/utils/constants/constants.ts","../../../projects/guachos-general-autocomplete/src/utils/services/utils.service.ts","../../../projects/guachos-general-autocomplete/src/utils/pipes/resolve-property-path.pipe.ts","../../../projects/guachos-general-autocomplete/src/lib/guachos-general-autocomplete.component.ts","../../../projects/guachos-general-autocomplete/src/lib/guachos-general-autocomplete.component.html","../../../projects/guachos-general-autocomplete/src/public-api.ts","../../../projects/guachos-general-autocomplete/src/guajiritos-general-autocomplete.ts"],"sourcesContent":["import { DisplayOption, DisplayOptionItemType } from '@guajiritos/services';\nimport {DisplayOptionItem} from \"@guajiritos/services/lib/interfaces/interfaces\";\n\n\nexport const GENERAL_DISPLAY_OPTIONS: DisplayOption = {\n firthLabel: [\n {\n type: DisplayOptionItemType.PATH,\n path: ['name']\n }\n ],\n applyTranslate: true\n};\n\nexport interface ServiceConfig {\n service: any;\n method: string;\n postBody: any;\n searchProperty: string;\n}\n","import {Injectable} from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class UtilsService {\n /**\n * Resolves the value of a property in an object by providing a path.\n *\n * @param {any} obj - The object to traverse.\n * @param {string[]} path - An array of strings representing the path to the desired property.\n * @return {any} The value of the property at the given path, or null if the path is invalid.\n */\n public static resolvePropertyByPath(obj: any, path: string[]): any {\n return path.reduce((prev, curr: string) => {\n return prev ? prev[curr] : null;\n }, obj || self);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { DisplayOptionItem, DisplayOptionItemType } from '@guajiritos/services';\n\nimport { UtilsService } from '../services/utils.service';\n\n@Pipe({\n name: 'resolvePropertyPath',\n standalone: true\n})\nexport class ResolvePropertyPath implements PipeTransform {\n /**\n * Transforms the given object based on the provided path and returns the transformed string.\n *\n * @param {any} obj - The object to be transformed.\n * @param {DisplayOptionItem[]} path - The array of display option items used for transformation.\n * @return {string} The transformed string.\n */\n transform(obj: any, path: DisplayOptionItem[]): string {\n let result: string = '';\n\n path?.forEach((item: DisplayOptionItem): void => {\n if (item?.type === DisplayOptionItemType.DIVIDER) {\n result += item?.divider;\n } else {\n if (item?.path) {\n result += UtilsService.resolvePropertyByPath(obj, item.path);\n }\n }\n });\n\n return result;\n }\n}\n","import { CommonModule } from \"@angular/common\";\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n EventEmitter,\n forwardRef,\n Input,\n NgZone,\n Output,\n signal,\n TemplateRef,\n ViewChild,\n WritableSignal,\n} from \"@angular/core\";\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALUE_ACCESSOR,\n ReactiveFormsModule,\n UntypedFormControl,\n ValidationErrors,\n ValidatorFn,\n Validators,\n} from \"@angular/forms\";\nimport {\n MatAutocomplete,\n MatAutocompleteModule,\n MatAutocompleteTrigger,\n} from \"@angular/material/autocomplete\";\nimport { MatButtonModule } from \"@angular/material/button\";\nimport { ThemePalette } from \"@angular/material/core\";\nimport {\n FloatLabelType,\n MatFormFieldAppearance,\n MatFormFieldModule,\n SubscriptSizing,\n} from \"@angular/material/form-field\";\nimport { MatIconModule } from \"@angular/material/icon\";\nimport { MatInputModule } from \"@angular/material/input\";\nimport { MatProgressSpinnerModule } from \"@angular/material/progress-spinner\";\nimport { TranslateModule, TranslateService } from \"@ngx-translate/core\";\nimport {\n debounceTime,\n finalize,\n Observable,\n Subject,\n from,\n switchMap,\n tap,\n} from \"rxjs\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\n\nimport {\n ApiFormData,\n AutocompleteService,\n DisplayOption,\n DisplayOptionItemType,\n I18nPipe,\n RestrictionFilter,\n} from \"@guajiritos/services\";\n\nimport {\n GENERAL_DISPLAY_OPTIONS,\n ServiceConfig,\n} from \"../utils/constants/constants\";\nimport { ResolvePropertyPath } from \"../utils/pipes/resolve-property-path.pipe\";\nimport { UtilsService } from \"../utils/services/utils.service\";\n\n@Component({\n selector: \"guajiritos-general-autocomplete\",\n templateUrl: \"./guachos-general-autocomplete.component.html\",\n styleUrls: [\"./guachos-general-autocomplete.component.scss\"],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n CommonModule,\n MatFormFieldModule,\n TranslateModule,\n MatIconModule,\n ReactiveFormsModule,\n MatInputModule,\n MatButtonModule,\n MatProgressSpinnerModule,\n MatAutocompleteModule,\n I18nPipe,\n ResolvePropertyPath,\n ],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => GuajiritosGeneralAutocomplete),\n multi: true,\n },\n ],\n})\nexport class GuajiritosGeneralAutocomplete\n implements ControlValueAccessor, AfterViewInit\n{\n constructor(\n private _autocompleteService: AutocompleteService,\n private _zone: NgZone,\n private _destroyRef: DestroyRef,\n public translateService: TranslateService,\n ) {}\n\n // --- Private Properties ---\n // Indica si la última actualización del input fue por una selección explícita desde el autocomplete\n private _isOptionSelected: boolean = false;\n private _clearDataSubject: Subject<void> = new Subject<void>();\n private _doFocusSubject: Subject<void> = new Subject<void>();\n private _selectedElement: any = null; // Almacena el objeto completo seleccionado\n private _url: string | null = null;\n private _limit: number = 20;\n private _offset: number = 0;\n private _restrictionsFilters: RestrictionFilter[] = [];\n private _lastSearchText: string = \"\"; // Almacena el texto usado en la última búsqueda de API\n\n // --- Public Signals ---\n public disabled: WritableSignal<boolean> = signal(false);\n public loading: WritableSignal<boolean> = signal(false);\n public required: WritableSignal<boolean> = signal(false);\n public filteredOptions: WritableSignal<any[]> = signal([]);\n public originalOptions: WritableSignal<any[]> = signal([]);\n public notAllowedOption: WritableSignal<any> = signal(null);\n public component: UntypedFormControl = new UntypedFormControl({\n value: null,\n disabled: false,\n });\n public hasMore: WritableSignal<boolean> = signal(true); // Indica si hay más datos para cargar\n\n // --- ViewChildren ---\n @ViewChild(\"inputText\", { static: true }) inputText!: ElementRef;\n @ViewChild(\"auto\") matAutocomplete!: MatAutocomplete;\n @ViewChild(MatAutocompleteTrigger)\n autocompleteTrigger!: MatAutocompleteTrigger;\n // --- Inputs ---\n @Input() floatLabel: FloatLabelType = \"auto\";\n @Input() color: ThemePalette = \"accent\";\n @Input() appearance: MatFormFieldAppearance = \"outline\";\n @Input() subscriptSizing: SubscriptSizing = \"dynamic\";\n @Input() bodyRequest?: ApiFormData;\n @Input() debounceTimeValue: number = 300;\n @Input() detailsTemplate?: TemplateRef<any>;\n @Input() label: string = \"Seleccione\";\n @Input() showLabel: boolean = true;\n @Input() placeholder: string = \"Seleccione un elemento\";\n @Input() field: string[] = [\"name\"];\n @Input() filterString: string[] | string = \"filter[$and][name][$like]\";\n @Input() displayOptions: DisplayOption = GENERAL_DISPLAY_OPTIONS;\n @Input() withoutPaddingBottom: boolean = true;\n @Input() valueId: boolean = false;\n @Input() showSuffix: boolean = false;\n @Input() requireSelection: boolean = false;\n @Input() order?: string;\n @Input() serviceConfig?: ServiceConfig;\n @Input() suffixIcon: string = \"search\";\n @Input() removeProperties: string[] = [];\n @Input() modifyResultFn: (options: any[]) => any[] = (options: any[]) =>\n options;\n\n // --- Outputs ---\n @Output() selectElement: EventEmitter<any> = new EventEmitter<any>();\n @Output() clearElement: EventEmitter<any> = new EventEmitter<any>();\n\n // --- Setters for Inputs ---\n @Input() set url(data: string) {\n if (data) {\n this._url = data;\n // Suscribirse a los cambios del componente una vez que la URL está disponible\n this.subscribeToComponentChanges();\n }\n }\n\n @Input() set limit(value: number) {\n if (value && !isNaN(value)) {\n this._limit = value;\n }\n }\n\n @Input() set clearData(value: Subject<void>) {\n this._clearDataSubject = value;\n this._clearDataSubject\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe({\n next: (): void => {\n this.clearInternalState();\n // No es necesario llamar a setValue(null) o propagateChange(null) aquí\n // porque clearInternalState ya lo hace.\n },\n });\n }\n\n @Input() set initialValue(value: any) {\n // Si el valor inicial es el mismo que el valor actual del control, no hacer nada para evitar bucles\n if (value === this.component.value) {\n return;\n }\n\n this._selectedElement = value;\n this._isOptionSelected = !!value; // Marcar como seleccionado si hay un valor inicial\n\n // Establecer el valor en el formControl sin emitir el evento\n // para evitar que subscribeToComponentChanges reaccione a esta carga inicial.\n this.component.setValue(value, { emitEvent: false });\n\n // Actualizar _lastSearchText basado en el valor inicial\n if (value) {\n this._lastSearchText = this.displayFn(value);\n console.log(\"initialValue set: _lastSearchText =\", this._lastSearchText);\n } else {\n this._lastSearchText = \"\";\n }\n }\n\n /**\n * Adds or removes search restrictions\n */\n @Input() set restrictions(restrictions: RestrictionFilter[]) {\n this._restrictionsFilters = restrictions?.length ? [...restrictions] : [];\n this.resetAutocompleteState();\n // Re-ejecutar búsqueda si el input tiene texto y hay restricciones\n const currentSearchText = this.getAutocompleteSearchText();\n if (currentSearchText) {\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n\n /**\n * Adds or removes required validation\n */\n @Input() set isRequired(required: boolean) {\n this.required.set(required);\n const validators: ValidatorFn[] = [autocompleteValidator];\n if (required) {\n validators.push(Validators.required);\n }\n this.component.setValidators(validators);\n this.component.updateValueAndValidity();\n }\n\n /**\n * Defines whether to perform a search when the element is in focus\n */\n @Input() set doFocus(focusSubject: Subject<void>) {\n this._doFocusSubject = focusSubject;\n this._doFocusSubject\n .pipe(\n debounceTime(this.debounceTimeValue), // Retrasar para evitar llamadas excesivas\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (): void => {\n this._zone.run((): void => {\n setTimeout((): void => {\n this.inputText?.nativeElement?.focus();\n (\n this.inputText?.nativeElement as HTMLInputElement\n )?.dispatchEvent(new Event(\"input\")); // Simular input para disparar valueChanges\n this.autocompleteTrigger?.openPanel();\n }, 50); // Un pequeño retraso para asegurar el foco y la apertura\n });\n },\n });\n }\n\n @Input() set notAllowedElements(element: any) {\n if (element) {\n this.notAllowedOption.set(element);\n this.filterOptionsBasedOnNotAllowed();\n }\n }\n\n /**\n * Resets the autocomplete pagination and options state.\n * Centralizes the logic to avoid duplication.\n */\n private resetAutocompleteState(): void {\n this._offset = 0;\n this.originalOptions.set([]);\n this.filteredOptions.set([]);\n this.hasMore.set(true);\n console.log(\"Autocomplete state reset (pagination/options).\");\n }\n\n /**\n * Subscription to search input changes\n */\n private subscribeToComponentChanges(): void {\n this.component.valueChanges\n .pipe(\n // TAP se ejecuta inmediatamente ANTES del debounce.\n // Esto es crucial para detectar borrados de texto en tiempo real.\n tap((value) => {\n const currentInputText = this.getAutocompleteSearchText();\n\n // Si el valor actual del control es un STRING (usuario escribiendo/borrando)\n // Y previamente había un objeto seleccionado (_selectedElement)\n // Y el texto en el input ya no coincide con el displayFn del _selectedElement,\n // entonces desvinculamos el _selectedElement y marcamos que no hay selección.\n if (\n typeof value === \"string\" &&\n this._selectedElement &&\n currentInputText !== this.displayFn(this._selectedElement)\n ) {\n console.log(\n \"TAP: User is editing/clearing text of a selected item. Deselecting internally.\",\n );\n this._selectedElement = null; // Quitar la referencia al objeto seleccionado\n this._isOptionSelected = false; // Marcar que no hay una opción seleccionada\n // IMPORTANTE: NO LLAMAR a `this.propagateChange(null);` ni `this.component.setValue(null);` aquí.\n // Queremos que el texto escrito/borrado permanezca en el input.\n // La limpieza total (propagateChange(null)) ocurrirá después del debounce o al cerrar el panel.\n } else if (typeof value === \"string\") {\n // Si el valor es un string, simplemente marcamos que no hay opción seleccionada.\n // Esto cubre los casos donde el usuario escribe por primera vez o borra sin haber seleccionado.\n this._isOptionSelected = false;\n }\n }),\n debounceTime(this.debounceTimeValue), // El debounce se aplica después de la lógica del tap\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (value: any): void => {\n const currentSearchText = this.getAutocompleteSearchText();\n\n // Caso 1: El valor es un objeto y coincide con el elemento seleccionado.\n // Esto ocurre si el usuario seleccionó un elemento y el debounce pasó sin más ediciones.\n if (\n typeof value === \"object\" &&\n value !== null &&\n this._selectedElement === value\n ) {\n console.log(\n \"Value is selected object (after debounce), skipping search.\",\n );\n // Aseguramos que el _lastSearchText esté correcto para este objeto.\n this._lastSearchText = this.displayFn(value);\n return;\n }\n\n // Caso 2: El usuario ha terminado de escribir o borrar texto.\n // Si el texto actual ha cambiado con respecto al último buscado, o se ha vaciado.\n if (\n (typeof value === \"string\" &&\n currentSearchText !== this._lastSearchText) ||\n (currentSearchText === \"\" && this._lastSearchText !== \"\")\n ) {\n this.resetAutocompleteState(); // Reiniciar paginación y opciones\n this._lastSearchText = currentSearchText; // Actualizar el último texto buscado\n console.log(\n \"Value changed (after debounce), initiating new search for:\",\n currentSearchText,\n );\n this.getAutocompleteByTextHandler(currentSearchText);\n\n // Si _selectedElement es null (porque se desvinculó en el tap)\n // y el texto actual no es vacío, propagar el string.\n // Si es vacío y no hay selección, propagamos null.\n if (!this._selectedElement && currentSearchText !== \"\") {\n this.propagateChange(currentSearchText);\n } else if (!this._selectedElement && currentSearchText === \"\") {\n this.propagateChange(null);\n }\n } else if (currentSearchText === \"\" && this._lastSearchText === \"\") {\n // Si el input está vacío y ya lo estaba, y el panel está abierto sin opciones,\n // cargar las opciones iniciales.\n if (\n this.matAutocomplete._isOpen &&\n this.originalOptions().length === 0 &&\n !this.loading()\n ) {\n console.log(\n \"Input empty, no options, panel open. Loading initial set.\",\n );\n this.getAutocompleteByTextHandler(\"\");\n }\n }\n },\n });\n }\n\n ngAfterViewInit(): void {\n // Suscribirse a la apertura del panel para añadir el listener de scroll\n this.matAutocomplete.opened\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n if (this.matAutocomplete?.panel) {\n // Asegurarse de que el listener sea removido antes de añadirlo para prevenir duplicados\n this.matAutocomplete.panel.nativeElement.removeEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n this.matAutocomplete.panel.nativeElement.addEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n\n // Si el panel se abre y no hay opciones cargadas, o si el input está vacío\n // y no hay una selección activa, cargar las opciones iniciales.\n const currentSearchText = this.getAutocompleteSearchText();\n if (\n this.originalOptions().length === 0 ||\n (!this._selectedElement && currentSearchText === \"\")\n ) {\n console.log(\"Panel opened, loading initial set of options.\");\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n });\n\n // Suscribirse al cierre del panel para remover el listener de scroll y manejar la deselección\n this.matAutocomplete.closed\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n if (this.matAutocomplete?.panel) {\n this.matAutocomplete.panel.nativeElement.removeEventListener(\n \"scroll\",\n this.onScroll.bind(this),\n );\n }\n\n const currentInputValue = this.component.value;\n const currentInputText = this.getAutocompleteSearchText();\n\n console.log(\n \"Autocomplete closed. Current Input Value:\",\n currentInputValue,\n \"Selected Element:\",\n this._selectedElement,\n \"Current Input Text:\",\n currentInputText,\n );\n\n // Lógica para manejar el borrado del input si no hay una selección válida\n // o si el texto no coincide con el elemento seleccionado.\n if (typeof currentInputValue === \"string\") {\n // Si el input está vacío Y no hay un elemento seleccionado\n if (currentInputText === \"\" && !this._selectedElement) {\n console.log(\n \"Autocomplete closed: Input empty and no selection. Clearing internal state.\",\n );\n this.clearInternalState(); // Usa un método para limpiar\n }\n // Si se requiere selección y el texto no coincide con el elemento seleccionado,\n // o no hay ningún elemento seleccionado, entonces se borra.\n else if (\n this.requireSelection &&\n (!this._selectedElement ||\n currentInputText !== this.displayFn(this._selectedElement))\n ) {\n console.warn(\n \"Autocomplete closed: Selection required and no valid match found. Clearing input.\",\n );\n this.clearInternalState(); // Usa un método para limpiar\n }\n // Si NO se requiere selección, pero el usuario ha editado el texto de un elemento previamente seleccionado.\n // En este caso, NO borramos, sino que revertimos al texto del elemento seleccionado si existe.\n else if (\n this._selectedElement &&\n currentInputText !== this.displayFn(this._selectedElement) &&\n !this.requireSelection\n ) {\n console.log(\n \"Autocomplete closed: Text edited for a selected item, reverting to original.\",\n );\n // Revertir al texto del elemento seleccionado.\n this.component.setValue(this._selectedElement, {\n emitEvent: false,\n });\n this._lastSearchText = this.displayFn(this._selectedElement);\n this.propagateChange(this._selectedElement); // Propagar el valor original si se revierte\n }\n // Si el texto del input es un string y no se requiere selección,\n // y no hay _selectedElement (porque se deseleccionó en el tap o nunca hubo),\n // asumimos que el usuario quiere el texto libre.\n // No hacemos nada, el texto permanece.\n else if (\n typeof currentInputValue === \"string\" &&\n !this.requireSelection &&\n !this._selectedElement &&\n currentInputText !== \"\"\n ) {\n // Si no hay un elemento seleccionado pero el usuario escribió algo\n // y no se requiere selección, dejamos el texto tal cual.\n // Aseguramos que _lastSearchText se actualice para evitar re-búsquedas innecesarias.\n this._lastSearchText = currentInputText;\n this.propagateChange(currentInputText);\n }\n }\n // Si el valor ya es un objeto (porque se seleccionó) pero el texto del input fue borrado\n // y el _selectedElement es null (ya se desvinculó en el tap), significa que debe limpiarse.\n else if (\n typeof currentInputValue === \"object\" &&\n currentInputText === \"\" &&\n !this._selectedElement\n ) {\n console.log(\n \"Autocomplete closed: Object value but input cleared by user. Deselecting.\",\n );\n this.clearInternalState();\n }\n });\n }\n\n /**\n * Helper method to clear the internal state of the autocomplete.\n * Este método ahora se encarga de la limpieza profunda, incluyendo el valor del FormControl y la propagación.\n * @param resetLastSearchText - If true, resets _lastSearchText to an empty string. Defaults to true.\n */\n private clearInternalState(resetLastSearchText: boolean = true): void {\n // Solo si el valor del control NO es null, lo seteamos a null para evitar bucles.\n // Esto es importante porque en el tap, solo desvinculamos `_selectedElement` pero no el control.\n if (this.component.value !== null) {\n this.component.setValue(null, { emitEvent: false });\n }\n this.propagateChange(null);\n this.selectElement.emit(null);\n this._selectedElement = null; // Asegurar que el objeto seleccionado esté a null\n this._isOptionSelected = false; // Asegurar que la bandera de selección esté a false\n if (resetLastSearchText) {\n this._lastSearchText = \"\";\n }\n this.resetAutocompleteState(); // Resetear opciones y paginación\n console.log(\"Internal autocomplete state cleared.\");\n }\n\n /**\n * Searches for elements to display in the autocomplete component.\n * Now supports pagination.\n * @param text - Text to search\n */\n private getAutocompleteByTextHandler(text?: string): void {\n // Si no hay más datos Y ya cargamos algo (offset > 0) Y el texto de búsqueda no ha cambiado,\n // y no estamos actualmente cargando, salir.\n if (\n !this.hasMore() &&\n this._offset > 0 &&\n text === this._lastSearchText && // Verificar que el texto de búsqueda actual sea el mismo\n !this.loading()\n ) {\n console.log(\n \"No more data for current search text, stopping further loads.\",\n );\n return;\n }\n\n if (this.loading()) {\n console.log(\"Already loading, exiting getAutocompleteByTextHandler.\");\n return;\n }\n\n this.loading.set(true);\n\n const currentOffset = this._offset; // Capturar el offset actual antes de la llamada\n const currentSearchTextForApi = text; // Usar el texto pasado, no el global _lastSearchText\n\n if (!this._url && !this.serviceConfig) {\n console.warn(\"Autocomplete: 'url' or 'serviceConfig' input is required.\");\n this.loading.set(false);\n this.hasMore.set(false);\n return;\n }\n\n let apiCall: Observable<any>;\n\n if (this._url) {\n apiCall = from(\n this._autocompleteService.getAutocompleteByText(\n this._url,\n currentSearchTextForApi, // Usar el texto de búsqueda actual\n this.filterString,\n this._restrictionsFilters,\n this.removeProperties,\n this.order,\n this.bodyRequest,\n { limit: this._limit, offset: currentOffset },\n ),\n ).pipe(switchMap((innerObservable) => innerObservable));\n } else if (this.serviceConfig) {\n let body: any = { ...this.serviceConfig };\n body[this.serviceConfig.searchProperty] = currentSearchTextForApi; // Usar el texto de búsqueda actual\n body[\"limit\"] = this._limit;\n body[\"offset\"] = currentOffset;\n apiCall = this.serviceConfig.service[this.serviceConfig.method](body);\n } else {\n this.loading.set(false);\n this.hasMore.set(false);\n return;\n }\n\n // Guardar la posición de scroll antes de la actualización\n let panelScrollTop = 0;\n if (this.matAutocomplete?.panel) {\n panelScrollTop = this.matAutocomplete.panel.nativeElement.scrollTop;\n }\n\n apiCall\n .pipe(\n finalize((): void => {\n this.loading.set(false);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: (result: any): void => {\n const newData = result?.payload?.data ?? result?.data ?? [];\n console.log(\n \"New Data received:\",\n newData.length,\n \"items. Current offset before update:\",\n this._offset,\n );\n\n this._offset += newData.length; // Actualizar offset con la cantidad de nuevos ítems\n\n if (newData.length < this._limit) {\n this.hasMore.set(false);\n console.log(\"No more data, hasMore = false\");\n } else {\n this.hasMore.set(true);\n console.log(\"Potentially more data, hasMore = true\");\n }\n\n // Actualizar las opciones originales\n this.originalOptions.update((currentOptions) => {\n const updatedOptions = [...currentOptions, ...newData];\n console.log(\"Total options after merge:\", updatedOptions.length);\n return updatedOptions;\n });\n this.filterOptionsBasedOnNotAllowed();\n\n // Restaurar la posición de scroll después de que Angular haya actualizado el DOM\n // Esto debe hacerse fuera de la zona de Angular o con un pequeño retardo.\n if (this.matAutocomplete?.panel && panelScrollTop > 0) {\n this._zone.runOutsideAngular(() => {\n setTimeout(() => {\n this.matAutocomplete.panel.nativeElement.scrollTop =\n panelScrollTop;\n console.log(\"Scroll position restored to:\", panelScrollTop);\n }, 0); // Un pequeño retardo para asegurar que el DOM se haya renderizado\n });\n }\n },\n error: (error) => {\n console.error(\"Error fetching autocomplete data:\", error);\n this.loading.set(false);\n this.hasMore.set(false);\n },\n });\n }\n\n private filterOptionsBasedOnNotAllowed(): void {\n let currentOptions = this.originalOptions();\n const modifiedOptions = this.modifyResultFn(currentOptions);\n if (modifiedOptions !== null && modifiedOptions !== undefined) {\n currentOptions = modifiedOptions;\n }\n\n if (this.notAllowedOption()) {\n this.filteredOptions.set(\n currentOptions.filter(\n (option: any): boolean =>\n JSON.stringify(option) !== JSON.stringify(this.notAllowedOption()),\n ),\n );\n } else {\n this.filteredOptions.set(currentOptions);\n }\n }\n\n /**\n * Defines the text to be used for the search\n */\n private getAutocompleteSearchText(): string {\n const value = this.component.value;\n if (typeof value === \"object\" && value !== null) {\n // Si el valor es un objeto, usa displayFn para obtener el texto\n return this.displayFn(value);\n } else if (typeof value === \"string\") {\n return value;\n }\n return \"\";\n }\n\n // --- ControlValueAccessor methods ---\n propagateChange = (_: any): void => {};\n\n registerOnChange(fn: (_: any) => void): void {\n this.propagateChange = fn;\n }\n\n registerOnTouched(): void {}\n\n /**\n * Recibe el valor desde el FormControl externo.\n */\n writeValue(value: any): void {\n // Establecer la bandera para indicar que el cambio viene de un setValue programático\n this._isOptionSelected = typeof value === \"object\" && value !== null;\n this.component.setValue(value, { emitEvent: false }); // No emitir evento para evitar bucles.\n\n this._selectedElement = value\n ? this.valueId && typeof value === \"object\"\n ? value?.id\n : value\n : null;\n\n // Actualizar _lastSearchText basado en el valor que se está escribiendo.\n // Si el valor es nulo, _lastSearchText también debe ser nulo o vacío\n if (value) {\n this._lastSearchText = this.displayFn(value);\n console.log(\"writeValue: Last search text set to:\", this._lastSearchText);\n } else {\n this._lastSearchText = \"\";\n console.log(\"writeValue: Last search text cleared.\");\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n if (isDisabled) {\n this.component.disable();\n } else {\n this.component.enable();\n }\n }\n\n /**\n * Function to display selected elements\n */\n public displayFn = (value: any): string => {\n if (!value) {\n return \"\";\n }\n // Si el valor ya es una cadena, devuélvelo directamente\n if (typeof value === \"string\") {\n return value;\n }\n\n let displayText: string = \"\";\n const options = this.displayOptions || GENERAL_DISPLAY_OPTIONS;\n\n options?.firthLabel?.forEach((field: any): void => {\n if (field?.type === DisplayOptionItemType.PATH) {\n displayText +=\n UtilsService.resolvePropertyByPath(value, field?.path) || \"\";\n } else {\n displayText += field?.divider || \"\";\n }\n });\n\n return displayText;\n };\n\n /**\n * Action on clearing the input value\n */\n public clear(trigger: MatAutocompleteTrigger): void {\n this.clearElement.emit(this.component.value);\n this.clearInternalState(); // Usa el método auxiliar para limpiar\n this._zone.run((): void => {\n setTimeout((): void => {\n trigger.openPanel(); // Reabrir el panel después de borrar\n this.getAutocompleteByTextHandler(\"\"); // Cargar opciones iniciales (o todas) después de borrar\n }, 100);\n });\n }\n\n /**\n * Action on element Focus\n */\n public onFocus(): void {\n const currentSearchText = this.getAutocompleteSearchText();\n // Si no hay opciones cargadas O el input está vacío y no hay un elemento seleccionado\n if (\n this.originalOptions().length === 0 ||\n (currentSearchText === \"\" && !this._selectedElement)\n ) {\n this.resetAutocompleteState(); // Reiniciar estado antes de una nueva búsqueda\n this._lastSearchText = currentSearchText;\n console.log(\"On focus, initiating search for:\", currentSearchText);\n this.getAutocompleteByTextHandler(currentSearchText);\n } else if (\n this.matAutocomplete._isOpen &&\n currentSearchText === this._lastSearchText\n ) {\n // Si el panel ya está abierto y el texto no ha cambiado, no hacer nada para evitar re-cargas innecesarias.\n // Si el panel no estaba abierto, la apertura de `matAutocomplete.opened` se encargará de la carga.\n console.log(\n \"On focus, panel already open with same text, skipping search.\",\n );\n }\n }\n\n public optionSelected($event: any): void {\n const selectedValue = $event?.option?.value;\n if (selectedValue) {\n this._isOptionSelected = true; // Establecer la bandera de selección\n this._selectedElement = selectedValue;\n this.selectElement.emit(selectedValue);\n\n if (this.valueId && typeof selectedValue === \"object\") {\n this.propagateChange(selectedValue?.id);\n } else {\n this.propagateChange(selectedValue);\n }\n // Cuando un ítem es seleccionado, actualizar _lastSearchText con su valor de display.\n // Esto es crucial para que el valueChanges no vuelva a disparar una búsqueda para este valor.\n this._lastSearchText = this.displayFn(selectedValue);\n console.log(\n \"Option selected. Last search text set to:\",\n this._lastSearchText,\n );\n } else {\n // Si se deselecciona o selecciona nulo\n console.log(\"Option selected is null or undefined, clearing state.\");\n this.clearInternalState();\n }\n }\n\n /**\n * Handles the scroll event in the autocomplete panel to load more data.\n */\n onScroll(event: Event): void {\n const element = event.target as HTMLElement;\n const scrollPosition = element.scrollTop + element.clientHeight;\n const scrollHeight = element.scrollHeight;\n const threshold = 50; // Pixels before the end to load more\n\n if (\n scrollHeight - scrollPosition <= threshold &&\n !this.loading() &&\n this.hasMore()\n ) {\n console.log(\"Loading more data for infinity scroll...\");\n // Usar el texto de búsqueda actual (que puede ser el texto del ítem seleccionado o lo que el usuario escribió)\n this.getAutocompleteByTextHandler(this.getAutocompleteSearchText());\n }\n }\n}\n\n/**\n * Custom validation for element selection\n */\nexport function autocompleteValidator(\n control: AbstractControl,\n): ValidationErrors | null {\n // Un valor válido es un objeto no nulo que tiene una propiedad 'id'.\n // Esto asegura que realmente se ha seleccionado un objeto del autocomplete, no solo texto libre.\n if (\n typeof control?.value === \"object\" &&\n control?.value !== null &&\n \"id\" in control.value\n ) {\n return null;\n }\n return { invalidSelection: true };\n}\n","<mat-form-field\n [floatLabel]=\"floatLabel\"\n class=\"w-100\"\n [appearance]=\"appearance\"\n [color]=\"color\"\n [subscriptSizing]=\"subscriptSizing\"\n>\n @if (showLabel) {\n <mat-label>{{ label | translate }}</mat-label>\n } @if (showSuffix) {\n <mat-icon matSuffix>{{ suffixIcon ?? \"search\" }}</mat-icon>\n }\n <input\n #inputText\n #trigger=\"matAutocompleteTrigger\"\n (focus)=\"onFocus()\"\n [formControl]=\"component\"\n type=\"text\"\n [matAutocomplete]=\"auto\"\n [placeholder]=\"placeholder | translate\"\n aria-label=\"autocomplete\"\n autocomplete=\"off\"\n matInput\n [required]=\"required()\"\n />\n @if (!loading() && component.value) {\n <button\n (click)=\"clear(trigger)\"\n [disabled]=\"disabled()\"\n aria-label=\"Clear\"\n mat-icon-button\n matSuffix\n >\n <mat-icon>close</mat-icon>\n </button>\n } @if (loading()) {\n <button aria-label=\"search\" mat-icon-button matSuffix>\n <mat-spinner [value]=\"90\" color=\"accent\" diameter=\"25\"></mat-spinner>\n </button>\n }\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [displayWith]=\"displayFn\"\n [requireSelection]=\"requireSelection\"\n (optionSelected)=\"optionSelected($event)\"\n >\n @for (option of filteredOptions(); track option) {\n <mat-option [value]=\"option\">\n @if (!displayOptions && !detailsTemplate) {\n {{ option?.name | i18n: translateService.currentLang }}\n } @if (!detailsTemplate) {\n <div class=\"display-options\">\n <span [ngStyle]=\"{'line-height': displayOptions?.secondLabel ? '16px' : ''}\">\n {{\n option | resolvePropertyPath : displayOptions.firthLabel\n | i18n : translateService.currentLang\n }}\n </span>\n @if (displayOptions?.secondLabel) {\n <span class=\"mat-caption\">\n {{\n option | resolvePropertyPath : displayOptions.secondLabel\n | i18n : translateService.currentLang\n }}\n </span>\n }\n </div>\n } @if (detailsTemplate) {\n <ng-container\n *ngTemplateOutlet=\"detailsTemplate; context: { $implicit: option }\"\n ></ng-container>\n }\n </mat-option>\n }\n </mat-autocomplete>\n\n @if (component.invalid && component.touched) {\n <mat-error>\n {{ 'Este campo es requerido.' | translate }}\n </mat-error>\n }\n</mat-form-field>\n","/*\n * Public API Surface of guachos-general-autocomplete\n */\n\nexport * from './utils/constants/constants';\nexport * from './lib/guachos-general-autocomplete.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
@@ -87,6 +87,8 @@ export declare class GuajiritosGeneralAutocomplete implements ControlValueAccess
|
|
87
87
|
ngAfterViewInit(): void;
|
88
88
|
/**
|
89
89
|
* Helper method to clear the internal state of the autocomplete.
|
90
|
+
* Este método ahora se encarga de la limpieza profunda, incluyendo el valor del FormControl y la propagación.
|
91
|
+
* @param resetLastSearchText - If true, resets _lastSearchText to an empty string. Defaults to true.
|
90
92
|
*/
|
91
93
|
private clearInternalState;
|
92
94
|
/**
|