utn-cli 2.0.34 → 2.0.36

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.0.34",
3
+ "version": "2.0.36",
4
4
  "description": "Herramienta CLI unificada para la gestión de plantillas en SIGU.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -4,6 +4,14 @@ const Router = express.Router();
4
4
  const Miscelaneo = require('./../servicios/Nucleo/Miscelaneas.js');
5
5
  const ManejadorDeErrores = require('../servicios/Nucleo/ManejadorDeErrores.js');
6
6
 
7
+ Router.post('/Verificar2FA', async (solicitud, respuesta, next) => {
8
+ try {
9
+ return respuesta.json({ body: await Miscelaneo.Verificar2FA(solicitud), error: undefined });
10
+ } catch (error) {
11
+ next(error);
12
+ }
13
+ });
14
+
7
15
  Router.get('/DatosParaReporteCSV', async (solicitud, respuesta, next) => {
8
16
  try {
9
17
  if (await Miscelaneo.validarTokenV2(solicitud.headers.authorization) && await Miscelaneo.validarAccesoDelOrigen(solicitud)) {
@@ -23,7 +23,7 @@ class ConsentimientoInformado {
23
23
 
24
24
  async AceptarConsentimientoInformado(Datos) {
25
25
  // Por agilidad no se usa el nombre formal de la tabla
26
- return await ejecutarConsulta("INSERT INTO `AceptacionesDeConsentimientosInformados` VALUES \
26
+ return await ejecutarConsulta("INSERT INTO `" + Miscelaneas.obtenerNombreLaBaseDeDatos() + "`.`AceptacionesDeConsentimientosInformados` VALUES \
27
27
  (NULL, ?, ?, 'Aceptación de versión de módulo', UUID(), NOW(4), NOW(4), ?)"
28
28
  , [await this.ConsentimientoInformadoId(), Datos.LastUser.split("@")[0], Datos.LastUser]);
29
29
  }
@@ -41,7 +41,7 @@ class ConsentimientoInformado {
41
41
 
42
42
  async ConsentimientoInformado(Datos) {
43
43
  // Por agilidad no se usa el nombre formal de la tabla
44
- const Aceptaciones = await ejecutarConsulta("SELECT COUNT(*) AS `Total` FROM `AceptacionesDeConsentimientosInformados` \
44
+ const Aceptaciones = await ejecutarConsulta("SELECT COUNT(*) AS `Total` FROM `" + Miscelaneas.obtenerNombreLaBaseDeDatos() + "`.`AceptacionesDeConsentimientosInformados` \
45
45
  WHERE `ConsentimientoInformadoId` = ? AND `Identificador` = ?"
46
46
  , [await this.ConsentimientoInformadoId(), Datos.LastUser.split("@")[0]]);
47
47
  const ValoresARetornar = {};
@@ -1,4 +1,4 @@
1
- const { ejecutarConsulta, ejecutarConsultaSIGU, ejecutarConsultaCumulo } = require('./db.js');
1
+ const { ejecutarConsulta, ejecutarConsultaSIGU, ejecutarConsultaCumulo, crearObjetoConexionSIGU } = require('./db.js');
2
2
  const ManejadorDeErrores = require('./ManejadorDeErrores.js');
3
3
  const InformacionDelModulo = require('../InformacionDelModulo.js');
4
4
  const { envioDeCorreo } = require('./EnvioDeCorreos.js');
@@ -40,6 +40,10 @@ class Miscelaneo {
40
40
  this.EnlaceDeAcceso = undefined;
41
41
  };
42
42
 
43
+ async obtenerNombreLaBaseDeDatos() {
44
+ return this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3);
45
+ }
46
+
43
47
  async RegistrarPermisoExtra(Permiso, Descripcion) {
44
48
  await ejecutarConsultaSIGU("SELECT IFNULL(MAX(`PermisoExtraId`), 0) + 1 INTO @`SiguientePermisoId` FROM `SIGU`.`SIGU_PermisosExtraV2`;\
45
49
  INSERT INTO `SIGU`.`SIGU_PermisosExtraV2` VALUES\
@@ -450,7 +454,6 @@ class Miscelaneo {
450
454
  , [Identificador]);
451
455
 
452
456
  // ENVIAR CORREO
453
- console.log(CorreoElectronico[0][0].CorreoElectronico)
454
457
  await envioDeCorreo(
455
458
  CorreoElectronico[0][0].CorreoElectronico,
456
459
  "Código de verificación 2FA",
@@ -3,88 +3,106 @@ button:focus {
3
3
  }
4
4
 
5
5
  .contenedor {
6
-
7
- min-height: 20vh;
8
- padding: 2%;
9
- padding-top: 10%;
10
- padding-bottom: 5%;
11
-
6
+ max-height: 80vh;
7
+ display: flex;
8
+ flex-direction: column;
9
+ padding: 20px;
10
+ /* Padding uniforme en todos los lados */
12
11
  background-color: white;
12
+ overflow: hidden;
13
+ box-sizing: border-box;
13
14
  }
14
15
 
15
- .zona-archivo {
16
- width: 90%;
17
- height: 10vh;
18
- margin-left: 4%;
19
- border: 2px dashed #3498db;
20
- padding: 1%;
21
- align-items: center;
16
+ .lista {
17
+ width: 100%;
18
+ /* Ocupa todo el ancho disponible del contenedor */
19
+ margin-bottom: 15px;
20
+ max-height: 300px;
21
+ overflow-y: auto;
22
+ overflow-x: hidden;
22
23
  display: flex;
23
- cursor: pointer;
24
- transition: background 0.3s;
24
+ flex-direction: column;
25
+ gap: 8px;
26
+ /* Espacio uniforme entre archivos */
25
27
  }
26
28
 
27
- .texto {
28
- width: 100%;
29
- text-align: center;
29
+ /* Estilo de la fila de archivo */
30
+ .lista .archivo {
31
+ border: solid 1px #007bff;
32
+ border-radius: 8px;
33
+ display: flex;
34
+ justify-content: space-between;
35
+ align-items: center;
36
+ padding: 8px 15px;
37
+ /* Espacio interno simétrico */
38
+ box-sizing: border-box;
30
39
  }
31
40
 
32
- .zona-archivo:hover,
33
- .zona-archivo.arrastrar {
34
- background: #e3f2fd;
41
+ .lista .archivo p {
42
+ margin: 0;
43
+ flex: 1;
44
+ /* El texto toma el espacio restante */
45
+ text-align: left;
46
+ padding-right: 10px;
35
47
  }
36
48
 
37
- .texto-clic {
38
- color: #007bff;
39
- font-weight: bold;
49
+ /* Zona de Arrastre */
50
+ .zona-archivo {
51
+ width: 100%;
52
+ /* Centrado automático */
53
+ height: 100px;
54
+ border: 2px dashed #3498db;
55
+ border-radius: 8px;
56
+ display: flex;
57
+ justify-content: center;
58
+ align-items: center;
40
59
  cursor: pointer;
41
- text-decoration: underline;
60
+ transition: background 0.3s;
61
+ box-sizing: border-box;
42
62
  }
43
63
 
44
- .pie {
45
- margin-top: 5%;
46
- margin-right: 5%;
64
+ /* Centrado del mensaje vacío */
65
+ .mensaje-vacio {
47
66
  display: flex;
48
- flex-direction: row-reverse;
67
+ justify-content: center;
68
+ align-items: center;
69
+ padding: 40px 0;
70
+ /* Margen superior e inferior igual */
71
+ color: #7f8c8d;
72
+ width: 100%;
49
73
  }
50
74
 
51
- .lista {
52
- width: 95%;
53
- margin-bottom: 2%;
54
- padding-left: 4%;
75
+ .mensaje-vacio p {
76
+ margin: 0;
55
77
  }
56
78
 
57
- .lista .archivo {
58
- border: solid 1px #007bff;
59
- ;
60
- border-radius: 10px;
61
- width: 100%;
79
+ .pie {
80
+ margin-top: 20px;
62
81
  display: flex;
63
- justify-content: center;
64
- align-items: center;
65
- margin-bottom: 1%;
82
+ justify-content: flex-end;
83
+ /* Alinea botones a la derecha */
84
+ gap: 10px;
66
85
  }
67
86
 
68
- .lista .archivo p {
69
-
70
- text-align: center;
71
- width: 70%;
72
- padding: 1%;
87
+ /* Estilizador de Scrollbar */
88
+ .lista::-webkit-scrollbar {
89
+ width: 6px;
73
90
  }
74
91
 
75
- .lista p:nth-child(odd) {
76
- margin-right: 2%;
92
+ .lista::-webkit-scrollbar-thumb {
93
+ background: #bdc3c7;
94
+ border-radius: 10px;
77
95
  }
78
96
 
97
+ /* Iconos */
79
98
  .descargar {
80
99
  color: #007bff;
81
- margin-right: 5%;
82
100
  }
83
101
 
84
102
  .eliminar {
85
- color: red;
103
+ color: #e74c3c;
86
104
  }
87
105
 
88
106
  .deshabilitado {
89
- color: gray;
107
+ color: #bdc3c7;
90
108
  }
@@ -2,7 +2,8 @@
2
2
  <div class="lista">
3
3
  @for(archivo of ListaArchivos;track $index){
4
4
  <div class="archivo">
5
- <p>{{archivo.Nombre}}</p>
5
+ <p style="text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{archivo.Nombre}}
6
+ </p>
6
7
  <button mat-icon-button (click)="DescargarArchivo(archivo.ArchivoId,archivo.Nombre)" matTooltip="Descargar">
7
8
  <!--pone deshabilitado si es estado coincide con el indicado -->
8
9
  <mat-icon class="descargar">download</mat-icon>
@@ -29,11 +30,13 @@
29
30
  </div>
30
31
  } @else {
31
32
  @if(ListaArchivos.length === 0) {
32
- <p>Sin archivos adjuntos</p>
33
+ <div class="mensaje-vacio">
34
+ <p>Sin archivos adjuntos</p>
35
+ </div>
33
36
  }
34
37
  }
35
38
  <div class="pie">
36
39
  <button mat-button [disabled]="!EsEditable" (click)="SubirArchivo()">Guardar</button>
37
40
  <button mat-button (click)="Cancelar()">Cerrar</button>
38
41
  </div>
39
- </div>
42
+ </div>
@@ -21,10 +21,17 @@ export class SubirArchivoComponent implements OnInit {
21
21
  Etiqueta = this.data.Etiqueta + this.Permiso;
22
22
  EsEditable = this.data.EsEditable;
23
23
  Token: any;
24
- constructor(private datosGlobalesService: DatosGlobalesService,
25
- private http: HttpClient
26
- ) { }
24
+ public RutaParaListar: string = 'misc/listarArchivos/';
25
+ public RutaParaDescargar: string = 'misc/descargarArchivo/';
26
+ constructor(private datosGlobalesService: DatosGlobalesService, private http: HttpClient) { }
27
+
27
28
  ngOnInit(): void {
29
+ if (this.data.RutaParaListar) {
30
+ this.RutaParaListar = this.data.RutaParaListar;
31
+ }
32
+ if (this.data.RutaParaDescargar) {
33
+ this.RutaParaDescargar = this.data.RutaParaDescargar;
34
+ }
28
35
  this.ListarArchivos(this.Etiqueta)
29
36
  }
30
37
 
@@ -33,7 +40,6 @@ export class SubirArchivoComponent implements OnInit {
33
40
  event.stopPropagation();
34
41
  const archivoZona = event.target as HTMLElement;
35
42
  archivoZona.classList.add('arrastrar');
36
-
37
43
  }
38
44
 
39
45
  ArrastrarAfuera(event: DragEvent) {
@@ -44,10 +50,8 @@ export class SubirArchivoComponent implements OnInit {
44
50
  Soltar(event: DragEvent) {
45
51
  event.preventDefault();
46
52
  event.stopPropagation();
47
-
48
53
  const archivoZona = event.target as HTMLElement;
49
54
  archivoZona.classList.remove('arrastrar');
50
-
51
55
  if (event.dataTransfer?.files.length && this.EsEditable) {
52
56
  this.Archivo = event.dataTransfer.files[0];
53
57
  }
@@ -89,7 +93,7 @@ export class SubirArchivoComponent implements OnInit {
89
93
  }
90
94
 
91
95
  ListarArchivos(Etiqueta: string) {
92
- this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/listarArchivos/' + Etiqueta)
96
+ this.http.get(this.datosGlobalesService.ObtenerURL() + this.RutaParaListar + Etiqueta)
93
97
  .subscribe({
94
98
  next: (data: any) => {
95
99
  this.ListaArchivos = data.body;
@@ -101,7 +105,7 @@ export class SubirArchivoComponent implements OnInit {
101
105
  }
102
106
 
103
107
  DescargarArchivo(ArchivoId: string, Nombre: string) {
104
- this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/descargarArchivo/' + ArchivoId + this.Permiso
108
+ this.http.get(this.datosGlobalesService.ObtenerURL() + this.RutaParaDescargar + ArchivoId + this.Permiso
105
109
  , { responseType: 'blob' })
106
110
  .subscribe((pdfBlob) => {
107
111
  const url = window.URL.createObjectURL(pdfBlob);