@guajiritos/general-autocomplete 19.0.4 → 19.0.6

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.
@@ -95,9 +95,8 @@ class GuajiritosGeneralAutocomplete {
95
95
  this._zone = _zone;
96
96
  this._destroyRef = _destroyRef;
97
97
  this.translateService = translateService;
98
- // --- Private Properties ---
99
- // Indica si la última actualización del input fue por una selección explícita desde el autocomplete
100
- this._isOptionSelected = false;
98
+ // --- Propiedades Privadas ---
99
+ this._isOptionSelected = false; // Indica si la última actualización del input fue por una selección explícita desde el autocompletado
101
100
  this._clearDataSubject = new Subject();
102
101
  this._doFocusSubject = new Subject();
103
102
  this._selectedElement = null; // Almacena el objeto completo seleccionado
@@ -105,8 +104,8 @@ class GuajiritosGeneralAutocomplete {
105
104
  this._limit = 20;
106
105
  this._offset = 0;
107
106
  this._restrictionsFilters = [];
108
- this._lastSearchText = ""; // Almacena el texto usado en la última búsqueda de API
109
- // --- Public Signals ---
107
+ this._lastSearchText = ""; // Almacena el texto usado en la última búsqueda de API exitosa
108
+ // --- Señales Públicas (Signals) ---
110
109
  this.disabled = signal(false);
111
110
  this.loading = signal(false);
112
111
  this.required = signal(false);
@@ -140,10 +139,10 @@ class GuajiritosGeneralAutocomplete {
140
139
  // --- Outputs ---
141
140
  this.selectElement = new EventEmitter();
142
141
  this.clearElement = new EventEmitter();
143
- // --- ControlValueAccessor methods ---
142
+ // --- Métodos de ControlValueAccessor ---
144
143
  this.propagateChange = (_) => { };
145
144
  /**
146
- * Function to display selected elements
145
+ * Función para mostrar los elementos seleccionados
147
146
  */
148
147
  this.displayFn = (value) => {
149
148
  if (!value) {
@@ -167,7 +166,7 @@ class GuajiritosGeneralAutocomplete {
167
166
  return displayText;
168
167
  };
169
168
  }
170
- // --- Setters for Inputs ---
169
+ // --- Setters para Inputs ---
171
170
  set url(data) {
172
171
  if (data) {
173
172
  this._url = data;
@@ -187,8 +186,6 @@ class GuajiritosGeneralAutocomplete {
187
186
  .subscribe({
188
187
  next: () => {
189
188
  this.clearInternalState();
190
- // No es necesario llamar a setValue(null) o propagateChange(null) aquí
191
- // porque clearInternalState ya lo hace.
192
189
  },
193
190
  });
194
191
  }
@@ -205,26 +202,32 @@ class GuajiritosGeneralAutocomplete {
205
202
  // Actualizar _lastSearchText basado en el valor inicial
206
203
  if (value) {
207
204
  this._lastSearchText = this.displayFn(value);
208
- console.log("initialValue set: _lastSearchText =", this._lastSearchText);
205
+ console.log("initialValue establecido: _lastSearchText =", this._lastSearchText);
209
206
  }
210
207
  else {
211
208
  this._lastSearchText = "";
212
209
  }
213
210
  }
214
211
  /**
215
- * Adds or removes search restrictions
212
+ * Añade o elimina restricciones de búsqueda
216
213
  */
217
214
  set restrictions(restrictions) {
218
215
  this._restrictionsFilters = restrictions?.length ? [...restrictions] : [];
216
+ // Siempre resetear el estado cuando cambian las restricciones
219
217
  this.resetAutocompleteState();
220
- // Re-ejecutar búsqueda si el input tiene texto y hay restricciones
218
+ // Re-ejecutar búsqueda si el input tiene texto o si está vacío y no hay selección, o si las restricciones cambiaron realmente el resultado esperado.
221
219
  const currentSearchText = this.getAutocompleteSearchText();
222
- if (currentSearchText) {
220
+ // Sólo si ya había un texto o una selección, o si las restricciones realmente impactan la búsqueda inicial.
221
+ if (currentSearchText !== this._lastSearchText ||
222
+ (!currentSearchText && !this._selectedElement) ||
223
+ restrictions?.length > 0) {
224
+ console.log("Restricciones cambiadas, iniciando nueva búsqueda.");
225
+ // No actualizar _lastSearchText aquí, se actualiza después de la API.
223
226
  this.getAutocompleteByTextHandler(currentSearchText);
224
227
  }
225
228
  }
226
229
  /**
227
- * Adds or removes required validation
230
+ * Añade o elimina la validación de requerido
228
231
  */
229
232
  set isRequired(required) {
230
233
  this.required.set(required);
@@ -236,7 +239,7 @@ class GuajiritosGeneralAutocomplete {
236
239
  this.component.updateValueAndValidity();
237
240
  }
238
241
  /**
239
- * Defines whether to perform a search when the element is in focus
242
+ * Define si se realiza una búsqueda cuando el elemento está en foco
240
243
  */
241
244
  set doFocus(focusSubject) {
242
245
  this._doFocusSubject = focusSubject;
@@ -248,7 +251,13 @@ class GuajiritosGeneralAutocomplete {
248
251
  this._zone.run(() => {
249
252
  setTimeout(() => {
250
253
  this.inputText?.nativeElement?.focus();
251
- this.inputText?.nativeElement?.dispatchEvent(new Event("input")); // Simular input para disparar valueChanges
254
+ // Simular evento 'input' para disparar valueChanges, pero solo si el input está vacío
255
+ // o si ya hay un valor pero no es el seleccionado (usuario queriendo buscar de nuevo).
256
+ if (!this.component.value ||
257
+ (typeof this.component.value === "string" &&
258
+ !this._selectedElement)) {
259
+ this.inputText?.nativeElement?.dispatchEvent(new Event("input"));
260
+ }
252
261
  this.autocompleteTrigger?.openPanel();
253
262
  }, 50); // Un pequeño retraso para asegurar el foco y la apertura
254
263
  });
@@ -262,24 +271,24 @@ class GuajiritosGeneralAutocomplete {
262
271
  }
263
272
  }
264
273
  /**
265
- * Resets the autocomplete pagination and options state.
266
- * Centralizes the logic to avoid duplication.
274
+ * Reinicia el estado de paginación y opciones del autocompletado.
275
+ * Centraliza la lógica para evitar duplicación.
267
276
  */
268
277
  resetAutocompleteState() {
269
278
  this._offset = 0;
270
279
  this.originalOptions.set([]);
271
280
  this.filteredOptions.set([]);
272
281
  this.hasMore.set(true);
273
- console.log("Autocomplete state reset (pagination/options).");
282
+ console.log("Estado de autocompletado reiniciado (paginación/opciones).");
274
283
  }
275
284
  /**
276
- * Subscription to search input changes
285
+ * Suscripción a los cambios del input de búsqueda
277
286
  */
278
287
  subscribeToComponentChanges() {
279
288
  this.component.valueChanges
280
289
  .pipe(
281
290
  // TAP se ejecuta inmediatamente ANTES del debounce.
282
- // Esto es crucial para detectar borrados de texto en tiempo real.
291
+ // Esto es crucial para detectar borrados de texto en tiempo real y desvincular _selectedElement.
283
292
  tap((value) => {
284
293
  const currentInputText = this.getAutocompleteSearchText();
285
294
  // Si el valor actual del control es un STRING (usuario escribiendo/borrando)
@@ -289,12 +298,9 @@ class GuajiritosGeneralAutocomplete {
289
298
  if (typeof value === "string" &&
290
299
  this._selectedElement &&
291
300
  currentInputText !== this.displayFn(this._selectedElement)) {
292
- console.log("TAP: User is editing/clearing text of a selected item. Deselecting internally.");
301
+ console.log("TAP: El usuario está editando/borrando texto de un elemento seleccionado. Deseleccionando internamente.");
293
302
  this._selectedElement = null; // Quitar la referencia al objeto seleccionado
294
303
  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
304
  }
299
305
  else if (typeof value === "string") {
300
306
  // Si el valor es un string, simplemente marcamos que no hay opción seleccionada.
@@ -311,45 +317,45 @@ class GuajiritosGeneralAutocomplete {
311
317
  if (typeof value === "object" &&
312
318
  value !== null &&
313
319
  this._selectedElement === value) {
314
- console.log("Value is selected object (after debounce), skipping search.");
320
+ console.log("El valor es un objeto seleccionado (después de debounce), saltando la búsqueda.");
315
321
  // Aseguramos que el _lastSearchText esté correcto para este objeto.
316
322
  this._lastSearchText = this.displayFn(value);
317
323
  return;
318
324
  }
319
325
  // 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.
321
- if ((typeof value === "string" &&
322
- currentSearchText !== this._lastSearchText) ||
323
- (currentSearchText === "" && this._lastSearchText !== "")) {
324
- this.resetAutocompleteState(); // Reiniciar paginación y opciones
325
- this._lastSearchText = currentSearchText; // Actualizar el último texto buscado
326
- console.log("Value changed (after debounce), initiating new search for:", currentSearchText);
326
+ // Si el texto actual ha cambiado con respecto al último buscado.
327
+ if (currentSearchText !== this._lastSearchText) {
328
+ this.resetAutocompleteState(); // Reiniciar paginación y opciones para la nueva búsqueda
329
+ this._lastSearchText = currentSearchText; // Actualizar el último texto buscado ANTES de la llamada a la API
330
+ console.log("El valor ha cambiado (después de debounce), iniciando nueva búsqueda para:", currentSearchText);
327
331
  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
- }
332
+ // Propagar el valor del input al control externo si no hay un elemento seleccionado
333
+ // y el texto no está vacío, o si está vacío y no hay selección.
334
+ // if (!this._selectedElement && currentSearchText !== "") {
335
+ // this.propagateChange(currentSearchText);
336
+ // } else if (!this._selectedElement && currentSearchText === "") {
337
+ // this.propagateChange(null);
338
+ // }
337
339
  }
338
- else if (currentSearchText === "" && this._lastSearchText === "") {
339
- // Si el input está vacío y ya lo estaba, y el panel está abierto sin opciones,
340
- // cargar las opciones iniciales.
340
+ else {
341
+ console.log("El valor no ha cambiado o es un estado estable, saltando nueva búsqueda de valueChanges.");
342
+ // Si el texto es el mismo, pero el panel está abierto, sin opciones y hay más datos potenciales,
343
+ // podemos necesitar una recarga (ej. si una búsqueda anterior falló o la red fue lenta).
341
344
  if (this.matAutocomplete._isOpen &&
342
345
  this.originalOptions().length === 0 &&
343
- !this.loading()) {
344
- console.log("Input empty, no options, panel open. Loading initial set.");
345
- this.getAutocompleteByTextHandler("");
346
+ !this.loading() &&
347
+ this.hasMore() &&
348
+ currentSearchText === "" // Solo si el input está vacío y no hay opciones
349
+ ) {
350
+ console.log("Input sin cambios pero panel abierto/vacío, activando re-búsqueda.");
351
+ this.getAutocompleteByTextHandler(currentSearchText);
346
352
  }
347
353
  }
348
354
  },
349
355
  });
350
356
  }
351
357
  ngAfterViewInit() {
352
- // Suscribirse a la apertura del panel para añadir el listener de scroll
358
+ // Suscribirse a la apertura del panel para añadir el listener de scroll y cargar datos
353
359
  this.matAutocomplete.opened
354
360
  .pipe(takeUntilDestroyed(this._destroyRef))
355
361
  .subscribe(() => {
@@ -357,14 +363,31 @@ class GuajiritosGeneralAutocomplete {
357
363
  // Asegurarse de que el listener sea removido antes de añadirlo para prevenir duplicados
358
364
  this.matAutocomplete.panel.nativeElement.removeEventListener("scroll", this.onScroll.bind(this));
359
365
  this.matAutocomplete.panel.nativeElement.addEventListener("scroll", this.onScroll.bind(this));
360
- // Si el panel se abre y no hay opciones cargadas, o si el input está vacío
361
- // y no hay una selección activa, cargar las opciones iniciales.
362
366
  const currentSearchText = this.getAutocompleteSearchText();
363
- if (this.originalOptions().length === 0 ||
364
- (!this._selectedElement && currentSearchText === "")) {
365
- console.log("Panel opened, loading initial set of options.");
367
+ // **********************************************
368
+ // MODIFICACIÓN CLAVE AQUÍ:
369
+ // Cargar opciones iniciales SOLO SI:
370
+ // 1. No hay opciones cargadas (primera apertura o después de un clear/reset).
371
+ // 2. O el texto actual en el input es diferente del _lastSearchText (el usuario escribió algo nuevo o borró y abrió).
372
+ // 3. O el input está vacío Y no hay un _selectedElement Y hay más datos por cargar Y el offset es 0 (lo que implica que es la primera carga para este estado vacío).
373
+ // Esto evita la doble llamada si subscribeToComponentChanges ya disparó una búsqueda
374
+ // para el mismo texto, o si ya se sabe que no hay más datos para un input vacío.
375
+ // **********************************************
376
+ if (this.originalOptions().length === 0 || // No hay opciones, cargar siempre.
377
+ currentSearchText !== this._lastSearchText || // El texto ha cambiado, nueva búsqueda.
378
+ (currentSearchText === "" &&
379
+ !this._selectedElement &&
380
+ this.hasMore() &&
381
+ this._offset === 0) // Input vacío, sin selección, con potencial de datos, y es la primera carga.
382
+ ) {
383
+ console.log("Panel abierto, condiciones cumplidas para búsqueda inicial/nueva. Cargando conjunto inicial de opciones.");
384
+ this.resetAutocompleteState(); // Asegurarse de resetear antes de una nueva carga
385
+ this._lastSearchText = currentSearchText; // Sincronizar _lastSearchText con la búsqueda que se va a realizar
366
386
  this.getAutocompleteByTextHandler(currentSearchText);
367
387
  }
388
+ else {
389
+ console.log("Panel abierto, opciones ya cargadas o elemento seleccionado existe, o texto sin cambios. Saltando carga inicial.");
390
+ }
368
391
  }
369
392
  });
370
393
  // Suscribirse al cierre del panel para remover el listener de scroll y manejar la deselección
@@ -376,13 +399,13 @@ class GuajiritosGeneralAutocomplete {
376
399
  }
377
400
  const currentInputValue = this.component.value;
378
401
  const currentInputText = this.getAutocompleteSearchText();
379
- console.log("Autocomplete closed. Current Input Value:", currentInputValue, "Selected Element:", this._selectedElement, "Current Input Text:", currentInputText);
402
+ console.log("Autocompletado cerrado. Valor actual del Input:", currentInputValue, "Elemento seleccionado:", this._selectedElement, "Texto actual del Input:", currentInputText);
380
403
  // Lógica para manejar el borrado del input si no hay una selección válida
381
404
  // o si el texto no coincide con el elemento seleccionado.
382
405
  if (typeof currentInputValue === "string") {
383
406
  // Si el input está vacío Y no hay un elemento seleccionado
384
407
  if (currentInputText === "" && !this._selectedElement) {
385
- console.log("Autocomplete closed: Input empty and no selection. Clearing internal state.");
408
+ console.log("Autocompletado cerrado: Input vacío y sin selección. Limpiando estado interno.");
386
409
  this.clearInternalState(); // Usa un método para limpiar
387
410
  }
388
411
  // Si se requiere selección y el texto no coincide con el elemento seleccionado,
@@ -390,7 +413,7 @@ class GuajiritosGeneralAutocomplete {
390
413
  else if (this.requireSelection &&
391
414
  (!this._selectedElement ||
392
415
  currentInputText !== this.displayFn(this._selectedElement))) {
393
- console.warn("Autocomplete closed: Selection required and no valid match found. Clearing input.");
416
+ console.warn("Autocompletado cerrado: Selección requerida y no se encontró una coincidencia válida. Limpiando input.");
394
417
  this.clearInternalState(); // Usa un método para limpiar
395
418
  }
396
419
  // Si NO se requiere selección, pero el usuario ha editado el texto de un elemento previamente seleccionado.
@@ -398,7 +421,7 @@ class GuajiritosGeneralAutocomplete {
398
421
  else if (this._selectedElement &&
399
422
  currentInputText !== this.displayFn(this._selectedElement) &&
400
423
  !this.requireSelection) {
401
- console.log("Autocomplete closed: Text edited for a selected item, reverting to original.");
424
+ console.log("Autocompletado cerrado: Texto editado para un elemento seleccionado, revirtiendo al original.");
402
425
  // Revertir al texto del elemento seleccionado.
403
426
  this.component.setValue(this._selectedElement, {
404
427
  emitEvent: false,
@@ -426,15 +449,15 @@ class GuajiritosGeneralAutocomplete {
426
449
  else if (typeof currentInputValue === "object" &&
427
450
  currentInputText === "" &&
428
451
  !this._selectedElement) {
429
- console.log("Autocomplete closed: Object value but input cleared by user. Deselecting.");
452
+ console.log("Autocompletado cerrado: Valor de objeto pero input limpiado por el usuario. Deseleccionando.");
430
453
  this.clearInternalState();
431
454
  }
432
455
  });
433
456
  }
434
457
  /**
435
- * Helper method to clear the internal state of the autocomplete.
458
+ * Método auxiliar para limpiar el estado interno del autocompletado.
436
459
  * 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.
460
+ * @param resetLastSearchText - Si es true, reinicia _lastSearchText a una cadena vacía. Por defecto es true.
438
461
  */
439
462
  clearInternalState(resetLastSearchText = true) {
440
463
  // Solo si el valor del control NO es null, lo seteamos a null para evitar bucles.
@@ -450,44 +473,48 @@ class GuajiritosGeneralAutocomplete {
450
473
  this._lastSearchText = "";
451
474
  }
452
475
  this.resetAutocompleteState(); // Resetear opciones y paginación
453
- console.log("Internal autocomplete state cleared.");
476
+ console.log("Estado interno del autocompletado limpiado.");
454
477
  }
455
478
  /**
456
- * Searches for elements to display in the autocomplete component.
457
- * Now supports pagination.
458
- * @param text - Text to search
479
+ * Busca elementos para mostrar en el componente de autocompletado.
480
+ * Ahora soporta paginación.
481
+ * @param text - Texto a buscar
459
482
  */
460
483
  getAutocompleteByTextHandler(text) {
461
- // Si no hay más datos Y ya cargamos algo (offset > 0) Y el texto de búsqueda no ha cambiado,
462
- // y no estamos actualmente cargando, salir.
463
- if (!this.hasMore() &&
464
- this._offset > 0 &&
465
- text === this._lastSearchText && // Verificar que el texto de búsqueda actual sea el mismo
466
- !this.loading()) {
467
- console.log("No more data for current search text, stopping further loads.");
484
+ const currentSearchText = text ?? "";
485
+ // Si ya estamos cargando, salimos para evitar peticiones duplicadas.
486
+ if (this.loading()) {
487
+ console.log("Ya estamos cargando, saliendo de getAutocompleteByTextHandler.");
468
488
  return;
469
489
  }
470
- if (this.loading()) {
471
- console.log("Already loading, exiting getAutocompleteByTextHandler.");
490
+ // **********************************************
491
+ // CLAVE: Evitar búsquedas innecesarias cuando ya se sabe que no hay más datos
492
+ // para el texto actual.
493
+ // Importante: Esto no debe detener la primera carga (offset 0).
494
+ // **********************************************
495
+ if (!this.hasMore() && // No hay más datos
496
+ this._offset > 0 && // Ya se cargó algo antes
497
+ currentSearchText === this._lastSearchText // El mismo texto de búsqueda para el que ya se agotaron los resultados
498
+ ) {
499
+ console.log("No hay más datos para el texto de búsqueda actual, deteniendo cargas adicionales.");
472
500
  return;
473
501
  }
474
502
  this.loading.set(true);
475
503
  const currentOffset = this._offset; // Capturar el offset actual antes de la llamada
476
- const currentSearchTextForApi = text; // Usar el texto pasado, no el global _lastSearchText
477
504
  if (!this._url && !this.serviceConfig) {
478
- console.warn("Autocomplete: 'url' or 'serviceConfig' input is required.");
505
+ console.warn("Autocompletado: Se requiere el input 'url' o 'serviceConfig'.");
479
506
  this.loading.set(false);
480
507
  this.hasMore.set(false);
481
508
  return;
482
509
  }
483
510
  let apiCall;
484
511
  if (this._url) {
485
- apiCall = from(this._autocompleteService.getAutocompleteByText(this._url, currentSearchTextForApi, // Usar el texto de búsqueda actual
512
+ apiCall = from(this._autocompleteService.getAutocompleteByText(this._url, currentSearchText, // Usar el texto de búsqueda actual
486
513
  this.filterString, this._restrictionsFilters, this.removeProperties, this.order, this.bodyRequest, { limit: this._limit, offset: currentOffset })).pipe(switchMap((innerObservable) => innerObservable));
487
514
  }
488
515
  else if (this.serviceConfig) {
489
516
  let body = { ...this.serviceConfig };
490
- body[this.serviceConfig.searchProperty] = currentSearchTextForApi; // Usar el texto de búsqueda actual
517
+ body[this.serviceConfig.searchProperty] = currentSearchText; // Usar el texto de búsqueda actual
491
518
  body["limit"] = this._limit;
492
519
  body["offset"] = currentOffset;
493
520
  apiCall = this.serviceConfig.service[this.serviceConfig.method](body);
@@ -509,22 +536,31 @@ class GuajiritosGeneralAutocomplete {
509
536
  .subscribe({
510
537
  next: (result) => {
511
538
  const newData = result?.payload?.data ?? result?.data ?? [];
512
- console.log("New Data received:", newData.length, "items. Current offset before update:", this._offset);
539
+ console.log("Nuevos datos recibidos:", newData.length, "elementos. Offset actual antes de la actualización:", this._offset);
540
+ // Si el offset es 0 (primera carga para esta búsqueda), reemplazamos las opciones.
541
+ // De lo contrario, las añadimos.
542
+ // Esto maneja que cada nueva búsqueda reemplace los resultados anteriores,
543
+ // y el scroll añada a los existentes.
544
+ if (currentOffset === 0) {
545
+ this.originalOptions.set(newData);
546
+ console.log("Primera carga para este texto. Opciones originales reemplazadas.");
547
+ }
548
+ else {
549
+ this.originalOptions.update((currentOptions) => [
550
+ ...currentOptions,
551
+ ...newData,
552
+ ]);
553
+ console.log("Carga adicional por scroll. Opciones originales actualizadas.");
554
+ }
513
555
  this._offset += newData.length; // Actualizar offset con la cantidad de nuevos ítems
514
556
  if (newData.length < this._limit) {
515
557
  this.hasMore.set(false);
516
- console.log("No more data, hasMore = false");
558
+ console.log("No hay más datos, hasMore = false");
517
559
  }
518
560
  else {
519
561
  this.hasMore.set(true);
520
- console.log("Potentially more data, hasMore = true");
562
+ console.log("Potencialmente más datos, hasMore = true");
521
563
  }
522
- // Actualizar las opciones originales
523
- this.originalOptions.update((currentOptions) => {
524
- const updatedOptions = [...currentOptions, ...newData];
525
- console.log("Total options after merge:", updatedOptions.length);
526
- return updatedOptions;
527
- });
528
564
  this.filterOptionsBasedOnNotAllowed();
529
565
  // Restaurar la posición de scroll después de que Angular haya actualizado el DOM
530
566
  // Esto debe hacerse fuera de la zona de Angular o con un pequeño retardo.
@@ -533,13 +569,13 @@ class GuajiritosGeneralAutocomplete {
533
569
  setTimeout(() => {
534
570
  this.matAutocomplete.panel.nativeElement.scrollTop =
535
571
  panelScrollTop;
536
- console.log("Scroll position restored to:", panelScrollTop);
572
+ console.log("Posición de scroll restaurada a:", panelScrollTop);
537
573
  }, 0); // Un pequeño retardo para asegurar que el DOM se haya renderizado
538
574
  });
539
575
  }
540
576
  },
541
577
  error: (error) => {
542
- console.error("Error fetching autocomplete data:", error);
578
+ console.error("Error al obtener datos de autocompletado:", error);
543
579
  this.loading.set(false);
544
580
  this.hasMore.set(false);
545
581
  },
@@ -559,7 +595,7 @@ class GuajiritosGeneralAutocomplete {
559
595
  }
560
596
  }
561
597
  /**
562
- * Defines the text to be used for the search
598
+ * Define el texto a utilizar para la búsqueda
563
599
  */
564
600
  getAutocompleteSearchText() {
565
601
  const value = this.component.value;
@@ -592,11 +628,11 @@ class GuajiritosGeneralAutocomplete {
592
628
  // Si el valor es nulo, _lastSearchText también debe ser nulo o vacío
593
629
  if (value) {
594
630
  this._lastSearchText = this.displayFn(value);
595
- console.log("writeValue: Last search text set to:", this._lastSearchText);
631
+ console.log("writeValue: Último texto de búsqueda establecido a:", this._lastSearchText);
596
632
  }
597
633
  else {
598
634
  this._lastSearchText = "";
599
- console.log("writeValue: Last search text cleared.");
635
+ console.log("writeValue: Último texto de búsqueda limpiado.");
600
636
  }
601
637
  }
602
638
  setDisabledState(isDisabled) {
@@ -609,7 +645,7 @@ class GuajiritosGeneralAutocomplete {
609
645
  }
610
646
  }
611
647
  /**
612
- * Action on clearing the input value
648
+ * Acción al limpiar el valor del input
613
649
  */
614
650
  clear(trigger) {
615
651
  this.clearElement.emit(this.component.value);
@@ -622,24 +658,16 @@ class GuajiritosGeneralAutocomplete {
622
658
  });
623
659
  }
624
660
  /**
625
- * Action on element Focus
661
+ * Acción al enfocar el elemento
626
662
  */
627
663
  onFocus() {
628
- const currentSearchText = this.getAutocompleteSearchText();
629
- // Si no hay opciones cargadas O el input está vacío y no hay un elemento seleccionado
630
- if (this.originalOptions().length === 0 ||
631
- (currentSearchText === "" && !this._selectedElement)) {
632
- this.resetAutocompleteState(); // Reiniciar estado antes de una nueva búsqueda
633
- this._lastSearchText = currentSearchText;
634
- console.log("On focus, initiating search for:", currentSearchText);
635
- this.getAutocompleteByTextHandler(currentSearchText);
636
- }
637
- else if (this.matAutocomplete._isOpen &&
638
- currentSearchText === this._lastSearchText) {
639
- // Si el panel ya está abierto y el texto no ha cambiado, no hacer nada para evitar re-cargas innecesarias.
640
- // Si el panel no estaba abierto, la apertura de `matAutocomplete.opened` se encargará de la carga.
641
- console.log("On focus, panel already open with same text, skipping search.");
642
- }
664
+ this.getAutocompleteByTextHandler("");
665
+ console.log("On focus: El panel será abierto por el trigger.");
666
+ // NOTA CLAVE: Ya NO disparamos getAutocompleteByTextHandler aquí directamente.
667
+ // La lógica de carga inicial cuando el panel se abre se gestiona
668
+ // en la suscripción a `this.matAutocomplete.opened` en `ngAfterViewInit`.
669
+ // Esto es crucial para evitar doble disparo, especialmente en dispositivos táctiles.
670
+ // El openPanel() lo maneja el trigger en el HTML, lo cual a su vez dispara matAutocomplete.opened.
643
671
  }
644
672
  optionSelected($event) {
645
673
  const selectedValue = $event?.option?.value;
@@ -656,26 +684,26 @@ class GuajiritosGeneralAutocomplete {
656
684
  // Cuando un ítem es seleccionado, actualizar _lastSearchText con su valor de display.
657
685
  // Esto es crucial para que el valueChanges no vuelva a disparar una búsqueda para este valor.
658
686
  this._lastSearchText = this.displayFn(selectedValue);
659
- console.log("Option selected. Last search text set to:", this._lastSearchText);
687
+ console.log("Opción seleccionada. Último texto de búsqueda establecido a:", this._lastSearchText);
660
688
  }
661
689
  else {
662
690
  // Si se deselecciona o selecciona nulo
663
- console.log("Option selected is null or undefined, clearing state.");
691
+ console.log("La opción seleccionada es nula o indefinida, limpiando el estado.");
664
692
  this.clearInternalState();
665
693
  }
666
694
  }
667
695
  /**
668
- * Handles the scroll event in the autocomplete panel to load more data.
696
+ * Maneja el evento de scroll en el panel del autocompletado para cargar más datos.
669
697
  */
670
698
  onScroll(event) {
671
699
  const element = event.target;
672
700
  const scrollPosition = element.scrollTop + element.clientHeight;
673
701
  const scrollHeight = element.scrollHeight;
674
- const threshold = 50; // Pixels before the end to load more
702
+ const threshold = 50; // Píxeles antes del final para cargar más
675
703
  if (scrollHeight - scrollPosition <= threshold &&
676
704
  !this.loading() &&
677
705
  this.hasMore()) {
678
- console.log("Loading more data for infinity scroll...");
706
+ console.log("Cargando más datos por scroll infinito...");
679
707
  // Usar el texto de búsqueda actual (que puede ser el texto del ítem seleccionado o lo que el usuario escribió)
680
708
  this.getAutocompleteByTextHandler(this.getAutocompleteSearchText());
681
709
  }
@@ -785,16 +813,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImpo
785
813
  type: Input
786
814
  }] } });
787
815
  /**
788
- * Custom validation for element selection
816
+ * Validación personalizada para la selección de elementos
789
817
  */
790
818
  function autocompleteValidator(control) {
791
819
  // Un valor válido es un objeto no nulo que tiene una propiedad 'id'.
792
- // Esto asegura que realmente se ha seleccionado un objeto del autocomplete, no solo texto libre.
820
+ // Esto asegura que realmente se ha seleccionado un objeto del autocompletado, no solo texto libre.
821
+ // Si el control está vacío, no se aplica esta validación aquí, sino la de 'Validators.required' si está presente.
822
+ if (control.value === null ||
823
+ typeof control.value === "undefined" ||
824
+ control.value === "") {
825
+ return null; // Deja que Validators.required maneje si está vacío.
826
+ }
793
827
  if (typeof control?.value === "object" &&
794
828
  control?.value !== null &&
795
829
  "id" in control.value) {
796
830
  return null;
797
831
  }
832
+ // Si el valor es una cadena (texto libre) y debería ser un objeto seleccionado.
798
833
  return { invalidSelection: true };
799
834
  }
800
835
 
@@ -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.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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"}
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 // --- Propiedades Privadas ---\n private _isOptionSelected: boolean = false; // Indica si la última actualización del input fue por una selección explícita desde el autocompletado\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 exitosa\n\n // --- Señales Públicas (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\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 para 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 },\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(\n \"initialValue establecido: _lastSearchText =\",\n this._lastSearchText,\n );\n } else {\n this._lastSearchText = \"\";\n }\n }\n\n /**\n * Añade o elimina restricciones de búsqueda\n */\n @Input() set restrictions(restrictions: RestrictionFilter[]) {\n this._restrictionsFilters = restrictions?.length ? [...restrictions] : [];\n // Siempre resetear el estado cuando cambian las restricciones\n this.resetAutocompleteState();\n // Re-ejecutar búsqueda si el input tiene texto o si está vacío y no hay selección, o si las restricciones cambiaron realmente el resultado esperado.\n const currentSearchText = this.getAutocompleteSearchText();\n // Sólo si ya había un texto o una selección, o si las restricciones realmente impactan la búsqueda inicial.\n if (\n currentSearchText !== this._lastSearchText ||\n (!currentSearchText && !this._selectedElement) ||\n restrictions?.length > 0\n ) {\n console.log(\"Restricciones cambiadas, iniciando nueva búsqueda.\");\n // No actualizar _lastSearchText aquí, se actualiza después de la API.\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n\n /**\n * Añade o elimina la validación de requerido\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 * Define si se realiza una búsqueda cuando el elemento está en foco\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 // Simular evento 'input' para disparar valueChanges, pero solo si el input está vacío\n // o si ya hay un valor pero no es el seleccionado (usuario queriendo buscar de nuevo).\n if (\n !this.component.value ||\n (typeof this.component.value === \"string\" &&\n !this._selectedElement)\n ) {\n (\n this.inputText?.nativeElement as HTMLInputElement\n )?.dispatchEvent(new Event(\"input\"));\n }\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 * Reinicia el estado de paginación y opciones del autocompletado.\n * Centraliza la lógica para evitar duplicación.\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(\"Estado de autocompletado reiniciado (paginación/opciones).\");\n }\n\n /**\n * Suscripción a los cambios del input de búsqueda\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 y desvincular _selectedElement.\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: El usuario está editando/borrando texto de un elemento seleccionado. Deseleccionando internamente.\",\n );\n this._selectedElement = null; // Quitar la referencia al objeto seleccionado\n this._isOptionSelected = false; // Marcar que no hay una opción seleccionada\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 \"El valor es un objeto seleccionado (después de debounce), saltando la búsqueda.\",\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.\n if (currentSearchText !== this._lastSearchText) {\n this.resetAutocompleteState(); // Reiniciar paginación y opciones para la nueva búsqueda\n this._lastSearchText = currentSearchText; // Actualizar el último texto buscado ANTES de la llamada a la API\n console.log(\n \"El valor ha cambiado (después de debounce), iniciando nueva búsqueda para:\",\n currentSearchText,\n );\n this.getAutocompleteByTextHandler(currentSearchText);\n\n // Propagar el valor del input al control externo si no hay un elemento seleccionado\n // y el texto no está vacío, o si está vacío y no hay selección.\n // if (!this._selectedElement && currentSearchText !== \"\") {\n // this.propagateChange(currentSearchText);\n // } else if (!this._selectedElement && currentSearchText === \"\") {\n // this.propagateChange(null);\n // }\n } else {\n console.log(\n \"El valor no ha cambiado o es un estado estable, saltando nueva búsqueda de valueChanges.\",\n );\n // Si el texto es el mismo, pero el panel está abierto, sin opciones y hay más datos potenciales,\n // podemos necesitar una recarga (ej. si una búsqueda anterior falló o la red fue lenta).\n if (\n this.matAutocomplete._isOpen &&\n this.originalOptions().length === 0 &&\n !this.loading() &&\n this.hasMore() &&\n currentSearchText === \"\" // Solo si el input está vacío y no hay opciones\n ) {\n console.log(\n \"Input sin cambios pero panel abierto/vacío, activando re-búsqueda.\",\n );\n this.getAutocompleteByTextHandler(currentSearchText);\n }\n }\n },\n });\n }\n\n ngAfterViewInit(): void {\n // Suscribirse a la apertura del panel para añadir el listener de scroll y cargar datos\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 const currentSearchText = this.getAutocompleteSearchText();\n\n // **********************************************\n // MODIFICACIÓN CLAVE AQUÍ:\n // Cargar opciones iniciales SOLO SI:\n // 1. No hay opciones cargadas (primera apertura o después de un clear/reset).\n // 2. O el texto actual en el input es diferente del _lastSearchText (el usuario escribió algo nuevo o borró y abrió).\n // 3. O el input está vacío Y no hay un _selectedElement Y hay más datos por cargar Y el offset es 0 (lo que implica que es la primera carga para este estado vacío).\n // Esto evita la doble llamada si subscribeToComponentChanges ya disparó una búsqueda\n // para el mismo texto, o si ya se sabe que no hay más datos para un input vacío.\n // **********************************************\n if (\n this.originalOptions().length === 0 || // No hay opciones, cargar siempre.\n currentSearchText !== this._lastSearchText || // El texto ha cambiado, nueva búsqueda.\n (currentSearchText === \"\" &&\n !this._selectedElement &&\n this.hasMore() &&\n this._offset === 0) // Input vacío, sin selección, con potencial de datos, y es la primera carga.\n ) {\n console.log(\n \"Panel abierto, condiciones cumplidas para búsqueda inicial/nueva. Cargando conjunto inicial de opciones.\",\n );\n this.resetAutocompleteState(); // Asegurarse de resetear antes de una nueva carga\n this._lastSearchText = currentSearchText; // Sincronizar _lastSearchText con la búsqueda que se va a realizar\n this.getAutocompleteByTextHandler(currentSearchText);\n } else {\n console.log(\n \"Panel abierto, opciones ya cargadas o elemento seleccionado existe, o texto sin cambios. Saltando carga inicial.\",\n );\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 \"Autocompletado cerrado. Valor actual del Input:\",\n currentInputValue,\n \"Elemento seleccionado:\",\n this._selectedElement,\n \"Texto actual del Input:\",\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 \"Autocompletado cerrado: Input vacío y sin selección. Limpiando estado interno.\",\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 \"Autocompletado cerrado: Selección requerida y no se encontró una coincidencia válida. Limpiando 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 \"Autocompletado cerrado: Texto editado para un elemento seleccionado, revirtiendo al 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 \"Autocompletado cerrado: Valor de objeto pero input limpiado por el usuario. Deseleccionando.\",\n );\n this.clearInternalState();\n }\n });\n }\n\n /**\n * Método auxiliar para limpiar el estado interno del autocompletado.\n * Este método ahora se encarga de la limpieza profunda, incluyendo el valor del FormControl y la propagación.\n * @param resetLastSearchText - Si es true, reinicia _lastSearchText a una cadena vacía. Por defecto es 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(\"Estado interno del autocompletado limpiado.\");\n }\n\n /**\n * Busca elementos para mostrar en el componente de autocompletado.\n * Ahora soporta paginación.\n * @param text - Texto a buscar\n */\n private getAutocompleteByTextHandler(text?: string): void {\n const currentSearchText = text ?? \"\";\n\n // Si ya estamos cargando, salimos para evitar peticiones duplicadas.\n if (this.loading()) {\n console.log(\n \"Ya estamos cargando, saliendo de getAutocompleteByTextHandler.\",\n );\n return;\n }\n\n // **********************************************\n // CLAVE: Evitar búsquedas innecesarias cuando ya se sabe que no hay más datos\n // para el texto actual.\n // Importante: Esto no debe detener la primera carga (offset 0).\n // **********************************************\n if (\n !this.hasMore() && // No hay más datos\n this._offset > 0 && // Ya se cargó algo antes\n currentSearchText === this._lastSearchText // El mismo texto de búsqueda para el que ya se agotaron los resultados\n ) {\n console.log(\n \"No hay más datos para el texto de búsqueda actual, deteniendo cargas adicionales.\",\n );\n return;\n }\n\n this.loading.set(true);\n\n const currentOffset = this._offset; // Capturar el offset actual antes de la llamada\n\n if (!this._url && !this.serviceConfig) {\n console.warn(\n \"Autocompletado: Se requiere el input 'url' o 'serviceConfig'.\",\n );\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 currentSearchText, // 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] = currentSearchText; // 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 \"Nuevos datos recibidos:\",\n newData.length,\n \"elementos. Offset actual antes de la actualización:\",\n this._offset,\n );\n\n // Si el offset es 0 (primera carga para esta búsqueda), reemplazamos las opciones.\n // De lo contrario, las añadimos.\n // Esto maneja que cada nueva búsqueda reemplace los resultados anteriores,\n // y el scroll añada a los existentes.\n if (currentOffset === 0) {\n this.originalOptions.set(newData);\n console.log(\n \"Primera carga para este texto. Opciones originales reemplazadas.\",\n );\n } else {\n this.originalOptions.update((currentOptions) => [\n ...currentOptions,\n ...newData,\n ]);\n console.log(\n \"Carga adicional por scroll. Opciones originales actualizadas.\",\n );\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 hay más datos, hasMore = false\");\n } else {\n this.hasMore.set(true);\n console.log(\"Potencialmente más datos, hasMore = true\");\n }\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(\"Posición de scroll restaurada a:\", 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 al obtener datos de autocompletado:\", 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 * Define el texto a utilizar para la búsqueda\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 // --- Métodos de ControlValueAccessor ---\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(\n \"writeValue: Último texto de búsqueda establecido a:\",\n this._lastSearchText,\n );\n } else {\n this._lastSearchText = \"\";\n console.log(\"writeValue: Último texto de búsqueda limpiado.\");\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 * Función para mostrar los elementos seleccionados\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 * Acción al limpiar el valor del input\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 * Acción al enfocar el elemento\n */\n public onFocus(): void {\n this.getAutocompleteByTextHandler(\"\");\n console.log(\"On focus: El panel será abierto por el trigger.\");\n // NOTA CLAVE: Ya NO disparamos getAutocompleteByTextHandler aquí directamente.\n // La lógica de carga inicial cuando el panel se abre se gestiona\n // en la suscripción a `this.matAutocomplete.opened` en `ngAfterViewInit`.\n // Esto es crucial para evitar doble disparo, especialmente en dispositivos táctiles.\n // El openPanel() lo maneja el trigger en el HTML, lo cual a su vez dispara matAutocomplete.opened.\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 \"Opción seleccionada. Último texto de búsqueda establecido a:\",\n this._lastSearchText,\n );\n } else {\n // Si se deselecciona o selecciona nulo\n console.log(\n \"La opción seleccionada es nula o indefinida, limpiando el estado.\",\n );\n this.clearInternalState();\n }\n }\n\n /**\n * Maneja el evento de scroll en el panel del autocompletado para cargar más datos.\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; // Píxeles antes del final para cargar más\n\n if (\n scrollHeight - scrollPosition <= threshold &&\n !this.loading() &&\n this.hasMore()\n ) {\n console.log(\"Cargando más datos por scroll infinito...\");\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 * Validación personalizada para la selección de elementos\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 autocompletado, no solo texto libre.\n // Si el control está vacío, no se aplica esta validación aquí, sino la de 'Validators.required' si está presente.\n if (\n control.value === null ||\n typeof control.value === \"undefined\" ||\n control.value === \"\"\n ) {\n return null; // Deja que Validators.required maneje si está vacío.\n }\n\n if (\n typeof control?.value === \"object\" &&\n control?.value !== null &&\n \"id\" in control.value\n ) {\n return null;\n }\n // Si el valor es una cadena (texto libre) y debería ser un objeto seleccionado.\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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"}
@@ -63,43 +63,43 @@ export declare class GuajiritosGeneralAutocomplete implements ControlValueAccess
63
63
  set clearData(value: Subject<void>);
64
64
  set initialValue(value: any);
65
65
  /**
66
- * Adds or removes search restrictions
66
+ * Añade o elimina restricciones de búsqueda
67
67
  */
68
68
  set restrictions(restrictions: RestrictionFilter[]);
69
69
  /**
70
- * Adds or removes required validation
70
+ * Añade o elimina la validación de requerido
71
71
  */
72
72
  set isRequired(required: boolean);
73
73
  /**
74
- * Defines whether to perform a search when the element is in focus
74
+ * Define si se realiza una búsqueda cuando el elemento está en foco
75
75
  */
76
76
  set doFocus(focusSubject: Subject<void>);
77
77
  set notAllowedElements(element: any);
78
78
  /**
79
- * Resets the autocomplete pagination and options state.
80
- * Centralizes the logic to avoid duplication.
79
+ * Reinicia el estado de paginación y opciones del autocompletado.
80
+ * Centraliza la lógica para evitar duplicación.
81
81
  */
82
82
  private resetAutocompleteState;
83
83
  /**
84
- * Subscription to search input changes
84
+ * Suscripción a los cambios del input de búsqueda
85
85
  */
86
86
  private subscribeToComponentChanges;
87
87
  ngAfterViewInit(): void;
88
88
  /**
89
- * Helper method to clear the internal state of the autocomplete.
89
+ * Método auxiliar para limpiar el estado interno del autocompletado.
90
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.
91
+ * @param resetLastSearchText - Si es true, reinicia _lastSearchText a una cadena vacía. Por defecto es true.
92
92
  */
93
93
  private clearInternalState;
94
94
  /**
95
- * Searches for elements to display in the autocomplete component.
96
- * Now supports pagination.
97
- * @param text - Text to search
95
+ * Busca elementos para mostrar en el componente de autocompletado.
96
+ * Ahora soporta paginación.
97
+ * @param text - Texto a buscar
98
98
  */
99
99
  private getAutocompleteByTextHandler;
100
100
  private filterOptionsBasedOnNotAllowed;
101
101
  /**
102
- * Defines the text to be used for the search
102
+ * Define el texto a utilizar para la búsqueda
103
103
  */
104
104
  private getAutocompleteSearchText;
105
105
  propagateChange: (_: any) => void;
@@ -111,26 +111,26 @@ export declare class GuajiritosGeneralAutocomplete implements ControlValueAccess
111
111
  writeValue(value: any): void;
112
112
  setDisabledState(isDisabled: boolean): void;
113
113
  /**
114
- * Function to display selected elements
114
+ * Función para mostrar los elementos seleccionados
115
115
  */
116
116
  displayFn: (value: any) => string;
117
117
  /**
118
- * Action on clearing the input value
118
+ * Acción al limpiar el valor del input
119
119
  */
120
120
  clear(trigger: MatAutocompleteTrigger): void;
121
121
  /**
122
- * Action on element Focus
122
+ * Acción al enfocar el elemento
123
123
  */
124
124
  onFocus(): void;
125
125
  optionSelected($event: any): void;
126
126
  /**
127
- * Handles the scroll event in the autocomplete panel to load more data.
127
+ * Maneja el evento de scroll en el panel del autocompletado para cargar más datos.
128
128
  */
129
129
  onScroll(event: Event): void;
130
130
  static ɵfac: i0.ɵɵFactoryDeclaration<GuajiritosGeneralAutocomplete, never>;
131
131
  static ɵcmp: i0.ɵɵComponentDeclaration<GuajiritosGeneralAutocomplete, "guajiritos-general-autocomplete", never, { "floatLabel": { "alias": "floatLabel"; "required": false; }; "color": { "alias": "color"; "required": false; }; "appearance": { "alias": "appearance"; "required": false; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; }; "bodyRequest": { "alias": "bodyRequest"; "required": false; }; "debounceTimeValue": { "alias": "debounceTimeValue"; "required": false; }; "detailsTemplate": { "alias": "detailsTemplate"; "required": false; }; "label": { "alias": "label"; "required": false; }; "showLabel": { "alias": "showLabel"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "field": { "alias": "field"; "required": false; }; "filterString": { "alias": "filterString"; "required": false; }; "displayOptions": { "alias": "displayOptions"; "required": false; }; "withoutPaddingBottom": { "alias": "withoutPaddingBottom"; "required": false; }; "valueId": { "alias": "valueId"; "required": false; }; "showSuffix": { "alias": "showSuffix"; "required": false; }; "requireSelection": { "alias": "requireSelection"; "required": false; }; "order": { "alias": "order"; "required": false; }; "serviceConfig": { "alias": "serviceConfig"; "required": false; }; "suffixIcon": { "alias": "suffixIcon"; "required": false; }; "removeProperties": { "alias": "removeProperties"; "required": false; }; "modifyResultFn": { "alias": "modifyResultFn"; "required": false; }; "url": { "alias": "url"; "required": false; }; "limit": { "alias": "limit"; "required": false; }; "clearData": { "alias": "clearData"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "restrictions": { "alias": "restrictions"; "required": false; }; "isRequired": { "alias": "isRequired"; "required": false; }; "doFocus": { "alias": "doFocus"; "required": false; }; "notAllowedElements": { "alias": "notAllowedElements"; "required": false; }; }, { "selectElement": "selectElement"; "clearElement": "clearElement"; }, never, never, true, never>;
132
132
  }
133
133
  /**
134
- * Custom validation for element selection
134
+ * Validación personalizada para la selección de elementos
135
135
  */
136
136
  export declare function autocompleteValidator(control: AbstractControl): ValidationErrors | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guajiritos/general-autocomplete",
3
- "version": "19.0.4",
3
+ "version": "19.0.6",
4
4
  "peerDependencies": {
5
5
  "@angular/cdk": "^19.2.17",
6
6
  "@angular/common": "^19.2.12",