@jvsoft/utils 1.0.0-alpha.5 → 1.0.0-alpha.7

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.
Files changed (56) hide show
  1. package/README.md +5 -0
  2. package/directives/autocomplete-match-validator.directive.d.ts +10 -0
  3. package/directives/autocomplete.directive.d.ts +23 -0
  4. package/{src/pipes → directives}/index.d.ts +1 -1
  5. package/directives/public-api.d.ts +2 -0
  6. package/fesm2022/jvsoft-utils-directives.mjs +150 -0
  7. package/fesm2022/jvsoft-utils-directives.mjs.map +1 -0
  8. package/fesm2022/jvsoft-utils.mjs +270 -41
  9. package/fesm2022/jvsoft-utils.mjs.map +1 -1
  10. package/package.json +8 -16
  11. package/public-api.d.ts +5 -4
  12. package/src/functions/mat-form-controls/autocomplete.d.ts +21 -2
  13. package/src/pipes/display-with.pipe.d.ts +14 -0
  14. package/src/pipes/public-api.d.ts +1 -0
  15. package/fesm2022/jvsoft-utils-src-functions.mjs +0 -1707
  16. package/fesm2022/jvsoft-utils-src-functions.mjs.map +0 -1
  17. package/fesm2022/jvsoft-utils-src-interfaces.mjs +0 -6
  18. package/fesm2022/jvsoft-utils-src-interfaces.mjs.map +0 -1
  19. package/fesm2022/jvsoft-utils-src-pipes.mjs +0 -290
  20. package/fesm2022/jvsoft-utils-src-pipes.mjs.map +0 -1
  21. package/functions/base64.d.ts +0 -89
  22. package/functions/browser.d.ts +0 -1
  23. package/functions/crypto-js.d.ts +0 -2
  24. package/functions/date.d.ts +0 -3
  25. package/functions/dev-log.d.ts +0 -97
  26. package/functions/email.d.ts +0 -2
  27. package/functions/file.d.ts +0 -10
  28. package/functions/forms.d.ts +0 -23
  29. package/functions/http-client.d.ts +0 -2
  30. package/functions/index.d.ts +0 -1
  31. package/functions/local-storage.d.ts +0 -29
  32. package/functions/mat-form-controls/autocomplete.d.ts +0 -48
  33. package/functions/mat-form-controls/index.d.ts +0 -2
  34. package/functions/number.d.ts +0 -2
  35. package/functions/object-transformation.d.ts +0 -2
  36. package/functions/objects-arrays.d.ts +0 -63
  37. package/functions/public-api.d.ts +0 -17
  38. package/functions/string.d.ts +0 -23
  39. package/functions/sweetalert.d.ts +0 -5
  40. package/functions/utiles.d.ts +0 -1
  41. package/interfaces/datos.d.ts +0 -4
  42. package/interfaces/index.d.ts +0 -1
  43. package/interfaces/public-api.d.ts +0 -1
  44. package/pipes/data-en-lista.pipe.d.ts +0 -8
  45. package/pipes/date-diff-string.pipe.d.ts +0 -17
  46. package/pipes/filtro.pipe.d.ts +0 -18
  47. package/pipes/form-control-is-required.pipe.d.ts +0 -9
  48. package/pipes/index.d.ts +0 -1
  49. package/pipes/json-parse.pipe.d.ts +0 -7
  50. package/pipes/no-sanitize.pipe.d.ts +0 -10
  51. package/pipes/public-api.d.ts +0 -8
  52. package/pipes/tipo-valor-funcion.pipe.d.ts +0 -9
  53. package/pipes/zero-fill.pipe.d.ts +0 -8
  54. package/src/functions/index.d.ts +0 -5
  55. package/src/interfaces/index.d.ts +0 -5
  56. /package/{classes → src/classes}/data-model.d.ts +0 -0
