utn-cli 2.1.56 → 2.1.57

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utn-cli",
3
- "version": "2.1.56",
3
+ "version": "2.1.57",
4
4
  "description": "Herramienta CLI unificada para la gestión de plantillas en SIGU.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "helmet": "^7.2.0",
26
26
  "jsonwebtoken": "^9.0.3",
27
27
  "mysql2": "^3.22.5",
28
- "nodemailer": "^8.0.11",
28
+ "nodemailer": "^9.0.1",
29
29
  "pdf-lib": "^1.17.1",
30
30
  "pdfkit": "^0.15.2"
31
31
  }
@@ -3,7 +3,7 @@
3
3
  "version": "0.0.0",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
- "start": "ng serve --host=0.0.0.0 --disable-host-check",
6
+ "start": "ng serve --host=0.0.0.0",
7
7
  "build": "ng build",
8
8
  "watch": "ng build --watch --configuration development",
9
9
  "test": "ng test"
@@ -1,12 +1,13 @@
1
1
  <div class="pagina">
2
2
  <div class="encabezado">
3
3
  <div class="encabezado-marca">
4
- @if(TienePermiso && esDashboard){
4
+ @if(TienePermiso() && esDashboard){
5
5
  <button class="botonDeNavegacion ColorBlanco" matTooltip="Módulos" title="Módulos" (click)="toggleSidebar()">
6
6
  <mat-icon>menu</mat-icon>
7
7
  </button>
8
- } @else if (TienePermiso) {
9
- <button class="botonDeNavegacion ColorBlanco" matTooltip="Menú principal" title="Menú principal" (click)="irAlInicio()">
8
+ } @else if (TienePermiso()) {
9
+ <button class="botonDeNavegacion ColorBlanco" matTooltip="Menú principal" title="Menú principal"
10
+ (click)="irAlInicio()">
10
11
  <mat-icon>home</mat-icon>
11
12
  </button>
12
13
  }
@@ -18,7 +19,7 @@
18
19
  <span class="encabezado-titulo-modulo">SIGU</span>
19
20
  </div>
20
21
  <div class="encabezado-acciones">
21
- @if(TienePermiso){
22
+ @if(TienePermiso()){
22
23
  <button class="botonDeNavegacion ColorBlanco" matTooltip="Ir atrás" title="Ir atrás" (click)="irAtras()">
23
24
  <mat-icon>arrow_back</mat-icon>
24
25
  </button>
@@ -62,7 +63,7 @@
62
63
  </div>
63
64
  <div class="zona-scrollable">
64
65
  <div [ngClass]="claseDelContenedor">
65
- <!-- @if(TienePermiso) {
66
+ <!-- @if(TienePermiso()) {
66
67
  <div class="botonesDeNavegacion">
67
68
  <button class="botonDeNavegacion" matTooltip="Ir atrás" title="Ir atrás" (click)="irAtras()">
68
69
  <mat-icon>arrow_back</mat-icon>
@@ -80,7 +81,7 @@
80
81
  </div>
81
82
  } -->
82
83
  <div class="contenido">
83
- @if(TienePermiso){
84
+ @if(TienePermiso()){
84
85
  @if(esDashboard && tieneTarjetas) {
85
86
  <div class="cabecera2">
86
87
  <div class="cabecera2-info">
@@ -117,9 +118,7 @@
117
118
  </div>
118
119
 
119
120
  @if (panelNotificacionesAbierto) {
120
- <app-panel-notificaciones
121
- [datos]="datosNotificaciones"
122
- (cerrar)="panelNotificacionesAbierto = false">
121
+ <app-panel-notificaciones [datos]="datosNotificaciones" (cerrar)="panelNotificacionesAbierto = false">
123
122
  </app-panel-notificaciones>
124
123
  }
125
124
 
@@ -1,5 +1,5 @@
1
1
  import { HttpClient } from '@angular/common/http';
2
- import { Component, OnInit, OnDestroy, NgZone, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';
2
+ import { Component, OnInit, OnDestroy, NgZone, AfterViewChecked, ViewChild, ElementRef, ChangeDetectorRef, signal } from '@angular/core';
3
3
  import { RouterOutlet, Router } from '@angular/router';
4
4
  import { DatosGlobalesService } from '../../../datos-globales.service';
5
5
  import { Location, CommonModule } from '@angular/common';
@@ -31,7 +31,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
31
31
  @ViewChild('filtroInput') filtroInput?: ElementRef<HTMLInputElement>;
32
32
  private focusDone = false;
33
33
 
34
- public TienePermiso: boolean = false;
34
+ public TienePermiso = signal<boolean>(false);
35
35
  public Titulo: string = '';
36
36
  public Modulo: string = '';
37
37
  public Version: string = '';
@@ -53,10 +53,10 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
53
53
  public itemsDeMenu: ItemDeMenu[] = [];
54
54
 
55
55
  get itemsDeMenuVisibles(): ItemDeMenu[] {
56
- return this.itemsDeMenu.filter(i => !i.requierePermiso || this.TienePermiso);
56
+ return this.itemsDeMenu.filter(i => !i.requierePermiso || this.TienePermiso());
57
57
  }
58
58
 
59
- get esDashboard(): boolean { return window.location.pathname === '/'; }
59
+ get esDashboard(): boolean { return typeof window !== 'undefined' ? window.location.pathname === '/' : true; }
60
60
 
61
61
  toggleSidebar(): void {
62
62
  const abriendo = !this.datosGlobalesService.sidebarVisible$.value;
@@ -80,19 +80,21 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
80
80
  }
81
81
 
82
82
  enfocarPrimeraTarjeta(event: Event): void {
83
+ if (typeof document === 'undefined') return;
83
84
  const primera = document.querySelector<HTMLElement>('.modulo-card[role="button"]');
84
85
  if (!primera) return;
85
86
  event.preventDefault();
86
87
  primera.focus();
87
88
  }
88
89
 
89
- constructor(private http: HttpClient, private datosGlobalesService: DatosGlobalesService, private location: Location, private dialog: MatDialog, private router: Router, private ngZone: NgZone) {
90
+ constructor(private http: HttpClient, private datosGlobalesService: DatosGlobalesService, private location: Location, private dialog: MatDialog, private router: Router, private ngZone: NgZone, private cdr: ChangeDetectorRef) {
90
91
  if (datosGlobalesService.ObtenerToken() === '') {
91
92
  datosGlobalesService.RedirigirALogin();
92
93
  }
93
94
  }
94
95
 
95
96
  obtenerMensajesModularesVisualizados(): string[] {
97
+ if (typeof localStorage === 'undefined') return [];
96
98
  const datos = localStorage.getItem('MensajesModularesVisualizados');
97
99
  return datos ? JSON.parse(datos) : [];
98
100
  }
@@ -123,6 +125,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
123
125
  if (item) item.posicion = c.Posicion;
124
126
  });
125
127
  this.itemsDeMenu.sort((a, b) => a.posicion - b.posicion);
128
+ this.cdr.detectChanges();
126
129
  },
127
130
  error: () => { }
128
131
  });
@@ -175,7 +178,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
175
178
  this.inicializarItemsDeMenu();
176
179
  this.cargarOrdenDelMenu();
177
180
 
178
- const url = window.location.href.toLowerCase();
181
+ const url = typeof window !== 'undefined' ? window.location.href.toLowerCase() : '';
179
182
  if (url.includes('calidad')) {
180
183
  this.claseDelContenedor = 'contenedor calidad';
181
184
  } else if (url.includes('pruebas')) {
@@ -194,8 +197,9 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
194
197
  this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/inicializar').subscribe(async (datos: any) => {
195
198
  const body = datos.body;
196
199
 
197
- this.TienePermiso = body.TienePermiso;
198
- if (!this.TienePermiso) {
200
+ this.TienePermiso.set(body.TienePermiso);
201
+ if (!this.TienePermiso()) {
202
+ this.cdr.detectChanges();
199
203
  this.Entrar();
200
204
  return;
201
205
  }
@@ -213,6 +217,8 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
213
217
  this.EnlaceDelVideo = body.EnlaceDelVideo;
214
218
  this.Mensajes = body.Notificaciones;
215
219
 
220
+ this.cdr.detectChanges();
221
+
216
222
  const { MensajeConfirmacionHTMLComponent } = await import('../../../Componentes/Nucleo/mensaje-confirmacion-html/mensaje-confirmacion-html');
217
223
 
218
224
  if (body.Consentimiento?.Aceptaciones === 0) {
@@ -318,7 +324,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
318
324
  irASabiasQue(): void {
319
325
  this.router.navigate(['/sabiasque']);
320
326
  }
321
-
327
+
322
328
  irAPreguntasFrecuentes(): void {
323
329
  this.router.navigate(['/preguntasfrecuentes']);
324
330
  }
@@ -1,5 +1,5 @@
1
1
  <div class="contenido" cdkDropList cdkDropListOrientation="mixed" (cdkDropListDropped)="drop($event)">
2
- @for (tarjeta of tarjetas; track tarjeta.titulo) {
2
+ @for (tarjeta of tarjetas(); track tarjeta.titulo) {
3
3
  <div cdkDrag [class.tarjeta-opaca]="esDimmed(tarjeta)">
4
4
  @if(isMobile) {
5
5
  <div class="drag-handle" cdkDragHandle aria-label="Arrastrar tarjeta">
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, OnDestroy, HostListener } from "@angular/core";
1
+ import { Component, OnInit, OnDestroy, HostListener, signal } from "@angular/core";
2
2
  import { CommonModule } from "@angular/common";
3
3
  import { Subject } from "rxjs";
4
4
  import { takeUntil } from "rxjs/operators";
@@ -66,14 +66,16 @@ type AnyTarjetaConfig = TarjetaConfig | TarjetaMultipleConfig | TarjetaReporteCo
66
66
  export class ContenedorPrincipalComponent implements OnInit, OnDestroy {
67
67
  public cantidad: number = 0;
68
68
  public cantidadMaxima: number = 0;
69
- public tarjetas: AnyTarjetaConfig[] = [];
70
- public filtro: string = '';
71
- public isMobile: boolean = window.innerWidth <= 768;
69
+ public tarjetas = signal<AnyTarjetaConfig[]>([]);
70
+ public filtro = signal<string>('');
71
+ public isMobile: boolean = typeof window !== 'undefined' ? window.innerWidth <= 768 : false;
72
72
  private destroy$ = new Subject<void>();
73
73
 
74
74
  @HostListener('window:resize')
75
75
  onResize(): void {
76
- this.isMobile = window.innerWidth <= 768;
76
+ if (typeof window !== 'undefined') {
77
+ this.isMobile = window.innerWidth <= 768;
78
+ }
77
79
  }
78
80
 
79
81
  constructor(private http: HttpClient, private datosGlobalesService: DatosGlobalesService, private dialog: MatDialog) {
@@ -87,23 +89,28 @@ export class ContenedorPrincipalComponent implements OnInit, OnDestroy {
87
89
  }
88
90
 
89
91
  esDimmed(tarjeta: AnyTarjetaConfig): boolean {
90
- if (!this.filtro.trim()) return false;
91
- return !tarjeta.titulo.toLowerCase().includes(this.filtro.toLowerCase());
92
+ const f = this.filtro();
93
+ if (!f.trim()) return false;
94
+ return !tarjeta.titulo.toLowerCase().includes(f.toLowerCase());
92
95
  }
93
96
 
94
97
  ngOnInit() {
95
98
  this.datosGlobalesService.filtroDeTarjetas$
96
99
  .pipe(takeUntil(this.destroy$))
97
- .subscribe(f => this.filtro = f);
100
+ .subscribe(f => {
101
+ this.filtro.set(f);
102
+ });
98
103
 
99
104
  this.http.get(`${this.datosGlobalesService.ObtenerURL()}misc/obtenerTarjetasDelContenedor`).subscribe({
100
105
  next: (datos: any) => {
101
- this.tarjetas = (datos.body ?? []).map((d: any) => this.mapearTarjeta(d));
102
- this.datosGlobalesService.cantidadDeTarjetas$.next(this.tarjetas.length);
106
+ console.log(datos)
107
+ const nuevasTarjetas = (datos.body ?? []).map((d: any) => this.mapearTarjeta(d));
108
+ this.tarjetas.set(nuevasTarjetas);
109
+ this.datosGlobalesService.cantidadDeTarjetas$.next(nuevasTarjetas.length);
103
110
  },
104
111
  error: (error) => {
105
112
  console.error('Error al obtener las tarjetas del contenedor:', error);
106
- this.tarjetas = [];
113
+ this.tarjetas.set([]);
107
114
  this.datosGlobalesService.cantidadDeTarjetas$.next(0);
108
115
  }
109
116
  });
@@ -143,15 +150,19 @@ export class ContenedorPrincipalComponent implements OnInit, OnDestroy {
143
150
  }
144
151
 
145
152
  drop(event: CdkDragDrop<AnyTarjetaConfig[]>) {
146
- moveItemInArray(this.tarjetas, event.previousIndex, event.currentIndex);
147
- this.tarjetas.forEach((tarjeta, index) => {
153
+ const tarjetasActuales = [...this.tarjetas()];
154
+ moveItemInArray(tarjetasActuales, event.previousIndex, event.currentIndex);
155
+
156
+ tarjetasActuales.forEach((tarjeta, index) => {
148
157
  tarjeta.position = (index + 1) * 10;
149
158
  });
159
+
160
+ this.tarjetas.set(tarjetasActuales);
150
161
  this.persistirConfiguracion();
151
162
  }
152
163
 
153
164
  persistirConfiguracion() {
154
- const Configuraciones = this.tarjetas.map(t => ({
165
+ const Configuraciones = this.tarjetas().map(t => ({
155
166
  Titulo: t.titulo,
156
167
  Posicion: t.position,
157
168
  ColorDeBorde: t.ColorDeBorde
@@ -2,7 +2,6 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
2
2
  import { provideRouter } from '@angular/router';
3
3
 
4
4
  import { routes } from './app.routes';
5
- import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
6
5
  import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
7
6
  import { provideHttpClient, withFetch, withInterceptors } from '@angular/common/http';
8
7
  import { MatPaginatorIntl } from '@angular/material/paginator';
@@ -16,7 +15,6 @@ export const appConfig: ApplicationConfig = {
16
15
  { provide: MatPaginatorIntl, useClass: PaginadorPersonalizado },
17
16
  provideZoneChangeDetection({ eventCoalescing: true }),
18
17
  provideRouter(routes),
19
- provideClientHydration(withEventReplay()),
20
18
  provideAnimationsAsync(),
21
19
  provideHttpClient(withFetch(), withInterceptors([AuthInterceptor])),
22
20
  provideCharts(withDefaultRegisterables()),
@@ -15,8 +15,9 @@ export class DatosGlobalesService {
15
15
  ObtenerToken() {
16
16
  const baseUrl = this.ObtenerURL();
17
17
  if (baseUrl === 'http://localhost/') {
18
- return 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxMiIsIklkZW50aWZpY2Fkb3IiOiIxMiIsImlhdCI6MTc3OTcxNjM5NCwiZXhwIjoxNzc5NzUyMzk0fQ.43_5Rnqyi-ArRpND81Z1MoPHluQbilX13AED102ilgQ';
18
+ return 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxMiIsIklkZW50aWZpY2Fkb3IiOiIxMiIsImlhdCI6MTc4MTgxNTQwNSwiZXhwIjoxNzgxODUxNDA1fQ.0Z-wvoJXT21HFe817Xl7jai45s8p1qwCMyfsG_2X5SA';
19
19
  }
20
+ if (typeof document === 'undefined') return '';
20
21
  const match = document.cookie.match(/(?:^|;\s*)_siguid=([^;]+)/);
21
22
  let token = match ? decodeURIComponent(match[1]) : '';
22
23
  if (token && !token.startsWith('Bearer ')) {
@@ -26,6 +27,7 @@ export class DatosGlobalesService {
26
27
  }
27
28
 
28
29
  ObtenerURL(): string {
30
+ if (typeof window === 'undefined') return 'http://localhost/';
29
31
  const { origin } = new URL(window.location.href);
30
32
  if (origin === 'http://localhost:4200') {
31
33
  return 'http://localhost/';
@@ -34,35 +36,18 @@ export class DatosGlobalesService {
34
36
  }
35
37
 
36
38
  RedirigirALogin() {
37
- // document.cookie = "_siguid=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
38
- // const url = window.location.href.toLowerCase();
39
- // if (url.includes('calidad')) {
40
- // this.claseDelContenedor = 'contenedor calidad';
41
- // } else if (url.includes('pruebas')) {
42
- // this.claseDelContenedor = 'contenedor pruebas';
43
- // } else {
44
- // this.claseDelContenedor = 'contenedor';
45
- // }
46
- // portalv2-frontend-pruebas
47
- // const protocolo = new URL(window.location.href).protocol
48
- // window.location.href = 'https://accesov2-frontend.sigu.utn.ac.cr/';
49
- document.cookie = "_siguid=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
50
- const redirect = encodeURIComponent(window.location.href);
51
- window.location.href = `https://accesov2-frontend.sigu.utn.ac.cr/?redirect=${redirect}`;
39
+ if (typeof document !== 'undefined') document.cookie = "_siguid=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
40
+ if (typeof window !== 'undefined') {
41
+ const redirect = encodeURIComponent(window.location.href);
42
+ window.location.href = `https://accesov2-frontend.sigu.utn.ac.cr/?redirect=${redirect}`;
43
+ }
52
44
  }
53
45
 
54
46
  RedirigirAPortal() {
55
- document.cookie = "_siguid=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
56
- // const url = window.location.href.toLowerCase();
57
- // if (url.includes('calidad')) {
58
- // this.claseDelContenedor = 'contenedor calidad';
59
- // } else if (url.includes('pruebas')) {
60
- // this.claseDelContenedor = 'contenedor pruebas';
61
- // } else {
62
- // this.claseDelContenedor = 'contenedor';
63
- // }
64
- // portalv2-frontend-pruebas
65
- // const protocolo = new URL(window.location.href).protocol
66
- window.location.href = 'https://portalv2-frontend.sigu.utn.ac.cr/';
47
+ if (typeof document !== 'undefined') document.cookie = "_siguid=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
48
+ if (typeof window !== 'undefined') {
49
+ window.location.href = 'https://portalv2-frontend.sigu.utn.ac.cr/';
50
+ }
67
51
  }
68
52
  }
53
+