ngx-dsxlibrary 1.0.58 → 1.0.60

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.
@@ -14,8 +14,8 @@ import * as i1$2 from 'primeng/menubar';
14
14
  import { MenubarModule } from 'primeng/menubar';
15
15
  import { ToastrService } from 'ngx-toastr';
16
16
  import Swal from 'sweetalert2';
17
+ import { of, retry, delay, map, throwError, catchError, switchMap, finalize, Observable } from 'rxjs';
17
18
  import { HttpClient, HttpHeaders, HttpParams, HttpStatusCode, HttpErrorResponse } from '@angular/common/http';
18
- import { throwError, catchError, switchMap, finalize, Observable } from 'rxjs';
19
19
  import { JwtHelperService } from '@auth0/angular-jwt';
20
20
  import { CookieService } from 'ngx-cookie-service';
21
21
  import { CommonModule } from '@angular/common';
@@ -211,11 +211,11 @@ class LoadingComponent {
211
211
  // Accedemos directamente a la señal del servicio
212
212
  _spinnerService = inject(SpinnerLoadingService);
213
213
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
214
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: LoadingComponent, isStandalone: true, selector: "app-loading", ngImport: i0, template: "<!-- Actualizaci\u00F3n 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"assets/dsxResource/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#000c;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:9999}.loader{display:flex;justify-content:center;align-items:center;position:relative;cursor:not-allowed;scale:.7}.central{display:flex;justify-content:center;align-items:center;position:relative;width:10em;height:10em;border-radius:50%;box-shadow:.5em 1em 1em #8a2be2,-.5em .5em 1em #00f,.5em -.5em 1em purple,-.5em -.5em 1em #0ff;background-color:#0000004d}.external-shadow{width:10em;height:10em;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;box-shadow:.5em .5em 3em #8a2be2,-.5em .5em 3em #00f,.5em -.5em 3em purple,-.5em -.5em 3em #0ff;z-index:999;animation:rotate 3s linear infinite;background-color:#21212180}@keyframes rotate{0%{transform:rotate(0)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}}.spinner-image{width:70%;height:70%;border-radius:50%;object-fit:cover;position:absolute;z-index:1000}.loading-text{font-family:Montserrat,sans-serif;text-transform:uppercase;letter-spacing:3px;background:linear-gradient(45deg,#0ff,#f0f);-webkit-background-clip:text;background-clip:text;color:transparent}@keyframes pulse{0%,to{opacity:.7}50%{opacity:1}}\n"] });
214
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: LoadingComponent, isStandalone: true, selector: "app-loading", ngImport: i0, template: "<!-- Actualizaci\u00F3n 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"assets/dsxResource/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#000000e6;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:9999}.loader{display:flex;justify-content:center;align-items:center;position:relative;cursor:not-allowed;scale:.8}.central{display:flex;justify-content:center;align-items:center;position:relative;width:10em;height:10em;border-radius:50%;box-shadow:.5em 1em 1em #8a2be2,-.5em .5em 1em #00f,.5em -.5em 1em purple,-.5em -.5em 1em #0ff;background-color:#0003}.external-shadow{width:10em;height:10em;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;box-shadow:.5em .5em 3em #8a2be2,-.5em .5em 3em #00f,.5em -.5em 3em purple,-.5em -.5em 3em #0ff;z-index:999;animation:rotate 3s linear infinite;background-color:#21212180}@keyframes rotate{0%{transform:rotate(0)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}}.spinner-image{width:70%;height:70%;border-radius:50%;object-fit:cover;position:absolute;z-index:1000}.loading-text{font-family:Montserrat,sans-serif;text-transform:uppercase;letter-spacing:3px;background:linear-gradient(45deg,#0ff,#f0f);-webkit-background-clip:text;background-clip:text;color:transparent;margin-top:1em}@keyframes pulse{0%,to{opacity:.7}50%{opacity:1}}\n"] });
215
215
  }