@@ -1,6 +1,8 @@
1
- import { Validators, FormGroup, FormControl, FormArray } from '@angular/forms';
2
- import { untilDestroyed } from '@ngneat/until-destroy';
3
- import { startWith, debounceTime, tap, isObservable, switchMap, of, finalize } from 'rxjs';
1
+ import { Validators, FormGroup, FormControl, FormArray, NG_VALIDATORS, NgControl } from '@angular/forms';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, DestroyRef, Pipe, input, forwardRef, Directive, output, HostListener } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { tap, startWith, debounceTime, isObservable, switchMap, of, finalize, Subject, merge, distinctUntilChanged, map as map$1 } from 'rxjs';
4
6
  import { map } from 'rxjs/operators';
5
7
  import { Buffer } from 'buffer';
6
8
  import CryptoJS from 'crypto-js';
@@ -10,8 +12,6 @@ import { ReactiveFormConfig } from '@rxweb/reactive-form-validators';
10
12
  import moment from 'moment';
11
13
  import swal from 'sweetalert2';
12
14
  import { jwtDecode } from 'jwt-decode';
13
- import * as i0 from '@angular/core';
14
- import { Pipe } from '@angular/core';
15
15
  import * as i1 from '@angular/platform-browser';
16
16
 
17
17
  function deepMerge(source, target) {
@@ -287,6 +287,22 @@ function filtrarDatosLocal(data, value, campoBuscar) {
287
287
  });
288
288
  }
289
289
 
