@jvsoft/utils 0.0.13-alpha.5 → 1.0.0-alpha.10

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 (72) hide show
  1. package/README.md +5 -0
  2. package/directives/auto-select-first.directive.d.ts +13 -0
  3. package/directives/autocomplete-match-validator.directive.d.ts +10 -0
  4. package/directives/autocomplete.directive.d.ts +23 -0
  5. package/{src/functions → directives}/index.d.ts +1 -1
  6. package/directives/popover/popover-listener.directive.d.ts +12 -0
  7. package/directives/popover/popover-panel.component.d.ts +13 -0
  8. package/directives/popover/popover.directive.d.ts +23 -0
  9. package/directives/popover/popover.interface.d.ts +8 -0
  10. package/directives/popover/popover.service.d.ts +17 -0
  11. package/directives/public-api.d.ts +8 -0
  12. package/fesm2022/jvsoft-utils-directives.mjs +459 -0
  13. package/fesm2022/jvsoft-utils-directives.mjs.map +1 -0
  14. package/fesm2022/{jvsoft-utils-src-functions.mjs → jvsoft-utils-functions.mjs} +543 -190
  15. package/fesm2022/jvsoft-utils-functions.mjs.map +1 -0
  16. package/fesm2022/{jvsoft-utils-src-interfaces.mjs → jvsoft-utils-interfaces.mjs} +1 -1
  17. package/fesm2022/jvsoft-utils-interfaces.mjs.map +1 -0
  18. package/fesm2022/{jvsoft-utils-src-pipes.mjs → jvsoft-utils-pipes.mjs} +57 -2
  19. package/fesm2022/jvsoft-utils-pipes.mjs.map +1 -0
  20. package/fesm2022/jvsoft-utils-services.mjs +105 -0
  21. package/fesm2022/jvsoft-utils-services.mjs.map +1 -0
  22. package/fesm2022/jvsoft-utils.mjs +1142 -196
  23. package/fesm2022/jvsoft-utils.mjs.map +1 -1
  24. package/functions/base64.d.ts +87 -0
  25. package/functions/dev-log.d.ts +97 -0
  26. package/functions/index.d.ts +4 -0
  27. package/functions/mat-form-controls/autocomplete.d.ts +43 -27
  28. package/functions/objects-arrays.d.ts +13 -97
  29. package/functions/public-api.d.ts +1 -0
  30. package/interfaces/index.d.ts +4 -0
  31. package/package.json +27 -17
  32. package/pipes/display-with.pipe.d.ts +14 -0
  33. package/pipes/index.d.ts +4 -0
  34. package/pipes/public-api.d.ts +1 -0
  35. package/public-api.d.ts +6 -4
  36. package/{src/pipes → services}/index.d.ts +1 -1
  37. package/services/public-api.d.ts +1 -0
  38. package/services/reloj.service.d.ts +31 -0
  39. package/fesm2022/jvsoft-utils-src-functions.mjs.map +0 -1
  40. package/fesm2022/jvsoft-utils-src-interfaces.mjs.map +0 -1
  41. package/fesm2022/jvsoft-utils-src-pipes.mjs.map +0 -1
  42. package/src/functions/base64.d.ts +0 -2
  43. package/src/functions/browser.d.ts +0 -1
  44. package/src/functions/crypto-js.d.ts +0 -2
  45. package/src/functions/date.d.ts +0 -3
  46. package/src/functions/email.d.ts +0 -2
  47. package/src/functions/file.d.ts +0 -10
  48. package/src/functions/forms.d.ts +0 -23
  49. package/src/functions/http-client.d.ts +0 -2
  50. package/src/functions/local-storage.d.ts +0 -29
  51. package/src/functions/mat-form-controls/autocomplete.d.ts +0 -51
  52. package/src/functions/mat-form-controls/index.d.ts +0 -2
  53. package/src/functions/number.d.ts +0 -2
  54. package/src/functions/object-transformation.d.ts +0 -2
  55. package/src/functions/objects-arrays.d.ts +0 -147
  56. package/src/functions/public-api.d.ts +0 -16
  57. package/src/functions/string.d.ts +0 -23
  58. package/src/functions/sweetalert.d.ts +0 -5
  59. package/src/functions/utiles.d.ts +0 -1
  60. package/src/interfaces/datos.d.ts +0 -4
  61. package/src/interfaces/index.d.ts +0 -5
  62. package/src/interfaces/public-api.d.ts +0 -1
  63. package/src/pipes/data-en-lista.pipe.d.ts +0 -8
  64. package/src/pipes/date-diff-string.pipe.d.ts +0 -17
  65. package/src/pipes/filtro.pipe.d.ts +0 -18
  66. package/src/pipes/form-control-is-required.pipe.d.ts +0 -9
  67. package/src/pipes/json-parse.pipe.d.ts +0 -7
  68. package/src/pipes/no-sanitize.pipe.d.ts +0 -10
  69. package/src/pipes/public-api.d.ts +0 -8
  70. package/src/pipes/tipo-valor-funcion.pipe.d.ts +0 -9
  71. package/src/pipes/zero-fill.pipe.d.ts +0 -8
  72. /package/{classes → src/classes}/data-model.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,13 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class AutoSelectFirstDirective {
3
+ private readonly ngControl;
4
+ private readonly fcName;
5
+ private readonly toastr;
6
+ options: import("@angular/core").InputSignal<any[] | null>;
7
+ jvsIdKey: import("@angular/core").InputSignal<string | string[] | null>;
8
+ jvsEmptyMsg: import("@angular/core").InputSignal<string>;
9
+ onAutoSelect: import("@angular/core").OutputEmitterRef<any>;
10
+ constructor();
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<AutoSelectFirstDirective, never>;
12
+ static ɵdir: i0.ɵɵDirectiveDeclaration<AutoSelectFirstDirective, "[jvsAutoSelectFirst]", never, { "options": { "alias": "jvsAutoSelectFirst"; "required": false; "isSignal": true; }; "jvsIdKey": { "alias": "jvsIdKey"; "required": false; "isSignal": true; }; "jvsEmptyMsg": { "alias": "jvsEmptyMsg"; "required": false; "isSignal": true; }; }, { "onAutoSelect": "onAutoSelect"; }, never, never, true, never>;
13
+ }
@@ -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
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Generated bundle index. Do not edit.
3
3
  */
