utn-cli 2.0.31 → 2.0.33

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.31",
3
+ "version": "2.0.33",
4
4
  "description": "Herramienta CLI unificada para la gestión de plantillas en SIGU.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -277,6 +277,23 @@ Router.post('/reporteDeIncidencia/:Datos', async (solicitud, respuesta, next) =>
277
277
  }
278
278
  });
279
279
 
280
+ Router.post('/reporteDeSugerencia/:Datos', async (solicitud, respuesta, next) => {
281
+ try {
282
+ if (await Miscelaneo.validarTokenV2(solicitud.headers.authorization) && await Miscelaneo.validarAccesoDelOrigen(solicitud)) {
283
+ try {
284
+ return respuesta.json({ body: await Miscelaneo.reporteDeSugerencia(solicitud, solicitud.params.Datos), error: undefined });
285
+ } catch (error) {
286
+ const MensajeDeError = 'No fue posible reportar la incidencia';
287
+ console.error(new ManejadorDeErrores(MensajeDeError, ManejadorDeErrores.obtenerNumeroDeLinea(), true, `Dirección IP: ${solicitud.ip}`));
288
+ return respuesta.status(500).json({ body: undefined, error: MensajeDeError });
289
+ }
290
+ }
291
+ return respuesta.status(401).json({ body: undefined, error: ManejadorDeErrores.mensajeDeError401() });
292
+ } catch (error) {
293
+ next(error);
294
+ }
295
+ });
296
+
280
297
  Router.get('/cerrarSesion', async (solicitud, respuesta, next) => {
281
298
  try {
282
299
  if (await Miscelaneo.validarTokenV2(solicitud.headers.authorization) && await Miscelaneo.validarAccesoDelOrigen(solicitud)) {
@@ -317,7 +334,7 @@ Router.get('/obtenerPersonasFuncionarias', async (solicitud, respuesta, next) =>
317
334
  try {
318
335
  return respuesta.json({ body: await Miscelaneo.obtenerPersonasFuncionarias(), error: undefined });
319
336
  } catch (error) {
320
- const MensajeDeError = 'No fue posible obtener los datos de las personas estudiantes';
337
+ const MensajeDeError = 'No fue posible obtener los datos de las personas funcionarias';
321
338
  console.error(new ManejadorDeErrores(MensajeDeError, ManejadorDeErrores.obtenerNumeroDeLinea(), true, `Dirección IP: ${solicitud.ip}`));
322
339
  return respuesta.status(500).json({ body: undefined, error: MensajeDeError });
323
340
  }
@@ -543,6 +543,16 @@ class Miscelaneo {
543
543
  return;
544
544
  }
545
545
 
546
+ async reporteDeSugerencia(Solicitud, Datos) {
547
+ // const DatosDelArchivo = await this.cargarArchivo(Solicitud, Datos);
548
+ await envioDeCorreo('msavatar@utn.ac.cr', "Reporte de sugerencia",
549
+ "<p><b>Sistema: </b>" + this.NombreCanonicoDelModulo + "</p><br />"
550
+ + "<p><b>Asunto: </b>Reporte de sugerencia</p><br />"
551
+ + "<p><b>Detalle de la sugerencia: </b>" + Datos.detalle + "</p><br />"
552
+ + "<p><b>Información del usuario: </b>" + await this.obtenerDatosDeLaPersona(Solicitud.headers.authorization) + "</p><br />");
553
+ return;
554
+ }
555
+
546
556
  async cerrarSesion(Token) {
547
557
  let Resultado = undefined;
548
558
  try {
@@ -678,8 +688,8 @@ class Miscelaneo {
678
688
  async obtenerPersonasFuncionarias() {
679
689
  return await ejecutarConsultaSIGU("SELECT `Identificador`, `Identificacion`, `Nombre`, `PrimerApellido`,\
680
690
  `SegundoApellido` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` IN\
681
- (SELECT `Identificador` FROM `SIGU`.`SIGU_RolesPersonas` WHERE `PerfilGeneralId` = ?) ORDER BY `Nombre`, `PrimerApellido`,\
682
- `SegundoApellido`", [await this.perfilGeneralId()]);
691
+ (SELECT `Identificador` FROM `SIGU`.`EstructuraOrganizacional_Instancias`) ORDER BY `Nombre`, `PrimerApellido`,\
692
+ `SegundoApellido`");
683
693
  }
684
694
 
685
695
  // async rolPermisoIdDelMenuPadre() {
@@ -25,15 +25,10 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
25
25
 
26
26
  export class ReporteDeIncidenciasComponent implements OnInit {
27
27
  formulario!: FormGroup;
28
-
29
28
  archivos: File[] = [];
30
-
31
29
  readonly dialogRef = inject(MatDialogRef<ReporteDeIncidenciasComponent>);
32
-
33
30
  constructor(private fb: FormBuilder, private datosGlobalesService: DatosGlobalesService, private http: HttpClient) { }
34
-
35
31
  @ViewChild('EntradDeArchivo') EntradDeArchivo!: ElementRef<HTMLInputElement>;
36
-
37
32
  Archivo: any;
38
33
 
39
34
  ngOnInit(): void {
@@ -0,0 +1,37 @@
1
+ .contenedor {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+ }
5
+
6
+ .fila {
7
+ width: 100%;
8
+ min-width: 500px;
9
+ }
10
+
11
+ .campo {
12
+ width: 100%;
13
+ }
14
+
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;
22
+ display: flex;
23
+ cursor: pointer;
24
+ transition: background 0.3s;
25
+ }
26
+
27
+ .texto {
28
+ width: 100%;
29
+ text-align: center;
30
+ }
31
+
32
+ .texto-clic {
33
+ color: #007bff;
34
+ font-weight: bold;
35
+ cursor: pointer;
36
+ text-decoration: underline;
37
+ }
@@ -0,0 +1,17 @@
1
+ <h2 mat-dialog-title>Reporte de la sugerencia</h2>
2
+ <mat-dialog-content>
3
+ <div class="contenedor">
4
+ <form [formGroup]="formulario">
5
+ <div class="fila">
6
+ <mat-form-field class="campo">
7
+ <mat-label>Detalle de la sugerencia</mat-label>
8
+ <textarea matInput formControlName="detalle" required></textarea>
9
+ </mat-form-field>
10
+ </div>
11
+ </form>
12
+ </div>
13
+ </mat-dialog-content>
14
+ <mat-dialog-actions>
15
+ <button mat-button (click)="Cerrar()">Cerrar</button>
16
+ <button mat-button (click)="Enviar()">Enviar</button>
17
+ </mat-dialog-actions>
@@ -0,0 +1,54 @@
1
+ import { Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core';
2
+ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
3
+ import { MatFormFieldModule } from '@angular/material/form-field';
4
+ import { MatInputModule } from '@angular/material/input';
5
+ import { ReactiveFormsModule } from '@angular/forms';
6
+ import { MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';
7
+ import { MatButtonModule } from '@angular/material/button';
8
+ import { DatosGlobalesService } from '../../../datos-globales.service';
9
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
10
+
11
+ @Component({
12
+ selector: 'app-reporte-de-sugerencias',
13
+ templateUrl: './reporte-de-sugerencias.component.html',
14
+ styleUrls: ['./reporte-de-sugerencias.component.css'],
15
+ imports: [
16
+ MatFormFieldModule,
17
+ MatInputModule,
18
+ ReactiveFormsModule,
19
+ MatDialogContent,
20
+ MatButtonModule,
21
+ MatDialogTitle,
22
+ MatDialogActions
23
+ ]
24
+ })
25
+
26
+ export class ReporteDeSugerenciasComponent implements OnInit {
27
+ formulario!: FormGroup;
28
+ readonly dialogRef = inject(MatDialogRef<ReporteDeSugerenciasComponent>);
29
+ constructor(private fb: FormBuilder, private datosGlobalesService: DatosGlobalesService, private http: HttpClient) { }
30
+
31
+ ngOnInit(): void {
32
+ this.formulario = this.fb.group({
33
+ detalle: ['', Validators.required]
34
+ });
35
+ }
36
+
37
+ Cerrar(): void {
38
+ this.dialogRef.close();
39
+ }
40
+
41
+ Enviar() {
42
+ const Datos = JSON.stringify(this.formulario.value);
43
+ this.http.post(this.datosGlobalesService.ObtenerURL() + 'misc/reporteDeSugerencia/' + Datos, {})
44
+ .subscribe({
45
+ next: (data: any) => {
46
+ alert('Mensaje enviado');
47
+ },
48
+ error: (error) => {
49
+ console.error('Ocurrió un error al informar de la sugerencia:', error);
50
+ }
51
+ })
52
+ this.Cerrar();
53
+ }
54
+ }
@@ -96,7 +96,7 @@
96
96
  <ng-container matColumnDef="expand">
97
97
  <th mat-header-cell *matHeaderCellDef aria-label="Fila expandible"></th>
98
98
  <td mat-cell *matCellDef="let element">
99
- <button mat-icon-button aria-label="Expander fila"
99
+ <button mat-icon-button aria-label="Expandir fila"
100
100
  (click)="(elementoExpandible = elementoExpandible === element ? null : element); $event.stopPropagation()">
101
101
  @if (elementoExpandible === element) {
102
102
  <mat-icon>keyboard_arrow_up</mat-icon>
@@ -85,6 +85,9 @@
85
85
  <button class="botonDeNavegacion" matTooltip="Reporte" mat-button (click)="irASoporte()">
86
86
  <mat-icon>support_agent</mat-icon>
87
87
  </button>
88
+ <button class="botonDeNavegacion" matTooltip="Sugerencias" mat-button (click)="irASugerencias()">
89
+ <mat-icon>lightbulb</mat-icon>
90
+ </button>
88
91
  </div>
89
92
  </div>
90
93
  </div>
@@ -6,9 +6,10 @@ import { Location, CommonModule } from '@angular/common';
6
6
  import { MatIconModule } from '@angular/material/icon';
7
7
  import { MatTooltipModule } from '@angular/material/tooltip';
8
8
  import { MatDialog } from '@angular/material/dialog';
9
- import { ReporteDeIncidenciasComponent } from '../../../Componentes/Nucleo/reporte-de-incidencias/reporte-de-incidencias.component'
9
+ import { ReporteDeIncidenciasComponent } from '../../../Componentes/Nucleo/reporte-de-incidencias/reporte-de-incidencias.component';
10
10
  import { MensajesComponent } from '../../../Componentes/Nucleo/mensajes/mensajes.component';
11
11
  import { MensajeConfirmacionHTMLComponent } from '../../../Componentes/Nucleo/mensaje-confirmacion-html/mensaje-confirmacion-html';
12
+ import { ReporteDeSugerenciasComponent } from '../../../Componentes/Nucleo/reporte-de-sugerencias/reporte-de-sugerencias.component';
12
13
 
13
14
  @Component({
14
15
  selector: 'app-contenedor-componentes',
@@ -189,4 +190,8 @@ export class ContenedorComponentesComponent {
189
190
  window.location.href = datos.body;
190
191
  })
191
192
  }
193
+
194
+ irASugerencias(): void {
195
+ this.dialog.open(ReporteDeSugerenciasComponent);
196
+ }
192
197
  }