290
+ /**
291
+ * Intenta obtener el DestroyRef desde el llamador (objThis/control)
292
+ * o inyectándolo si estamos en un contexto de inyección.
293
+ */
294
+ function obtenerDestroyRef(caller, manualDRef, fnName = 'N/A') {
295
+ let dRef = manualDRef || caller?.['destroyRef'] || caller?.['_destroyRef'];
296
+ if (!dRef) {
297
+ try {
298
+ dRef = inject(DestroyRef, { optional: true });
299
+ }
300
+ catch (e) {
301
+ console.warn(`${fnName}: Falló inject(DestroyRef) (fuera del contexto de inyección). Pasa el destroyRef explícitamente o decláralo en el componente para habilitar la limpieza.`);
302
+ }
303
+ }
304
+ return dRef ?? undefined;
305
+ }
290
306
  function mostrarValorEnBusqueda(campos, idxSel) {
291
307
  const impDataMostrar = () => {
292
308
  let vD;
@@ -344,8 +360,12 @@ function mostrarValorEnBusqueda(campos, idxSel) {
344
360
  }
345
361
  return '';
346
362
  }
363
+ /**
364
+ * @deprecated Use JvsAutocompleteDirective en su lugar para un enfoque más declarativo y robusto.
365
+ */
347
366
  function changeSelectData(objThis, dataFiltro) {
348
- objThis['filtrados'][dataFiltro.variableResultado] = dataFiltro.formControl.valueChanges.pipe(untilDestroyed(objThis)).pipe(startWith(''), map(value => {
367
+ const dRef = obtenerDestroyRef(objThis, dataFiltro.destroyRef, 'changeSelectData');
368
+ objThis['filtrados'][dataFiltro.variableResultado] = dataFiltro.formControl.valueChanges.pipe(dRef ? takeUntilDestroyed(dRef) : tap(() => { })).pipe(startWith(''), map(value => {
349
369
  const varN = dataFiltro.data;
350
370
  if (varN) {
351
371
  if (value) {
@@ -385,14 +405,18 @@ function changeSelectData(objThis, dataFiltro) {
385
405
  return false;
386
406
  }));
387
407
  }
388
- function changeSelect(control, formControl, tipo, campoBuscar, campoFiltro = null) {
408
+ /**
409
+ * @deprecated Use JvsAutocompleteDirective en su lugar para un enfoque más declarativo y robusto.
410
+ */
411
+ function changeSelect(control, formControl, tipo, campoBuscar, campoFiltro = null, destroyRef) {
389
412
  // console.log(formControl);
390
413
  // const formGroup = formControl.parent.controls;
391
414
  // console.warn( Object.keys(formGroup).find(name => formControl === formGroup[name]) || null );
392
415
  if (!campoFiltro) {
393
416
  campoFiltro = tipo;
394
417
  }
395
- control['filtrados'][campoFiltro ?? '__'] = formControl.valueChanges.pipe(untilDestroyed(control)).pipe(startWith(''), map(value => {
418
+ const dRef = obtenerDestroyRef(control, destroyRef, 'changeSelect');
419
+ control['filtrados'][campoFiltro ?? '__'] = formControl.valueChanges.pipe(dRef ? takeUntilDestroyed(dRef) : tap(() => { })).pipe(startWith(''), map(value => {
396
420
  // console.warn(value);
397
421
  const partes = tipo.split('.');
398
422
  let varN;
@@ -440,12 +464,16 @@ function changeSelect(control, formControl, tipo, campoBuscar, campoFiltro = nul
440
464
  return false;
441
465
  }));
442
466
  }
467
+ /**
468
+ * @deprecated Use JvsAutocompleteDirective en su lugar para un enfoque más declarativo y robusto.
469
+ */
443
470
  function changeSelectDataApi(objThis, dataFiltro) {
444
471
  if (!dataFiltro.variableResultado) {
445
472
  dataFiltro.variableResultado = dataFiltro.tipoReq;
446
473
  }
447
474
  const idFiltrado = dataFiltro.variableResultado;
448
- dataFiltro.formControl.valueChanges.pipe(debounceTime(500), tap(() => {
475
+ const dRef = obtenerDestroyRef(objThis, dataFiltro.destroyRef, 'changeSelectDataApi');
476
+ dataFiltro.formControl.valueChanges.pipe(dRef ? takeUntilDestroyed(dRef) : tap(() => { }), debounceTime(500), tap(() => {
449
477
  objThis.filtrados[dataFiltro.variableResultado + 'tmp'] = isObservable(objThis.filtrados[idFiltrado]) ? [] : objThis.filtrados[idFiltrado] || [];
450
478
  if (objThis.filtrados[idFiltrado] !== objThis.filtrados[idFiltrado + 'tmp']) {
451
479
  objThis.filtrados[idFiltrado] = [];
@@ -467,8 +495,12 @@ function changeSelectDataApi(objThis, dataFiltro) {
467
495
  objThis.filtrados[idFiltrado] = data[dataFiltro.tipoReq] ?? [];
468
496
  });
469
497
  }
470
- function changeSelectApi(control, queryService, formControl, tipo, dataExtra = {}, dataExtraVariable = null, minLength = 1, anonimo = false) {
471
- formControl.valueChanges.pipe(debounceTime(500), tap((value) => {
498
+ /**
499
+ * @deprecated Use JvsAutocompleteDirective en su lugar para un enfoque más declarativo y robusto.
500
+ */
501
+ function changeSelectApi(control, queryService, formControl, tipo, dataExtra = {}, dataExtraVariable = null, minLength = 1, anonimo = false, destroyRef) {
502
+ const dRef = obtenerDestroyRef(control, destroyRef, 'changeSelectApi');
503
+ formControl.valueChanges.pipe(dRef ? takeUntilDestroyed(dRef) : tap(() => { }), debounceTime(500), tap((value) => {
472
504
  control['filtrados'][tipo + 'tmp'] = isObservable(control['filtrados'][tipo]) ? [] : control['filtrados'][tipo];
473
505
  if (control['filtrados'][tipo] != control['filtrados'][tipo + 'tmp']) {
474
506
  control['filtrados'][tipo] = [];
@@ -527,9 +559,13 @@ function seleccionarTextoInput$1(event) {
527
559
  * Función genérica para vincular un FormControl con datos desde API o Promise.
528
560
  * Preparada para migrar a signals en el futuro.
529
561
  */
562
+ /**
563
+ * @deprecated Use JvsAutocompleteDirective en su lugar para un enfoque más declarativo y robusto.
564
+ */
530
565
  function changeSelectReformateado(config) {
531
- const { objThis, tipoReq, formControl, queryService, campoId, minLength = 3, dataExtra = {}, dataExtraVariable = [], anonimo = false, variableResultado = tipoReq, } = config;
532
- formControl.valueChanges.pipe(debounceTime(500), tap(() => {
566
+ const { objThis, tipoReq, formControl, queryService, campoId, minLength = 3, dataExtra = {}, dataExtraVariable = [], anonimo = false, variableResultado = tipoReq, destroyRef } = config;
567
+ const dRef = obtenerDestroyRef(objThis, destroyRef, 'changeSelectReformateado');
568
+ formControl.valueChanges.pipe(dRef ? takeUntilDestroyed(dRef) : tap(() => { }), debounceTime(500), tap(() => {
533
569
  objThis.filtrados[variableResultado + 'tmp'] = isObservable(objThis.filtrados[variableResultado])
534
570
  ? []
535
571
  : objThis.filtrados[variableResultado] || [];
@@ -1846,10 +1882,10 @@ class DataEnListaPipe {
1846
1882
  }
1847
1883
  return null;
1848
1884
  }
1849
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataEnListaPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1850
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: DataEnListaPipe, isStandalone: true, name: "dataEnLista" });
1885
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DataEnListaPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1886
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DataEnListaPipe, isStandalone: true, name: "dataEnLista" });
1851
1887
  }
1852
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DataEnListaPipe, decorators: [{
1888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DataEnListaPipe, decorators: [{
1853
1889
  type: Pipe,
1854
1890
  args: [{
1855
1891
  name: 'dataEnLista',
@@ -1938,10 +1974,10 @@ class DateDiffStringPipe {
1938
1974
  seconds,
1939
1975
  };
1940
1976
  }
1941
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DateDiffStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1942
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: DateDiffStringPipe, isStandalone: true, name: "dateDiffString" });
1977
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DateDiffStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1978
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DateDiffStringPipe, isStandalone: true, name: "dateDiffString" });
1943
1979
  }
1944
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DateDiffStringPipe, decorators: [{
1980
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DateDiffStringPipe, decorators: [{
1945
1981
  type: Pipe,
1946
1982
  args: [{
1947
1983
  name: 'dateDiffString',
@@ -1993,10 +2029,10 @@ class FiltroPipe {
1993
2029
  return false;
1994
2030
  });
1995
2031
  }
1996
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FiltroPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1997
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: FiltroPipe, isStandalone: true, name: "filtro" });
2032
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FiltroPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2033
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: FiltroPipe, isStandalone: true, name: "filtro" });
1998
2034
  }
1999
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FiltroPipe, decorators: [{
2035
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FiltroPipe, decorators: [{
2000
2036
  type: Pipe,
2001
2037
  args: [{
2002
2038
  name: 'filtro'
@@ -2010,10 +2046,10 @@ class FormControlIsRequiredPipe {
2010
2046
  }
2011
2047
  return formControl.hasValidator(Validators.required);
2012
2048
  }
2013
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FormControlIsRequiredPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2014
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: FormControlIsRequiredPipe, isStandalone: true, name: "formControlIsRequired" });
2049
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormControlIsRequiredPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2050
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: FormControlIsRequiredPipe, isStandalone: true, name: "formControlIsRequired" });
2015
2051
  }
2016
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: FormControlIsRequiredPipe, decorators: [{
2052
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FormControlIsRequiredPipe, decorators: [{
2017
2053
  type: Pipe,
2018
2054
  args: [{
2019
2055
  name: 'formControlIsRequired'
@@ -2036,10 +2072,10 @@ class JsonParsePipe {
2036
2072
  return [];
2037
2073
  }
2038
2074
  }
2039
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: JsonParsePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2040
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: JsonParsePipe, isStandalone: true, name: "jsonParse" });
2075
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JsonParsePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2076
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: JsonParsePipe, isStandalone: true, name: "jsonParse" });
2041
2077
  }
2042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: JsonParsePipe, decorators: [{
2078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JsonParsePipe, decorators: [{
2043
2079
  type: Pipe,
2044
2080
  args: [{
2045
2081
  name: 'jsonParse'
@@ -2054,10 +2090,10 @@ class NoSanitizePipe {
2054
2090
  transform(html) {
2055
2091
  return this.domSanitizer.bypassSecurityTrustHtml(html);
2056
2092
  }
2057
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: NoSanitizePipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
2058
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: NoSanitizePipe, isStandalone: true, name: "noSanitize" });
2093
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NoSanitizePipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
2094
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: NoSanitizePipe, isStandalone: true, name: "noSanitize" });
2059
2095
  }
2060
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: NoSanitizePipe, decorators: [{
2096
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NoSanitizePipe, decorators: [{
2061
2097
  type: Pipe,
2062
2098
  args: [{ name: 'noSanitize' }]
2063
2099
  }], ctorParameters: () => [{ type: i1.DomSanitizer }] });
@@ -2072,10 +2108,10 @@ class TipoValorFuncionPipe {
2072
2108
  }
2073
2109
  return datoParam;
2074
2110
  }
2075
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: TipoValorFuncionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2076
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: TipoValorFuncionPipe, isStandalone: true, name: "tipoValorFuncion" });
2111
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TipoValorFuncionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2112
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: TipoValorFuncionPipe, isStandalone: true, name: "tipoValorFuncion" });
2077
2113
  }
2078
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: TipoValorFuncionPipe, decorators: [{
2114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TipoValorFuncionPipe, decorators: [{
2079
2115
  type: Pipe,
2080
2116
  args: [{
2081
2117
  name: 'tipoValorFuncion',
@@ -2094,10 +2130,10 @@ class ZeroFillPipe {
2094
2130
  }
2095
2131
  return s;
2096
2132
  }
2097
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ZeroFillPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2098
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: ZeroFillPipe, isStandalone: true, name: "zeroFill" });
2133
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ZeroFillPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2134
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: ZeroFillPipe, isStandalone: true, name: "zeroFill" });
2099
2135
  }
2100
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ZeroFillPipe, decorators: [{
2136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ZeroFillPipe, decorators: [{
2101
2137
  type: Pipe,
2102
2138
  args: [{
2103
2139
  name: 'zeroFill',
@@ -2107,18 +2143,211 @@ function zeroFill(value, digitos, ...args) {
2107
2143
  return new ZeroFillPipe().transform(value, digitos, args);
2108
2144
  }
2109
2145
 
2146
+ class JvsDisplayWithPipe {
2147
+ /**
2148
+ * Retorna una función compatible con [displayWith] de MatAutocomplete.
2149
+ * @param lista La lista de objetos donde buscar.
2150
+ * @param campoId El nombre del campo que coincide con el valor del control (ej: 'iCarreraId').
2151
+ * @param campoValue El nombre del campo (o campos) a mostrar (ej: 'cCarreraNombre' o ['cCodigo', 'cNombre']).
2152
+ * @param opcExtra Lista opcional de objetos extra donde buscar si no se encuentra en la lista principal.
2153
+ */
2154
+ transform(lista, campoId, campoValue, opcExtra) {
2155
+ return (idxSel) => {
2156
+ if (idxSel === null || idxSel === undefined || !lista) {
2157
+ return '';
2158
+ }
2159
+ const impDataMostrar = (vD) => {
2160
+ if (!vD)
2161
+ return '';
2162
+ if (Array.isArray(campoValue)) {
2163
+ return campoValue
2164
+ .map(field => vD[field] ?? '')
2165
+ .filter(val => !!val)
2166
+ .join(' - ');
2167
+ }
2168
+ return vD[campoValue]?.toString() || '';
2169
+ };
2170
+ // Buscar en la lista principal
2171
+ let item;
2172
+ if (campoId === '*object*' || campoId === '*objeto*') {
2173
+ item = lista.find(x => JSON.stringify(x).trim() === JSON.stringify(idxSel).trim());
2174
+ }
2175
+ else {
2176
+ item = lista.find(x => x[campoId] == idxSel);
2177
+ }
2178
+ // Si no se encuentra, buscar en opcExtra
2179
+ if (!item && opcExtra) {
2180
+ if (campoId === '*object*' || campoId === '*objeto*') {
2181
+ item = opcExtra.find(x => JSON.stringify(x).trim() === JSON.stringify(idxSel).trim());
2182
+ }
2183
+ else {
2184
+ item = opcExtra.find(x => x[campoId] == idxSel);
2185
+ }
2186
+ }
2187
+ return item ? impDataMostrar(item).trim() : '';
2188
+ };
2189
+ }
2190
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsDisplayWithPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2191
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: JvsDisplayWithPipe, isStandalone: true, name: "jvsDisplayWith" });
2192
+ }
2193
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsDisplayWithPipe, decorators: [{
2194
+ type: Pipe,
2195
+ args: [{
2196
+ name: 'jvsDisplayWith',
2197
+ standalone: true
2198
+ }]
2199
+ }] });
2200
+
2110
2201
  // export * from './otros';
2111
2202
 
2203
+ class AutocompleteMatchValidatorDirective {
2204
+ opciones = input([], { alias: 'jvsAutocompleteMatch' });
2205
+ formControlName = input();
2206
+ idLista = input();
2207
+ validate(control) {
2208
+ const idLista = this.idLista() ?? this.formControlName();
2209
+ const value = control.value;
2210
+ const opciones = this.opciones();
2211
+ if (!value)
2212
+ return null;
2213
+ if (!opciones) {
2214
+ console.error('Debe definir opciones para el validador jvsAutocompleteMatch');
2215
+ return { itemSelected: true };
2216
+ }
2217
+ const encontrado = opciones.some(item => typeof value === 'object'
2218
+ ? item[idLista] === value[idLista]
2219
+ : item[idLista] === value);
2220
+ return encontrado ? null : { itemSelected: true };
2221
+ }
2222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2223
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: AutocompleteMatchValidatorDirective, isStandalone: true, selector: "[jvsAutocompleteMatch]", inputs: { opciones: { classPropertyName: "opciones", publicName: "jvsAutocompleteMatch", isSignal: true, isRequired: false, transformFunction: null }, formControlName: { classPropertyName: "formControlName", publicName: "formControlName", isSignal: true, isRequired: false, transformFunction: null }, idLista: { classPropertyName: "idLista", publicName: "idLista", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
2224
+ {
2225
+ provide: NG_VALIDATORS,
2226
+ useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
2227
+ multi: true,
2228
+ },
2229
+ ], ngImport: i0 });
2230
+ }
2231
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, decorators: [{
2232
+ type: Directive,
2233
+ args: [{
2234
+ selector: '[jvsAutocompleteMatch]',
2235
+ providers: [
2236
+ {
2237
+ provide: NG_VALIDATORS,
2238
+ useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
2239
+ multi: true,
2240
+ },
2241
+ ],
2242
+ standalone: true
2243
+ }]
2244
+ }] });
2245
+
2246
+ class JvsAutocompleteDirective {
2247
+ destroyRef = inject(DestroyRef);
2248
+ ngControl = inject(NgControl, { optional: true });
2249
+ focus$ = new Subject();
2250
+ // Signal-based Inputs
2251
+ data = input(null);
2252
+ fields = input('');
2253
+ typeReq = input('');
2254
+ queryService = input(null);
2255
+ minLength = input(3);
2256
+ dataExtra = input({});
2257
+ anonimo = input(false);
2258
+ debounce = input(300);
2259
+ // Modern Outputs
2260
+ filtered = output();
2261
+ loading = output();
2262
+ onFocus() {
2263
+ this.focus$.next();
2264
+ }
2265
+ ngOnInit() {
2266
+ const control = this.ngControl;
2267
+ if (!control || !control.valueChanges) {
2268
+ console.warn('JvsAutocompleteDirective: No se encontró ngControl o valueChanges. Asegúrate de que el input tenga un formControl o formControlName.');
2269
+ return;
2270
+ }
2271
+ // Si es data local, bajamos el debounce por defecto a 0 si no se ha especificado
2272
+ const isLocal = this.data() && !this.typeReq();
2273
+ const actualDebounce = (isLocal && this.debounce() === 300) ? 0 : this.debounce();
2274
+ merge(control.valueChanges.pipe(debounceTime(actualDebounce)), this.focus$).pipe(takeUntilDestroyed(this.destroyRef), startWith(control.value), distinctUntilChanged(), tap(() => {
2275
+ if (this.typeReq())
2276
+ this.loading.emit(true);
2277
+ }), switchMap(() => {
2278
+ const value = control.value;
2279
+ // Si el valor es un objeto (proviene de seleccionar una opción), no volvemos a filtrar
2280
+ if (typeof value === 'object' && value !== null) {
2281
+ if (this.typeReq())
2282
+ this.loading.emit(false);
2283
+ return of(null);
2284
+ }
2285
+ if (this.typeReq() && this.queryService()) {
2286
+ return this.fetchApi(value?.toString() || '');
2287
+ }
2288
+ else if (this.data()) {
2289
+ const res = this.filterLocal(value?.toString() || '');
2290
+ return of(res);
2291
+ }
2292
+ if (this.typeReq())
2293
+ this.loading.emit(false);
2294
+ return of([]);
2295
+ })).subscribe((result) => {
2296
+ if (result !== null) {
2297
+ this.filtered.emit(result);
2298
+ }
2299
+ });
2300
+ }
2301
+ filterLocal(value) {
2302
+ const data = this.data();
2303
+ if (!value)
2304
+ return data || [];
2305
+ const search = value.toLowerCase();
2306
+ const rawFields = this.fields();
2307
+ const fields = Array.isArray(rawFields) ? rawFields : [rawFields];
2308
+ return (data || []).filter(item => {
2309
+ return fields.some(field => {
2310
+ const val = item[field];
2311
+ return val && val.toString().toLowerCase().includes(search);
2312
+ });
2313
+ });
2314
+ }
2315
+ fetchApi(value) {
2316
+ const typeReq = this.typeReq();
2317
+ const queryService = this.queryService();
2318
+ if (!value || value.length < this.minLength()) {
2319
+ this.loading.emit(false);
2320
+ return of([]);
2321
+ }
2322
+ return queryService.getDataMethod('GET', typeReq, {
2323
+ ...this.dataExtra(),
2324
+ txtBuscar: value
2325
+ }, this.anonimo()).pipe(map$1((res) => res[typeReq] ?? []), finalize(() => this.loading.emit(false)));
2326
+ }
2327
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2328
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: JvsAutocompleteDirective, isStandalone: true, selector: "[jvsAutocomplete]", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, typeReq: { classPropertyName: "typeReq", publicName: "typeReq", isSignal: true, isRequired: false, transformFunction: null }, queryService: { classPropertyName: "queryService", publicName: "queryService", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, dataExtra: { classPropertyName: "dataExtra", publicName: "dataExtra", isSignal: true, isRequired: false, transformFunction: null }, anonimo: { classPropertyName: "anonimo", publicName: "anonimo", isSignal: true, isRequired: false, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filtered: "filtered", loading: "loading" }, host: { listeners: { "focus": "onFocus()" } }, ngImport: i0 });
2329
+ }
2330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, decorators: [{
2331
+ type: Directive,
2332
+ args: [{
2333
+ selector: '[jvsAutocomplete]',
2334
+ standalone: true
2335
+ }]
2336
+ }], propDecorators: { onFocus: [{
2337
+ type: HostListener,
2338
+ args: ['focus']
2339
+ }] } });
2340
+
2112
2341
  /*
2113
2342
  * Public API Surface of utils
2114
2343
  */
2115
- // export * from './functions/common.function';
2116
- // export * from './lib/utils.component';
2117
- // export * from './lib/utils.service';
2344
+ // export * from './src/functions/common.function';
2345
+ // export * from './src/lib/utils.component';
2346
+ // export * from './src/lib/utils.service';
2118
2347
 
2119
2348
  /**
2120
2349
  * Generated bundle index. Do not edit.
2121
2350
  */
2122
2351
 
2123
- export { DataEnListaPipe, DataModel, DateDiffStringPipe, FiltroPipe, FormControlIsRequiredPipe, JsonParsePipe, NoSanitizePipe, TipoValorFuncionPipe, ZeroFillPipe, b64Decode, b64Encode, buscarPorCampo, changeSelect, changeSelectApi, changeSelectData, changeSelectDataApi, changeSelectReformateado, convertirBytes, dataEnLista, dateDiffString, decodeBase64Object, decodeBase64String, decodeBase64ToBlob, deepClone, deepMerge, delLocalStorage, desencriptar, devError, devGroup, devGroupEnd, devLog, devTable, devTime, devTimeEnd, devWarn, downLoadFileStream, eliminarColumnaPorIndex, eliminarDuplicados, eliminarElementos, encodeBase64File, encodeBase64Object, encodeBase64String, encriptar, esNumero, esPromise, establecerQuitarRequired, extraerDominio, filtrarDatosLocal, formControlIsRequired, formatearFecha, formatearFechaCadena, formatearFechaFormato, generateRandomString, getBrowserName, getCambiarPwd, getDataArchivoFromPath, getFormValidationErrors, getLocalStorage, getUniqueValues, getUniqueValuesByProperty, getValueByPath, groupBy, inicializarVariablesSessionStorage, isEmail, isProduction, jwtToken, jwtTokenData, jwtTokenExpiracion, jwtTokenExpiracionFaltante, localStorageKeys, markAsTouchedWithoutEmitEvent, maskEmail, mensajeAlerta, mensajeConfirmacion, mensajeTimer, mensajeToast, mensajesDeError, mensajesErrorFormControl, mostrarValorEnBusqueda, nestGroupsBy, numberToWords, objectPropertiesBoolean, objectPropertiesToType, obtenerHostDesdeUrl, obtenerMimeType, obtenerUltimoOrden, ordenarArray, ordenarPorPropiedad, ordenarPorPropiedades, roundToDecimal, sanitizarNombreArchivo, seleccionarTextoInput, setCambiarPwd, setControlDesdeLista, setJwtTokenData, setLocalStorage, setProductionMode, sumarObjetos, sumarPropiedades, tipoValorFuncion, toFormData, transformarFechasPorNombreDeCampo, verificarRUC, zeroFill };
2352
+ export { AutocompleteMatchValidatorDirective, DataEnListaPipe, DataModel, DateDiffStringPipe, FiltroPipe, FormControlIsRequiredPipe, JsonParsePipe, JvsAutocompleteDirective, JvsDisplayWithPipe, NoSanitizePipe, TipoValorFuncionPipe, ZeroFillPipe, b64Decode, b64Encode, buscarPorCampo, changeSelect, changeSelectApi, changeSelectData, changeSelectDataApi, changeSelectReformateado, convertirBytes, dataEnLista, dateDiffString, decodeBase64Object, decodeBase64String, decodeBase64ToBlob, deepClone, deepMerge, delLocalStorage, desencriptar, devError, devGroup, devGroupEnd, devLog, devTable, devTime, devTimeEnd, devWarn, downLoadFileStream, eliminarColumnaPorIndex, eliminarDuplicados, eliminarElementos, encodeBase64File, encodeBase64Object, encodeBase64String, encriptar, esNumero, esPromise, establecerQuitarRequired, extraerDominio, filtrarDatosLocal, formControlIsRequired, formatearFecha, formatearFechaCadena, formatearFechaFormato, generateRandomString, getBrowserName, getCambiarPwd, getDataArchivoFromPath, getFormValidationErrors, getLocalStorage, getUniqueValues, getUniqueValuesByProperty, getValueByPath, groupBy, inicializarVariablesSessionStorage, isEmail, isProduction, jwtToken, jwtTokenData, jwtTokenExpiracion, jwtTokenExpiracionFaltante, localStorageKeys, markAsTouchedWithoutEmitEvent, maskEmail, mensajeAlerta, mensajeConfirmacion, mensajeTimer, mensajeToast, mensajesDeError, mensajesErrorFormControl, mostrarValorEnBusqueda, nestGroupsBy, numberToWords, objectPropertiesBoolean, objectPropertiesToType, obtenerHostDesdeUrl, obtenerMimeType, obtenerUltimoOrden, ordenarArray, ordenarPorPropiedad, ordenarPorPropiedades, roundToDecimal, sanitizarNombreArchivo, seleccionarTextoInput, setCambiarPwd, setControlDesdeLista, setJwtTokenData, setLocalStorage, setProductionMode, sumarObjetos, sumarPropiedades, tipoValorFuncion, toFormData, transformarFechasPorNombreDeCampo, verificarRUC, zeroFill };
2124
2353
  //# sourceMappingURL=jvsoft-utils.mjs.map