4
- /// <amd-module name="@jvsoft/utils/src/functions" />
4
+ /// <amd-module name="@jvsoft/utils/directives" />
5
5
  export * from './public-api';
@@ -0,0 +1,12 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class JvsPopoverListenerDirective {
3
+ private readonly popoverService;
4
+ private readonly elementRef;
5
+ trigger: import("@angular/core").InputSignal<"hover" | "click" | "focus">;
6
+ onMouseOver(event: MouseEvent): void;
7
+ onMouseOut(event: MouseEvent): void;
8
+ onClick(event: MouseEvent): void;
9
+ private findPopoverTarget;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<JvsPopoverListenerDirective, never>;
11
+ static ɵdir: i0.ɵɵDirectiveDeclaration<JvsPopoverListenerDirective, "[jvsPopoverListener]", never, { "trigger": { "alias": "trigger"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
12
+ }
@@ -0,0 +1,13 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class JvsPopoverPanelComponent {
4
+ content: import("@angular/core").InputSignal<string | null>;
5
+ templateContent: import("@angular/core").InputSignal<TemplateRef<any> | null>;
6
+ context: import("@angular/core").InputSignal<any>;
7
+ customClass: import("@angular/core").InputSignal<string>;
8
+ private readonly baseClasses;
9
+ combinedClasses: import("@angular/core").Signal<string>;
10
+ isTemplate(): boolean;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<JvsPopoverPanelComponent, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<JvsPopoverPanelComponent, "jvs-popover-panel", never, { "content": { "alias": "content"; "required": false; "isSignal": true; }; "templateContent": { "alias": "templateContent"; "required": false; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; "customClass": { "alias": "customClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
13
+ }
@@ -0,0 +1,23 @@
1
+ import { OnDestroy, TemplateRef } from '@angular/core';
2
+ import { JvsPopoverTrigger } from './popover.interface';
3
+ import * as i0 from "@angular/core";
4
+ export declare class JvsPopoverDirective implements OnDestroy {
5
+ private readonly popoverService;
6
+ private readonly elementRef;
7
+ private readonly viewContainerRef;
8
+ content: import("@angular/core").InputSignal<string | TemplateRef<any> | null>;
9
+ context: import("@angular/core").InputSignal<any>;
10
+ trigger: import("@angular/core").InputSignal<JvsPopoverTrigger>;
11
+ position: import("@angular/core").InputSignal<"top" | "bottom" | "left" | "right">;
12
+ customClass: import("@angular/core").InputSignal<string>;
13
+ onMouseEnter(): void;
14
+ onMouseLeave(): void;
15
+ onClick(): void;
16
+ onFocus(): void;
17
+ onBlur(): void;
18
+ ngOnDestroy(): void;
19
+ show(): void;
20
+ hide(): void;
21
+ static ɵfac: i0.ɵɵFactoryDeclaration<JvsPopoverDirective, never>;
22
+ static ɵdir: i0.ɵɵDirectiveDeclaration<JvsPopoverDirective, "[jvsPopover]", never, { "content": { "alias": "jvsPopover"; "required": false; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; "trigger": { "alias": "trigger"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "customClass": { "alias": "customClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
23
+ }
@@ -0,0 +1,8 @@
1
+ export type JvsPopoverTrigger = 'hover' | 'click' | 'focus' | 'manual';
2
+ export interface JvsPopoverConfig {
3
+ trigger?: JvsPopoverTrigger;
4
+ position?: 'top' | 'bottom' | 'left' | 'right';
5
+ showDelay?: number;
6
+ hideDelay?: number;
7
+ customClass?: string;
8
+ }
@@ -0,0 +1,17 @@
1
+ import { TemplateRef, ViewContainerRef } from '@angular/core';
2
+ import { OverlayRef } from '@angular/cdk/overlay';
3
+ import * as i0 from "@angular/core";
4
+ export declare class JvsPopoverService {
5
+ private readonly overlay;
6
+ private readonly overlayPositionBuilder;
7
+ private overlayRef;
8
+ open(element: HTMLElement, content: string | TemplateRef<any>, options?: {
9
+ position?: 'top' | 'bottom' | 'left' | 'right';
10
+ customClass?: string;
11
+ viewContainerRef?: ViewContainerRef;
12
+ context?: any;
13
+ }): OverlayRef;
14
+ close(): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<JvsPopoverService, never>;
16
+ static ɵprov: i0.ɵɵInjectableDeclaration<JvsPopoverService>;
17
+ }
@@ -0,0 +1,8 @@
1
+ export * from './autocomplete-match-validator.directive';
2
+ export * from './popover/popover.directive';
3
+ export * from './popover/popover-listener.directive';
4
+ export * from './popover/popover.interface';
5
+ export * from './popover/popover-panel.component';
6
+ export * from './popover/popover.service';
7
+ export * from './autocomplete.directive';
8
+ export * from './auto-select-first.directive';
@@ -0,0 +1,459 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, forwardRef, Directive, computed, Component, inject, TemplateRef, Injectable, ElementRef, ViewContainerRef, HostListener, DestroyRef, output, effect, untracked } from '@angular/core';
3
+ import { NG_VALIDATORS, NgControl, FormControlName } from '@angular/forms';
4
+ import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
5
+ import { ComponentPortal } from '@angular/cdk/portal';
6
+ import * as i1 from '@angular/common';
7
+ import { CommonModule } from '@angular/common';
8
+ import { Subject, merge, debounceTime, startWith, distinctUntilChanged, tap, switchMap, of, map, finalize } from 'rxjs';
9
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
10
+ import { ToastrService } from 'ngx-toastr';
11
+
12
+ class AutocompleteMatchValidatorDirective {
13
+ opciones = input([], { alias: 'jvsAutocompleteMatch' });
14
+ formControlName = input();
15
+ idLista = input();
16
+ validate(control) {
17
+ const idLista = this.idLista() ?? this.formControlName();
18
+ const value = control.value;
19
+ const opciones = this.opciones();
20
+ if (!value)
21
+ return null;
22
+ if (!opciones) {
23
+ console.error('Debe definir opciones para el validador jvsAutocompleteMatch');
24
+ return { itemSelected: true };
25
+ }
26
+ const encontrado = opciones.some(item => typeof value === 'object'
27
+ ? item[idLista] === value[idLista]
28
+ : item[idLista] === value);
29
+ return encontrado ? null : { itemSelected: true };
30
+ }
31
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
32
+ 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: [
33
+ {
34
+ provide: NG_VALIDATORS,
35
+ useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
36
+ multi: true,
37
+ },
38
+ ], ngImport: i0 });
39
+ }
40
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutocompleteMatchValidatorDirective, decorators: [{
41
+ type: Directive,
42
+ args: [{
43
+ selector: '[jvsAutocompleteMatch]',
44
+ providers: [
45
+ {
46
+ provide: NG_VALIDATORS,
47
+ useExisting: forwardRef(() => AutocompleteMatchValidatorDirective),
48
+ multi: true,
49
+ },
50
+ ],
51
+ standalone: true
52
+ }]
53
+ }] });
54
+
55
+ class JvsPopoverPanelComponent {
56
+ content = input(null);
57
+ templateContent = input(null);
58
+ context = input(null);
59
+ customClass = input('');
60
+ baseClasses = 'bg-white shadow-md rounded border-sm border-gray-700 p-1 mat-elevation-z4';
61
+ combinedClasses = computed(() => {
62
+ return `${this.baseClasses} ${this.customClass()}`.trim();
63
+ });
64
+ isTemplate() {
65
+ return !!this.templateContent();
66
+ }
67
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
68
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.14", type: JvsPopoverPanelComponent, isStandalone: true, selector: "jvs-popover-panel", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, templateContent: { classPropertyName: "templateContent", publicName: "templateContent", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, customClass: { classPropertyName: "customClass", publicName: "customClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
69
+ <div [class]="combinedClasses()">
70
+ <ng-container *ngIf="isTemplate(); else htmlContent">
71
+ <ng-container *ngTemplateOutlet="templateContent(); context: context()"></ng-container>
72
+ </ng-container>
73
+ <ng-template #htmlContent>
74
+ <div [innerHTML]="content()"></div>
75
+ </ng-template>
76
+ </div>
77
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
78
+ }
79
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverPanelComponent, decorators: [{
80
+ type: Component,
81
+ args: [{ selector: 'jvs-popover-panel', standalone: true, imports: [CommonModule], template: `
82
+ <div [class]="combinedClasses()">
83
+ <ng-container *ngIf="isTemplate(); else htmlContent">
84
+ <ng-container *ngTemplateOutlet="templateContent(); context: context()"></ng-container>
85
+ </ng-container>
86
+ <ng-template #htmlContent>
87
+ <div [innerHTML]="content()"></div>
88
+ </ng-template>
89
+ </div>
90
+ `, styles: [":host{display:block}\n"] }]
91
+ }] });
92
+
93
+ class JvsPopoverService {
94
+ overlay = inject(Overlay);
95
+ overlayPositionBuilder = inject(OverlayPositionBuilder);
96
+ overlayRef = null;
97
+ open(element, content, options = {}) {
98
+ this.close();
99
+ const positionStrategy = this.overlayPositionBuilder
100
+ .flexibleConnectedTo(element)
101
+ .withPositions([
102
+ {
103
+ originX: 'center',
104
+ originY: options.position === 'top' ? 'top' : 'bottom',
105
+ overlayX: 'center',
106
+ overlayY: options.position === 'top' ? 'bottom' : 'top',
107
+ offsetY: options.position === 'top' ? -8 : 8
108
+ }
109
+ ]);
110
+ this.overlayRef = this.overlay.create({
111
+ positionStrategy,
112
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
113
+ hasBackdrop: false
114
+ });
115
+ const portal = new ComponentPortal(JvsPopoverPanelComponent, options.viewContainerRef);
116
+ const containerRef = this.overlayRef.attach(portal);
117
+ if (content instanceof TemplateRef) {
118
+ containerRef.setInput('templateContent', content);
119
+ }
120
+ else {
121
+ containerRef.setInput('content', content);
122
+ }
123
+ if (options.customClass) {
124
+ containerRef.setInput('customClass', options.customClass);
125
+ }
126
+ if (options.context) {
127
+ containerRef.setInput('context', options.context);
128
+ }
129
+ return this.overlayRef;
130
+ }
131
+ close() {
132
+ if (this.overlayRef) {
133
+ this.overlayRef.detach();
134
+ this.overlayRef.dispose();
135
+ this.overlayRef = null;
136
+ }
137
+ }
138
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
139
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverService, providedIn: 'root' });
140
+ }
141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverService, decorators: [{
142
+ type: Injectable,
143
+ args: [{
144
+ providedIn: 'root'
145
+ }]
146
+ }] });
147
+
148
+ class JvsPopoverDirective {
149
+ popoverService = inject(JvsPopoverService);
150
+ elementRef = inject(ElementRef);
151
+ viewContainerRef = inject(ViewContainerRef);
152
+ content = input(null, { alias: 'jvsPopover' });
153
+ context = input(null);
154
+ trigger = input('hover');
155
+ position = input('bottom');
156
+ customClass = input('');
157
+ onMouseEnter() {
158
+ if (this.trigger() === 'hover') {
159
+ this.show();
160
+ }
161
+ }
162
+ onMouseLeave() {
163
+ if (this.trigger() === 'hover') {
164
+ this.hide();
165
+ }
166
+ }
167
+ onClick() {
168
+ if (this.trigger() === 'click') {
169
+ this.show();
170
+ }
171
+ }
172
+ onFocus() {
173
+ if (this.trigger() === 'focus') {
174
+ this.show();
175
+ }
176
+ }
177
+ onBlur() {
178
+ if (this.trigger() === 'focus') {
179
+ this.hide();
180
+ }
181
+ }
182
+ ngOnDestroy() {
183
+ this.hide();
184
+ }
185
+ show() {
186
+ const content = this.content();
187
+ if (!content)
188
+ return;
189
+ this.popoverService.open(this.elementRef.nativeElement, content, {
190
+ position: this.position(),
191
+ customClass: this.customClass(),
192
+ viewContainerRef: this.viewContainerRef,
193
+ context: this.context()
194
+ });
195
+ }
196
+ hide() {
197
+ this.popoverService.close();
198
+ }
199
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
200
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: JvsPopoverDirective, isStandalone: true, selector: "[jvsPopover]", inputs: { content: { classPropertyName: "content", publicName: "jvsPopover", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, customClass: { classPropertyName: "customClass", publicName: "customClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "click": "onClick()", "focusin": "onFocus()", "focusout": "onBlur()" } }, ngImport: i0 });
201
+ }
202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverDirective, decorators: [{
203
+ type: Directive,
204
+ args: [{
205
+ selector: '[jvsPopover]',
206
+ standalone: true
207
+ }]
208
+ }], propDecorators: { onMouseEnter: [{
209
+ type: HostListener,
210
+ args: ['mouseenter']
211
+ }], onMouseLeave: [{
212
+ type: HostListener,
213
+ args: ['mouseleave']
214
+ }], onClick: [{
215
+ type: HostListener,
216
+ args: ['click']
217
+ }], onFocus: [{
218
+ type: HostListener,
219
+ args: ['focusin']
220
+ }], onBlur: [{
221
+ type: HostListener,
222
+ args: ['focusout']
223
+ }] } });
224
+
225
+ class JvsPopoverListenerDirective {
226
+ popoverService = inject(JvsPopoverService);
227
+ elementRef = inject(ElementRef);
228
+ trigger = input('hover');
229
+ onMouseOver(event) {
230
+ if (this.trigger() !== 'hover')
231
+ return;
232
+ const target = this.findPopoverTarget(event.target);
233
+ if (target) {
234
+ const content = target.getAttribute('data-jvs-popover');
235
+ if (content) {
236
+ this.popoverService.open(target, content, {
237
+ position: target.getAttribute('data-jvs-position') || 'bottom',
238
+ customClass: target.getAttribute('data-jvs-class') || ''
239
+ });
240
+ }
241
+ }
242
+ }
243
+ onMouseOut(event) {
244
+ if (this.trigger() !== 'hover')
245
+ return;
246
+ this.popoverService.close();
247
+ }
248
+ onClick(event) {
249
+ if (this.trigger() !== 'click')
250
+ return;
251
+ const target = this.findPopoverTarget(event.target);
252
+ if (target) {
253
+ const content = target.getAttribute('data-jvs-popover');
254
+ if (content) {
255
+ this.popoverService.open(target, content, {
256
+ position: target.getAttribute('data-jvs-position') || 'bottom',
257
+ customClass: target.getAttribute('data-jvs-class') || ''
258
+ });
259
+ }
260
+ }
261
+ }
262
+ findPopoverTarget(el) {
263
+ while (el && el !== this.elementRef.nativeElement) {
264
+ if (el.hasAttribute('data-jvs-popover')) {
265
+ return el;
266
+ }
267
+ el = el.parentElement;
268
+ }
269
+ return null;
270
+ }
271
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverListenerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
272
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: JvsPopoverListenerDirective, isStandalone: true, selector: "[jvsPopoverListener]", inputs: { trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseover": "onMouseOver($event)", "mouseout": "onMouseOut($event)", "click": "onClick($event)" } }, ngImport: i0 });
273
+ }
274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsPopoverListenerDirective, decorators: [{
275
+ type: Directive,
276
+ args: [{
277
+ selector: '[jvsPopoverListener]',
278
+ standalone: true
279
+ }]
280
+ }], propDecorators: { onMouseOver: [{
281
+ type: HostListener,
282
+ args: ['mouseover', ['$event']]
283
+ }], onMouseOut: [{
284
+ type: HostListener,
285
+ args: ['mouseout', ['$event']]
286
+ }], onClick: [{
287
+ type: HostListener,
288
+ args: ['click', ['$event']]
289
+ }] } });
290
+
291
+ class JvsAutocompleteDirective {
292
+ destroyRef = inject(DestroyRef);
293
+ ngControl = inject(NgControl, { optional: true });
294
+ focus$ = new Subject();
295
+ // Signal-based Inputs
296
+ data = input(null);
297
+ fields = input('');
298
+ typeReq = input('');
299
+ queryService = input(null);
300
+ minLength = input(3);
301
+ dataExtra = input({});
302
+ anonimo = input(false);
303
+ debounce = input(300);
304
+ // Modern Outputs
305
+ filtered = output();
306
+ loading = output();
307
+ onFocus() {
308
+ this.focus$.next();
309
+ }
310
+ ngOnInit() {
311
+ const control = this.ngControl;
312
+ if (!control || !control.valueChanges) {
313
+ console.warn('JvsAutocompleteDirective: No se encontró ngControl o valueChanges. Asegúrate de que el input tenga un formControl o formControlName.');
314
+ return;
315
+ }
316
+ // Si es data local, bajamos el debounce por defecto a 0 si no se ha especificado
317
+ const isLocal = this.data() && !this.typeReq();
318
+ const actualDebounce = (isLocal && this.debounce() === 300) ? 0 : this.debounce();
319
+ merge(control.valueChanges.pipe(debounceTime(actualDebounce)), this.focus$).pipe(takeUntilDestroyed(this.destroyRef), startWith(control.value), distinctUntilChanged(), tap(() => {
320
+ if (this.typeReq())
321
+ this.loading.emit(true);
322
+ }), switchMap(() => {
323
+ const value = control.value;
324
+ // Si el valor es un objeto (proviene de seleccionar una opción), no volvemos a filtrar
325
+ if (typeof value === 'object' && value !== null) {
326
+ if (this.typeReq())
327
+ this.loading.emit(false);
328
+ return of(null);
329
+ }
330
+ if (this.typeReq() && this.queryService()) {
331
+ return this.fetchApi(value?.toString() || '');
332
+ }
333
+ else if (this.data()) {
334
+ const res = this.filterLocal(value?.toString() || '');
335
+ return of(res);
336
+ }
337
+ if (this.typeReq())
338
+ this.loading.emit(false);
339
+ return of([]);
340
+ })).subscribe((result) => {
341
+ if (result !== null) {
342
+ this.filtered.emit(result);
343
+ }
344
+ });
345
+ }
346
+ filterLocal(value) {
347
+ const data = this.data();
348
+ if (!value)
349
+ return data || [];
350
+ const search = value.toLowerCase();
351
+ const rawFields = this.fields();
352
+ const fields = Array.isArray(rawFields) ? rawFields : [rawFields];
353
+ return (data || []).filter(item => {
354
+ return fields.some(field => {
355
+ const val = item[field];
356
+ return val && val.toString().toLowerCase().includes(search);
357
+ });
358
+ });
359
+ }
360
+ fetchApi(value) {
361
+ const typeReq = this.typeReq();
362
+ const queryService = this.queryService();
363
+ if (!value || value.length < this.minLength()) {
364
+ this.loading.emit(false);
365
+ return of([]);
366
+ }
367
+ return queryService.getDataMethod('GET', typeReq, {
368
+ ...this.dataExtra(),
369
+ txtBuscar: value
370
+ }, this.anonimo()).pipe(map((res) => res[typeReq] ?? []), finalize(() => this.loading.emit(false)));
371
+ }
372
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
373
+ 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 });
374
+ }
375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JvsAutocompleteDirective, decorators: [{
376
+ type: Directive,
377
+ args: [{
378
+ selector: '[jvsAutocomplete]',
379
+ standalone: true
380
+ }]
381
+ }], propDecorators: { onFocus: [{
382
+ type: HostListener,
383
+ args: ['focus']
384
+ }] } });
385
+
386
+ class AutoSelectFirstDirective {
387
+ ngControl = inject(NgControl, { optional: true });
388
+ fcName = inject(FormControlName, { optional: true });
389
+ toastr = inject(ToastrService, { optional: true });
390
+ // Inputs using Signals
391
+ options = input(null, { alias: 'jvsAutoSelectFirst' });
392
+ jvsIdKey = input(null);
393
+ jvsEmptyMsg = input('Lista sin elementos');
394
+ onAutoSelect = output();
395
+ constructor() {
396
+ effect(() => {
397
+ const currentOptions = this.options();
398
+ const idKey = this.jvsIdKey();
399
+ const emptyMsg = this.jvsEmptyMsg();
400
+ if (currentOptions === null)
401
+ return;
402
+ const optionsArray = Array.isArray(currentOptions) ? currentOptions : [];
403
+ if (optionsArray.length > 0) {
404
+ untracked(() => {
405
+ const control = this.ngControl?.control;
406
+ const currentValue = control?.value;
407
+ // Only autoselect if empty
408
+ if (control && (currentValue === null || currentValue === undefined || currentValue === '')) {
409
+ const firstItem = optionsArray[0];
410
+ let valueToSet;
411
+ // Resolve key
412
+ let effectiveKey = idKey;
413
+ // Default to formControlName if not provided
414
+ if (!effectiveKey && this.fcName) {
415
+ effectiveKey = this.fcName.name;
416
+ }
417
+ if (effectiveKey) {
418
+ if (Array.isArray(effectiveKey)) {
419
+ // Composite key: build an object with the specified keys
420
+ valueToSet = {};
421
+ effectiveKey.forEach(key => {
422
+ valueToSet[key] = firstItem[key];
423
+ });
424
+ }
425
+ else {
426
+ valueToSet = firstItem[effectiveKey];
427
+ }
428
+ }
429
+ else {
430
+ // Use whole item if no key resolution possible
431
+ valueToSet = firstItem;
432
+ }
433
+ control.setValue(valueToSet);
434
+ this.onAutoSelect.emit(firstItem);
435
+ }
436
+ });
437
+ }
438
+ else if (emptyMsg && this.toastr) {
439
+ this.toastr.warning(emptyMsg, 'Filtrado');
440
+ }
441
+ });
442
+ }
443
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutoSelectFirstDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
444
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: AutoSelectFirstDirective, isStandalone: true, selector: "[jvsAutoSelectFirst]", inputs: { options: { classPropertyName: "options", publicName: "jvsAutoSelectFirst", isSignal: true, isRequired: false, transformFunction: null }, jvsIdKey: { classPropertyName: "jvsIdKey", publicName: "jvsIdKey", isSignal: true, isRequired: false, transformFunction: null }, jvsEmptyMsg: { classPropertyName: "jvsEmptyMsg", publicName: "jvsEmptyMsg", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAutoSelect: "onAutoSelect" }, ngImport: i0 });
445
+ }
446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AutoSelectFirstDirective, decorators: [{
447
+ type: Directive,
448
+ args: [{
449
+ selector: '[jvsAutoSelectFirst]',
450
+ standalone: true
451
+ }]
452
+ }], ctorParameters: () => [] });
453
+
454
+ /**
455
+ * Generated bundle index. Do not edit.
456
+ */
457
+
458
+ export { AutoSelectFirstDirective, AutocompleteMatchValidatorDirective, JvsAutocompleteDirective, JvsPopoverDirective, JvsPopoverListenerDirective, JvsPopoverPanelComponent, JvsPopoverService };
459
+ //# sourceMappingURL=jvsoft-utils-directives.mjs.map