216
216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LoadingComponent, decorators: [{
217
217
  type: Component,
218
- args: [{ selector: 'app-loading', imports: [], template: "<!-- Actualizaci\u00F3n 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"assets/dsxResource/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#000c;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:9999}.loader{display:flex;justify-content:center;align-items:center;position:relative;cursor:not-allowed;scale:.7}.central{display:flex;justify-content:center;align-items:center;position:relative;width:10em;height:10em;border-radius:50%;box-shadow:.5em 1em 1em #8a2be2,-.5em .5em 1em #00f,.5em -.5em 1em purple,-.5em -.5em 1em #0ff;background-color:#0000004d}.external-shadow{width:10em;height:10em;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;box-shadow:.5em .5em 3em #8a2be2,-.5em .5em 3em #00f,.5em -.5em 3em purple,-.5em -.5em 3em #0ff;z-index:999;animation:rotate 3s linear infinite;background-color:#21212180}@keyframes rotate{0%{transform:rotate(0)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}}.spinner-image{width:70%;height:70%;border-radius:50%;object-fit:cover;position:absolute;z-index:1000}.loading-text{font-family:Montserrat,sans-serif;text-transform:uppercase;letter-spacing:3px;background:linear-gradient(45deg,#0ff,#f0f);-webkit-background-clip:text;background-clip:text;color:transparent}@keyframes pulse{0%,to{opacity:.7}50%{opacity:1}}\n"] }]
218
+ args: [{ selector: 'app-loading', imports: [], template: "<!-- Actualizaci\u00F3n 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"assets/dsxResource/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#000000e6;display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:9999}.loader{display:flex;justify-content:center;align-items:center;position:relative;cursor:not-allowed;scale:.8}.central{display:flex;justify-content:center;align-items:center;position:relative;width:10em;height:10em;border-radius:50%;box-shadow:.5em 1em 1em #8a2be2,-.5em .5em 1em #00f,.5em -.5em 1em purple,-.5em -.5em 1em #0ff;background-color:#0003}.external-shadow{width:10em;height:10em;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;box-shadow:.5em .5em 3em #8a2be2,-.5em .5em 3em #00f,.5em -.5em 3em purple,-.5em -.5em 3em #0ff;z-index:999;animation:rotate 3s linear infinite;background-color:#21212180}@keyframes rotate{0%{transform:rotate(0)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}}.spinner-image{width:70%;height:70%;border-radius:50%;object-fit:cover;position:absolute;z-index:1000}.loading-text{font-family:Montserrat,sans-serif;text-transform:uppercase;letter-spacing:3px;background:linear-gradient(45deg,#0ff,#f0f);-webkit-background-clip:text;background-clip:text;color:transparent;margin-top:1em}@keyframes pulse{0%,to{opacity:.7}50%{opacity:1}}\n"] }]
219
219
  }], ctorParameters: () => [] });
220
220
 
221
221
  class AlertaService {
@@ -267,6 +267,7 @@ class AlertaService {
267
267
  return this.preloadImage(icono).then(() => Swal.fire({
268
268
  title: title,
269
269
  html: text,
270
+ //theme: 'borderless',
270
271
  footer: '<strong>DevSoftXela</strong> 2025',
271
272
  imageUrl: `assets/dsxResource/${icono}`,
272
273
  imageWidth: 150,
@@ -415,72 +416,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
415
416
 
416
417
  const INITIAL_PARAMETERS = new InjectionToken('InitialParameters');
417
418
 
418
- class ParameterValuesService {
419
- // Inyecta INITIAL_PARAMETERS usando inject()
420
- initialParameters = inject(INITIAL_PARAMETERS);
421
- // Inicializa con valores predeterminados usando una Signal
422
- _dataParameter = signal(this.initialParameters, ...(ngDevMode ? [{ debugName: "_dataParameter" }] : []));
423
- // Getter para acceder a los valores actuales
424
- get dataParameter() {
425
- return this._dataParameter();
426
- }
427
- // Setter para actualizar los valores
428
- set dataParameter(values) {
429
- this._dataParameter.set(values);
430
- }
431
- getAllParameterValues(data) {
432
- // Verifica si los datos de la API son válidos
433
- if (!data || !data.parameterSecurity) {
434
- console.error('Los datos proporcionados desde la API no son válidos.');
435
- return [];
436
- }
437
- // Obtén los parámetros iniciales y de la API
438
- const initialParameters = this._dataParameter();
439
- const apiParameters = data.parameterSecurity;
440
- // Compara las cantidades
441
- if (initialParameters.length !== apiParameters.length) {
442
- console.warn(`Advertencia: La cantidad de parámetros inicializados (${initialParameters.length}) no coincide con la cantidad de parámetros cargados desde la API (${apiParameters.length}).`);
443
- }
444
- // Validación de nombres de parámetros
445
- const initialParameterNames = initialParameters.map((p) => p.parameterName);
446
- const apiParameterNames = apiParameters.map((p) => p.parameterName);
447
- // Encuentra parámetros faltantes o adicionales
448
- const missingParameters = initialParameterNames.filter((name) => !apiParameterNames.includes(name));
449
- const extraParameters = apiParameterNames.filter((name) => !initialParameterNames.includes(name));
450
- // Reporta discrepancias
451
- if (missingParameters.length > 0) {
452
- console.error(`Error: Los siguientes parámetros no se encontraron en la API: ${missingParameters.join(', ')}`);
453
- }
454
- if (extraParameters.length > 0) {
455
- console.warn(`Advertencia: La API devolvió parámetros no esperados: ${extraParameters.join(', ')}`);
456
- }
457
- // Transforma los datos de la API al formato MyParameterValues
458
- return apiParameters
459
- .filter((param) => initialParameterNames.includes(param.parameterName))
460
- .map((param) => ({
461
- parameterName: param.parameterName,
462
- values: param.parameterValues
463
- ? param.parameterValues.map((v) => v.value)
464
- : [],
465
- }));
466
- }
467
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
468
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, providedIn: 'root' });
469
- }
470
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, decorators: [{
471
- type: Injectable,
472
- args: [{
473
- providedIn: 'root',
474
- }]
475
- }] });
476
-
477
419
  class SecurityService {
478
420
  // Inyecta el servicio HttpClient para realizar peticiones HTTP
479
421
  http = inject(HttpClient);
480
422
  // Inyecta la configuración del entorno usando el token ENVIRONMENT
481
423
  environment = inject(ENVIRONMENT);
482
424
  // Construye la URL base de la API utilizando la URL de la aplicación desde la configuración del entorno
483
- urlApi = `${this.environment.myAppUrl}api/authorize`;
425
+ urlApi = `${this.environment.myAppUrl}api/auth`;
484
426
  /**
485
427
  * Método para obtener un nuevo token de acceso utilizando un refresh token.
486
428
  * @param refreshToken El refresh token que se utilizará para obtener un nuevo token de acceso.
@@ -490,7 +432,7 @@ class SecurityService {
490
432
  // Crea el cuerpo de la solicitud con el refresh token
491
433
  const body = { refreshToken };
492
434
  // Realiza una solicitud POST al endpoint de refresco de token
493
- return this.http.post(`${this.urlApi}/TokenRefresh/`, body, {
435
+ return this.http.post(`${this.urlApi}/token-refresh/`, body, {
494
436
  headers: new HttpHeaders({
495
437
  'Content-Type': 'application/json', // Establece el tipo de contenido como JSON
496
438
  }),
@@ -506,7 +448,7 @@ class SecurityService {
506
448
  // parametro diseñado para invalidar la caché a traves del filtro
507
449
  const params = new HttpParams().set('invalidCacheParam', invalidCacheParam.toString());
508
450
  // Realiza una solicitud GET al endpoint de parámetros de seguridad
509
- return this.http.get(`${this.urlApi}/securityParameter/`, { params });
451
+ return this.http.get(`${this.urlApi}/security-parameter/`, { params });
510
452
  }
511
453
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SecurityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
512
454
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SecurityService, providedIn: 'root' });
@@ -518,6 +460,159 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
518
460
  }]
519
461
  }] });
520
462
 
463
+ /**
464
+ * Servicio para gestionar los parámetros de seguridad de la aplicación.
465
+ * Permite cargar los parámetros desde la API, mantenerlos en memoria, y acceder
466
+ * a sus valores de forma segura evitando `undefined` en los componentes.
467
+ */
468
+ class ParameterValuesService {
469
+ /** Parámetros iniciales inyectados mediante INITIAL_PARAMETERS */
470
+ initialParameters = inject(INITIAL_PARAMETERS);
471
+ /** Servicio que contiene el método getParameterSecurity() */
472
+ apiService = inject(SecurityService);
473
+ /** Señal que contiene los parámetros cargados */
474
+ _dataParameter = signal(this.initialParameters, ...(ngDevMode ? [{ debugName: "_dataParameter" }] : []));
475
+ /** Flag que indica si ya se cargaron los parámetros desde la API */
476
+ _loaded = false;
477
+ /** ===================== GETTERS/SETTERS ===================== */
478
+ /**
479
+ * Devuelve los parámetros actuales como un array de solo lectura.
480
+ */
481
+ get dataParameter() {
482
+ return this._dataParameter();
483
+ }
484
+ /**
485
+ * Setter privado para actualizar los parámetros.
486
+ * Solo puede ser usado dentro del servicio para mantener la integridad de los datos.
487
+ * @param values Array de parámetros a almacenar
488
+ */
489
+ setDataParameter(values) {
490
+ if (!Array.isArray(values)) {
491
+ console.error('Error: valores inválidos para dataParameter');
492
+ return;
493
+ }
494
+ this._dataParameter.set(values);
495
+ }
496
+ /** ===================== MÉTODOS PRINCIPALES ===================== */
497
+ /**
498
+ * Carga los parámetros desde la API.
499
+ * Si ya se cargaron y force=false, devuelve la copia en memoria.
500
+ * @param force Indica si se debe forzar la recarga desde la API (default: false)
501
+ * @returns Observable que emite los parámetros cargados como MyParameterValues[]
502
+ */
503
+ loadParameters(force = false) {
504
+ if (this._loaded && !force) {
505
+ return of([...this.dataParameter]); // copia mutable
506
+ }
507
+ return this.apiService.getParameterSecurity(force).pipe(retry({
508
+ count: 3,
509
+ delay: (error, retryCount) => {
510
+ console.warn(`Reintentando carga de parámetros (${retryCount})...`, error);
511
+ // espera progresiva
512
+ return of(null).pipe(delay(1000 * retryCount));
513
+ },
514
+ }), map((response) => {
515
+ const apiParameters = response.parameterSecurity ?? [];
516
+ this.validateParameters(apiParameters);
517
+ const values = this.mapToMyParameterValues(apiParameters);
518
+ this.setDataParameter(values);
519
+ this._loaded = true;
520
+ return values;
521
+ }));
522
+ }
523
+ /**
524
+ * Fuerza la recarga de los parámetros desde la API.
525
+ * @returns Observable que emite los parámetros actualizados
526
+ */
527
+ refreshParameters() {
528
+ return this.loadParameters(true);
529
+ }
530
+ /** ===================== MÉTODOS PRIVADOS ===================== */
531
+ /**
532
+ * Valida que los parámetros devueltos por la API coincidan con los iniciales.
533
+ * Muestra errores o advertencias en consola si existen diferencias.
534
+ * @param apiParameters Parámetros recibidos desde la API
535
+ */
536
+ validateParameters(apiParameters) {
537
+ const initialNames = this.initialParameters.map((p) => p.parameterName);
538
+ const apiNames = apiParameters.map((p) => p.parameterName);
539
+ const missing = initialNames.filter((name) => !apiNames.includes(name));
540
+ const extra = apiNames.filter((name) => !initialNames.includes(name));
541
+ if (missing.length)
542
+ console.error(`Faltan en API: ${missing.join(', ')}`);
543
+ if (extra.length)
544
+ console.warn(`Extra en API: ${extra.join(', ')}`);
545
+ if (initialNames.length !== apiNames.length) {
546
+ console.warn(`Cantidad distinta: iniciales=${initialNames.length}, api=${apiNames.length}`);
547
+ }
548
+ }
549
+ /**
550
+ * Transforma un array de ParameterSecurity en MyParameterValues
551
+ * @param apiParameters Parámetros recibidos desde la API
552
+ * @returns Array de MyParameterValues
553
+ */
554
+ mapToMyParameterValues(apiParameters) {
555
+ const initialNames = this.initialParameters.map((p) => p.parameterName);
556
+ return apiParameters
557
+ .filter((param) => initialNames.includes(param.parameterName))
558
+ .map((param) => ({
559
+ parameterName: param.parameterName,
560
+ values: param.parameterValues?.map((v) => v.value) ?? [],
561
+ }));
562
+ }
563
+ /** ===================== HELPERS SEGUROS ===================== */
564
+ /**
565
+ * Obtiene un valor específico de un parámetro.
566
+ * Devuelve `defaultValue` si no existe o el índice es inválido.
567
+ * @param parameterName Nombre del parámetro
568
+ * @param index Índice del valor dentro del array (default: 0)
569
+ * @param defaultValue Valor por defecto si no existe
570
+ * @returns Valor del parámetro o defaultValue
571
+ */
572
+ getValue(parameterName, index = 0, defaultValue = null) {
573
+ const param = this.dataParameter.find((p) => p.parameterName === parameterName);
574
+ if (!param || index < 0 || index >= param.values.length) {
575
+ return defaultValue;
576
+ }
577
+ return param.values[index];
578
+ }
579
+ /**
580
+ * Compara un valor específico con un valor esperado.
581
+ * @param parameterName Nombre del parámetro
582
+ * @param expectedValue Valor esperado
583
+ * @param index Índice del valor dentro del array (default: 0)
584
+ * @returns true si coincide, false en caso contrario
585
+ */
586
+ isParameterValue(parameterName, expectedValue, index = 0) {
587
+ return this.getValue(parameterName, index) === expectedValue;
588
+ }
589
+ /**
590
+ * Verifica si un parámetro tiene al menos un valor.
591
+ * @param parameterName Nombre del parámetro
592
+ * @returns true si tiene al menos un valor, false si no tiene
593
+ */
594
+ hasAnyValue(parameterName) {
595
+ return this.getAllValues(parameterName).length > 0;
596
+ }
597
+ /**
598
+ * Devuelve todos los valores de un parámetro.
599
+ * @param parameterName Nombre del parámetro
600
+ * @returns Array de valores
601
+ */
602
+ getAllValues(parameterName) {
603
+ return (this.dataParameter.find((p) => p.parameterName === parameterName)
604
+ ?.values ?? []);
605
+ }
606
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
607
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, providedIn: 'root' });
608
+ }
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ParameterValuesService, decorators: [{
610
+ type: Injectable,
611
+ args: [{
612
+ providedIn: 'root',
613
+ }]
614
+ }] });
615
+
521
616
  class NavbarDsxComponent {
522
617
  _securityService = inject(SecurityService);
523
618
  _parameterSecurityService = inject(ParameterValuesService);
@@ -555,13 +650,15 @@ class NavbarDsxComponent {
555
650
  localStorage.setItem('theme', theme);
556
651
  }
557
652
  actualizarSeguridadIT() {
558
- this._securityService.getParameterSecurity(true).subscribe({
559
- next: (response) => {
560
- const values = this._parameterSecurityService.getAllParameterValues(response);
561
- this._parameterSecurityService.dataParameter = values;
653
+ this._parameterSecurityService.refreshParameters().subscribe({
654
+ next: (values) => {
562
655
  this._alertaService.toastrAlerts(2, 'SeguridadIT', 'Parametro actualizado!', 2);
656
+ console.log('Parámetros cargados:', values);
657
+ },
658
+ error: (err) => {
659
+ console.error('Error al actualizar parámetros de SeguridadIT', err);
660
+ this._alertaService.toastrAlerts(3, 'SeguridadIT', 'Error al actualizar parámetros!', 2);
563
661
  },
564
- error: (err) => console.log(err),
565
662
  complete: () => '',
566
663
  });
567
664
  }
@@ -853,7 +950,7 @@ const httpAuthorizeInterceptor = (req, next) => {
853
950
  _activeRequest++;
854
951
  // Función para controlar el spinner.hide()
855
952
  const hideSpinner = () => {
856
- // Solo oculta si NO está en modo depuración
953
+ // Se debe comentarizar para evitar que se oculte el spinner inmediatamente
857
954
  _spinnerService.hide();
858
955
  };
859
956
  return next(authReq).pipe(catchError((error) => {
@@ -943,6 +1040,13 @@ function createInitialCache(cacheKeys) {
943
1040
  return Object.fromEntries(Object.values(cacheKeys).map((key) => [key, false]));
944
1041
  }
945
1042
 
1043
+ const INITIAL_PARAMETERS_FOR_TYPE = [
1044
+ 'pCreate',
1045
+ 'pRead',
1046
+ 'pUpdate',
1047
+ 'pDelete',
1048
+ ];
1049
+
946
1050
  class DsxAddToolsModule {
947
1051
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DsxAddToolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
948
1052
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: DsxAddToolsModule, imports: [JsonValuesDebujComponent], exports: [CommonModule,
@@ -1119,23 +1223,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1119
1223
  * Este servicio utiliza señales (`signal`) para almacenar el estado de invalidación de caché
1120
1224
  * y permite marcar ciertas entradas como inválidas mediante una llamada a `invalidate`.
1121
1225
  *
1122
- * ### Ejemplo de definición del mapa de claves:
1226
+ * ---
1227
+ * ## Uso básico
1228
+ * Si no se especifica el tipo genérico `T`, el servicio funcionará con un mapa genérico
1229
+ * `Record<string, string>` sin autocompletado.
1230
+ *
1231
+ * ```ts
1232
+ * const cacheService = inject(CacheService);
1233
+ * cacheService.invalidate(['cualquierClave']);
1234
+ * ```
1235
+ *
1236
+ * ---
1237
+ * ## Uso tipado (recomendado)
1238
+ * 1. Definir las claves de caché en el proyecto consumidor:
1123
1239
  * ```ts
1124
- * export const CACHE_KEYS = {
1240
+ * export const INITIAL_CACHE_KEYS = {
1125
1241
  * cliente: 'invalidateCacheCliente',
1126
1242
  * empresa: 'invalidateCacheEmpresa'
1127
1243
  * } as const;
1244
+ *
1245
+ * export type ValueCacheKeys = typeof INITIAL_CACHE_KEYS;
1128
1246
  * ```
1129
1247
  *
1130
- * ### Ejemplo de uso:
1248
+ * 2. Proveer estas claves en `AppModule` o un módulo raíz:
1131
1249
  * ```ts
1132
- * const cacheService = inject(CacheService<typeof CACHE_KEYS>);
1250
+ * providers: [
1251
+ * { provide: CACHE_KEYS, useValue: INITIAL_CACHE_KEYS }
1252
+ * ]
1253
+ * ```
1254
+ *
1255
+ * 3. Inyectar el servicio especificando el tipo:
1256
+ * ```ts
1257
+ * const cacheService = inject<CacheService<ValueCacheKeys>>(CacheService);
1133
1258
  *
1134
- * cacheService.options.invalidateCacheCliente; // acceso tipado
1135
- * cacheService.invalidate(['cliente']); // marca la propiedad como true
1259
+ * cacheService.options.invalidateCacheCliente; // boolean con autocompletado
1260
+ * cacheService.invalidate(['cliente']); // marca como invalidado
1136
1261
  * ```
1137
1262
  *
1138
- * @typeParam T - Objeto con claves simbólicas como `cliente`, `empresa`, y valores string literales usados como claves reales de caché.
1263
+ * @typeParam T - Objeto con claves simbólicas (`keyof T`) como `cliente`, `empresa`,
1264
+ * y valores string literales usados como claves reales de caché.
1265
+ * Por defecto: `Record<string, string>`.
1139
1266
  */
1140
1267
  class CacheService {
1141
1268
  /**
@@ -1194,6 +1321,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1194
1321
  }]
1195
1322
  }] });
1196
1323
 
1324
+ function createTypedCacheProvider(tokenName) {
1325
+ const token = new InjectionToken(tokenName);
1326
+ const provider = {
1327
+ provide: token,
1328
+ useFactory: () => new CacheService(),
1329
+ deps: [],
1330
+ };
1331
+ return { token, provider };
1332
+ }
1333
+
1197
1334
  class EndpointService {
1198
1335
  http = inject(HttpClient);
1199
1336
  environment = inject(ENVIRONMENT);
@@ -1790,5 +1927,5 @@ function CUICorrecto(cui) {
1790
1927
  * Generated bundle index. Do not edit.
1791
1928
  */
1792
1929
 
1793
- export { AlertaService, AppMessageErrorComponent, AuthorizeService, CACHE_KEYS, CacheService, DsxAddToolsModule, ENVIRONMENT, EndpointService, INITIAL_PARAMETERS, JsonHighlightPipe, JsonValuesDebujComponent, KpicardComponent, LoadingComponent, NavbarDsxComponent, OnlyRangoPatternDirective, ParameterValuesService, PrimeNgModule, SecurityService, SelectAllOnFocusDirective, TruncatePipe, UtilityAddService, atLeastOneFieldRequiredValidator, createInitialCache, cuiValidator, dateMinMaxValidator, dateRangeValidator, httpAuthorizeInterceptor, nitValidator };
1930
+ export { AlertaService, AppMessageErrorComponent, AuthorizeService, CACHE_KEYS, CacheService, DsxAddToolsModule, ENVIRONMENT, EndpointService, INITIAL_PARAMETERS, JsonHighlightPipe, JsonValuesDebujComponent, KpicardComponent, LoadingComponent, NavbarDsxComponent, OnlyRangoPatternDirective, ParameterValuesService, PrimeNgModule, SecurityService, SelectAllOnFocusDirective, TruncatePipe, UtilityAddService, atLeastOneFieldRequiredValidator, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, httpAuthorizeInterceptor, nitValidator };
1794
1931
  //# sourceMappingURL=ngx-dsxlibrary.mjs.map