@jvsoft/utils 1.0.0-alpha.6 → 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.
- package/README.md +5 -0
- package/directives/autocomplete-match-validator.directive.d.ts +10 -0
- package/directives/autocomplete.directive.d.ts +23 -0
- package/directives/index.d.ts +5 -0
- package/directives/public-api.d.ts +2 -0
- package/fesm2022/jvsoft-utils-directives.mjs +150 -0
- package/fesm2022/jvsoft-utils-directives.mjs.map +1 -0
- package/fesm2022/jvsoft-utils.mjs +246 -17
- package/fesm2022/jvsoft-utils.mjs.map +1 -1
- package/package.json +9 -5
- package/public-api.d.ts +5 -4
- package/{functions → src/functions}/mat-form-controls/autocomplete.d.ts +21 -2
- package/src/pipes/display-with.pipe.d.ts +14 -0
- package/{pipes → src/pipes}/public-api.d.ts +1 -0
- /package/{classes → src/classes}/data-model.d.ts +0 -0
- /package/{functions → src/functions}/base64.d.ts +0 -0
- /package/{functions → src/functions}/browser.d.ts +0 -0
- /package/{functions → src/functions}/crypto-js.d.ts +0 -0
- /package/{functions → src/functions}/date.d.ts +0 -0
- /package/{functions → src/functions}/dev-log.d.ts +0 -0
- /package/{functions → src/functions}/email.d.ts +0 -0
- /package/{functions → src/functions}/file.d.ts +0 -0
- /package/{functions → src/functions}/forms.d.ts +0 -0
- /package/{functions → src/functions}/http-client.d.ts +0 -0
- /package/{functions → src/functions}/local-storage.d.ts +0 -0
- /package/{functions → src/functions}/mat-form-controls/index.d.ts +0 -0
- /package/{functions → src/functions}/number.d.ts +0 -0
- /package/{functions → src/functions}/object-transformation.d.ts +0 -0
- /package/{functions → src/functions}/objects-arrays.d.ts +0 -0
- /package/{functions → src/functions}/public-api.d.ts +0 -0
- /package/{functions → src/functions}/string.d.ts +0 -0
- /package/{functions → src/functions}/sweetalert.d.ts +0 -0
- /package/{functions → src/functions}/utiles.d.ts +0 -0
- /package/{interfaces → src/interfaces}/datos.d.ts +0 -0
- /package/{interfaces → src/interfaces}/public-api.d.ts +0 -0
- /package/{pipes → src/pipes}/data-en-lista.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/date-diff-string.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/filtro.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/form-control-is-required.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/json-parse.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/no-sanitize.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/tipo-valor-funcion.pipe.d.ts +0 -0
- /package/{pipes → src/pipes}/zero-fill.pipe.d.ts +0 -0
package/README.md
CHANGED
|
@@ -58,6 +58,11 @@ ng e2e
|
|
|
58
58
|
|
|
59
59
|
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
60
60
|
|
|
61
|
+
## Documentación
|
|
62
|
+
|
|
63
|
+
- [Directiva JvAutocomplete](./docs/autocomplete.md): Guía detallada de uso, ejemplos y referencia de la API.
|
|
64
|
+
- [Utilidades de Logging](./docs/logging.md): Guía para el uso de logs en desarrollo.
|
|
65
|
+
|
|
61
66
|
## Additional Resources
|
|
62
67
|
|
|
63
68
|
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AbstractControl, ValidationErrors, Validator } from '@angular/forms';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class AutocompleteMatchValidatorDirective implements Validator {
|
|
4
|
+
opciones: import("@angular/core").InputSignal<any[]>;
|
|
5
|
+
formControlName: import("@angular/core").InputSignal<any>;
|
|
6
|
+
idLista: import("@angular/core").InputSignal<string | undefined>;
|
|
7
|
+
validate(control: AbstractControl): ValidationErrors | null;
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AutocompleteMatchValidatorDirective, never>;
|
|
9
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AutocompleteMatchValidatorDirective, "[jvsAutocompleteMatch]", never, { "opciones": { "alias": "jvsAutocompleteMatch"; "required": false; "isSignal": true; }; "formControlName": { "alias": "formControlName"; "required": false; "isSignal": true; }; "idLista": { "alias": "idLista"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class JvsAutocompleteDirective implements OnInit {
|
|
4
|
+
private readonly destroyRef;
|
|
5
|
+
private readonly ngControl;
|
|
6
|
+
private readonly focus$;
|
|
7
|
+
data: import("@angular/core").InputSignal<any[] | null>;
|
|
8
|
+
fields: import("@angular/core").InputSignal<string | string[]>;
|
|
9
|
+
typeReq: import("@angular/core").InputSignal<string>;
|
|
10
|
+
queryService: import("@angular/core").InputSignal<any>;
|
|
11
|
+
minLength: import("@angular/core").InputSignal<number>;
|
|
12
|
+
dataExtra: import("@angular/core").InputSignal<any>;
|
|
13
|
+
anonimo: import("@angular/core").InputSignal<boolean>;
|
|
14
|
+
debounce: import("@angular/core").InputSignal<number>;
|
|
15
|
+
filtered: import("@angular/core").OutputEmitterRef<any[]>;
|
|
16
|
+
loading: import("@angular/core").OutputEmitterRef<boolean>;
|
|
17
|
+
onFocus(): void;
|
|
18
|
+
ngOnInit(): void;
|
|
19
|
+
private filterLocal;
|
|
20
|
+
private fetchApi;
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<JvsAutocompleteDirective, never>;
|
|
22
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<JvsAutocompleteDirective, "[jvsAutocomplete]", never, { "data": { "alias": "data"; "required": false; "isSignal": true; }; "fields": { "alias": "fields"; "required": false; "isSignal": true; }; "typeReq": { "alias": "typeReq"; "required": false; "isSignal": true; }; "queryService": { "alias": "queryService"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "dataExtra": { "alias": "dataExtra"; "required": false; "isSignal": true; }; "anonimo": { "alias": "anonimo"; "required": false; "isSignal": true; }; "debounce": { "alias": "debounce"; "required": false; "isSignal": true; }; }, { "filtered": "filtered"; "loading": "loading"; }, never, never, true, never>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, forwardRef, Directive, inject, DestroyRef, output, HostListener } from '@angular/core';
|
|
3
|
+
import { NG_VALIDATORS, NgControl } from '@angular/forms';
|
|
4
|
+
import { Subject, merge, debounceTime, startWith, distinctUntilChanged, tap, switchMap, of, map, finalize } from 'rxjs';
|
|
5
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
+
|
|
7
|
+
class AutocompleteMatchValidatorDirective {
|
|
8
|
+
opciones = input([], { alias: 'jvsAutocompleteMatch' });
|
|
9
|
+
formControlName = input();
|
|
10
|
+
idLista = input();
|
|
11
|
+
validate(control) {
|
|
12
|
+
const idLista = this.idLista() ?? this.formControlName();
|
|
13
|
+
const value = control.value;
|
|
14
|
+
const opciones = this.opciones();
|
|
15
|
+
if (!value)
|
|
16
|
+
return null;
|
|
17
|
+
if (!opciones) {
|
|
18
|
+
console.error('Debe definir opciones para el validador jvsAutocompleteMatch');
|
|
19
|
+
return { itemSelected: true };
|
|
20
|
+
}
|
|
21
|
+
const encontrado = opciones.some(item => typeof value === 'object'
|
|
22
|
+
? item[idLista] === value[idLista]
|
|
23
|
+
: item[idLista] === value);
|
|
24
|
+
return encontrado ? null : { itemSelected: true };
|
|
25
|
+
}
|
|
26
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
27
|
+
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: [
|
|
28
|
+
{
|
|
29
|
+
provide: NG_VALIDATORS,
|
|
30
|
+
useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
|
|
31
|
+
multi: true,
|
|
32
|
+
},
|
|
33
|
+
], ngImport: i0 });
|
|
34
|
+
}
|
|
35
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, decorators: [{
|
|
36
|
+
type: Directive,
|
|
37
|
+
args: [{
|
|
38
|
+
selector: '[jvsAutocompleteMatch]',
|
|
39
|
+
providers: [
|
|
40
|
+
{
|
|
41
|
+
provide: NG_VALIDATORS,
|
|
42
|
+
useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
|
|
43
|
+
multi: true,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
standalone: true
|
|
47
|
+
}]
|
|
48
|
+
}] });
|
|
49
|
+
|
|
50
|
+
class JvsAutocompleteDirective {
|
|
51
|
+
destroyRef = inject(DestroyRef);
|
|
52
|
+
ngControl = inject(NgControl, { optional: true });
|
|
53
|
+
focus$ = new Subject();
|
|
54
|
+
// Signal-based Inputs
|
|
55
|
+
data = input(null);
|
|
56
|
+
fields = input('');
|
|
57
|
+
typeReq = input('');
|
|
58
|
+
queryService = input(null);
|
|
59
|
+
minLength = input(3);
|
|
60
|
+
dataExtra = input({});
|
|
61
|
+
anonimo = input(false);
|
|
62
|
+
debounce = input(300);
|
|
63
|
+
// Modern Outputs
|
|
64
|
+
filtered = output();
|
|
65
|
+
loading = output();
|
|
66
|
+
onFocus() {
|
|
67
|
+
this.focus$.next();
|
|
68
|
+
}
|
|
69
|
+
ngOnInit() {
|
|
70
|
+
const control = this.ngControl;
|
|
71
|
+
if (!control || !control.valueChanges) {
|
|
72
|
+
console.warn('JvsAutocompleteDirective: No se encontró ngControl o valueChanges. Asegúrate de que el input tenga un formControl o formControlName.');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Si es data local, bajamos el debounce por defecto a 0 si no se ha especificado
|
|
76
|
+
const isLocal = this.data() && !this.typeReq();
|
|
77
|
+
const actualDebounce = (isLocal && this.debounce() === 300) ? 0 : this.debounce();
|
|
78
|
+
merge(control.valueChanges.pipe(debounceTime(actualDebounce)), this.focus$).pipe(takeUntilDestroyed(this.destroyRef), startWith(control.value), distinctUntilChanged(), tap(() => {
|
|
79
|
+
if (this.typeReq())
|
|
80
|
+
this.loading.emit(true);
|
|
81
|
+
}), switchMap(() => {
|
|
82
|
+
const value = control.value;
|
|
83
|
+
// Si el valor es un objeto (proviene de seleccionar una opción), no volvemos a filtrar
|
|
84
|
+
if (typeof value === 'object' && value !== null) {
|
|
85
|
+
if (this.typeReq())
|
|
86
|
+
this.loading.emit(false);
|
|
87
|
+
return of(null);
|
|
88
|
+
}
|
|
89
|
+
if (this.typeReq() && this.queryService()) {
|
|
90
|
+
return this.fetchApi(value?.toString() || '');
|
|
91
|
+
}
|
|
92
|
+
else if (this.data()) {
|
|
93
|
+
const res = this.filterLocal(value?.toString() || '');
|
|
94
|
+
return of(res);
|
|
95
|
+
}
|
|
96
|
+
if (this.typeReq())
|
|
97
|
+
this.loading.emit(false);
|
|
98
|
+
return of([]);
|
|
99
|
+
})).subscribe((result) => {
|
|
100
|
+
if (result !== null) {
|
|
101
|
+
this.filtered.emit(result);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
filterLocal(value) {
|
|
106
|
+
const data = this.data();
|
|
107
|
+
if (!value)
|
|
108
|
+
return data || [];
|
|
109
|
+
const search = value.toLowerCase();
|
|
110
|
+
const rawFields = this.fields();
|
|
111
|
+
const fields = Array.isArray(rawFields) ? rawFields : [rawFields];
|
|
112
|
+
return (data || []).filter(item => {
|
|
113
|
+
return fields.some(field => {
|
|
114
|
+
const val = item[field];
|
|
115
|
+
return val && val.toString().toLowerCase().includes(search);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
fetchApi(value) {
|
|
120
|
+
const typeReq = this.typeReq();
|
|
121
|
+
const queryService = this.queryService();
|
|
122
|
+
if (!value || value.length < this.minLength()) {
|
|
123
|
+
this.loading.emit(false);
|
|
124
|
+
return of([]);
|
|
125
|
+
}
|
|
126
|
+
return queryService.getDataMethod('GET', typeReq, {
|
|
127
|
+
...this.dataExtra(),
|
|
128
|
+
txtBuscar: value
|
|
129
|
+
}, this.anonimo()).pipe(map((res) => res[typeReq] ?? []), finalize(() => this.loading.emit(false)));
|
|
130
|
+
}
|
|
131
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
132
|
+
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 });
|
|
133
|
+
}
|
|
134
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, decorators: [{
|
|
135
|
+
type: Directive,
|
|
136
|
+
args: [{
|
|
137
|
+
selector: '[jvsAutocomplete]',
|
|
138
|
+
standalone: true
|
|
139
|
+
}]
|
|
140
|
+
}], propDecorators: { onFocus: [{
|
|
141
|
+
type: HostListener,
|
|
142
|
+
args: ['focus']
|
|
143
|
+
}] } });
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Generated bundle index. Do not edit.
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
export { AutocompleteMatchValidatorDirective, JvsAutocompleteDirective };
|
|
150
|
+
//# sourceMappingURL=jvsoft-utils-directives.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jvsoft-utils-directives.mjs","sources":["../../../projects/utils/directives/autocomplete-match-validator.directive.ts","../../../projects/utils/directives/autocomplete.directive.ts","../../../projects/utils/directives/jvsoft-utils-directives.ts"],"sourcesContent":["import { Directive, forwardRef, input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';\n\n@Directive({\n selector: '[jvsAutocompleteMatch]',\n providers: [\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),\n multi: true,\n },\n ],\n standalone: true\n})\nexport class AutocompleteMatchValidatorDirective implements Validator {\n opciones = input<any[]>([], { alias: 'jvsAutocompleteMatch' });\n formControlName = input<any>();\n idLista = input<string>();\n\n validate(control: AbstractControl): ValidationErrors | null {\n const idLista = this.idLista() ?? this.formControlName();\n const value = control.value;\n const opciones = this.opciones();\n\n if (!value) return null;\n\n if (!opciones) {\n console.error('Debe definir opciones para el validador jvsAutocompleteMatch');\n return { itemSelected: true };\n }\n\n const encontrado = opciones.some(item =>\n typeof value === 'object'\n ? item[idLista] === value[idLista]\n : item[idLista] === value\n );\n\n return encontrado ? null : { itemSelected: true };\n }\n}\n","import { Directive, ElementRef, EventEmitter, inject, OnInit, DestroyRef, HostListener, input, output } from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { debounceTime, distinctUntilChanged, isObservable, of, switchMap, takeUntil, tap, finalize, map, Observable, startWith, merge, Subject } from 'rxjs';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\n@Directive({\n selector: '[jvsAutocomplete]',\n standalone: true\n})\nexport class JvsAutocompleteDirective implements OnInit {\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true });\n private readonly focus$ = new Subject<void>();\n \n // Signal-based Inputs\n data = input<any[] | null>(null);\n fields = input<string | string[]>('');\n typeReq = input<string>('');\n queryService = input<any>(null);\n minLength = input<number>(3);\n dataExtra = input<any>({});\n anonimo = input<boolean>(false);\n debounce = input<number>(300);\n \n // Modern Outputs\n filtered = output<any[]>();\n loading = output<boolean>();\n\n @HostListener('focus')\n onFocus() {\n this.focus$.next();\n }\n\n ngOnInit(): void {\n const control = this.ngControl;\n if (!control || !control.valueChanges) {\n console.warn('JvsAutocompleteDirective: No se encontró ngControl o valueChanges. Asegúrate de que el input tenga un formControl o formControlName.');\n return;\n }\n\n // Si es data local, bajamos el debounce por defecto a 0 si no se ha especificado\n const isLocal = this.data() && !this.typeReq();\n const actualDebounce = (isLocal && this.debounce() === 300) ? 0 : this.debounce();\n\n merge(\n control.valueChanges.pipe(debounceTime(actualDebounce)),\n this.focus$\n ).pipe(\n takeUntilDestroyed(this.destroyRef),\n startWith(control.value),\n distinctUntilChanged(),\n tap(() => {\n if (this.typeReq()) this.loading.emit(true);\n }),\n switchMap((): Observable<any[] | null> => {\n const value = control.value;\n // Si el valor es un objeto (proviene de seleccionar una opción), no volvemos a filtrar\n if (typeof value === 'object' && value !== null) {\n if (this.typeReq()) this.loading.emit(false);\n return of(null);\n }\n\n if (this.typeReq() && this.queryService()) {\n return this.fetchApi(value?.toString() || '');\n } else if (this.data()) {\n const res = this.filterLocal(value?.toString() || '');\n return of(res);\n }\n \n if (this.typeReq()) this.loading.emit(false);\n return of([]);\n })\n ).subscribe((result) => {\n if (result !== null) {\n this.filtered.emit(result);\n }\n });\n }\n\n private filterLocal(value: string): any[] {\n const data = this.data();\n if (!value) return data || [];\n \n const search = value.toLowerCase();\n const rawFields = this.fields();\n const fields = Array.isArray(rawFields) ? rawFields : [rawFields];\n\n return (data || []).filter(item => {\n return fields.some(field => {\n const val = item[field];\n return val && val.toString().toLowerCase().includes(search);\n });\n });\n }\n\n private fetchApi(value: string): Observable<any[]> {\n const typeReq = this.typeReq();\n const queryService = this.queryService();\n\n if (!value || value.length < this.minLength()) {\n this.loading.emit(false);\n return of([]);\n }\n\n return queryService.getDataMethod('GET', typeReq, {\n ...this.dataExtra(),\n txtBuscar: value\n }, this.anonimo()).pipe(\n map((res: any) => res[typeReq] ?? []),\n finalize(() => this.loading.emit(false))\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { Validators, FormGroup, FormControl, FormArray } from '@angular/forms';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
471
|
-
|
|
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
|
-
|
|
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] || [];
|
|
@@ -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
|