utn-cli 2.1.0 → 2.1.2
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/.claude/settings.local.json +7 -0
- package/commands/commit.js +14 -1
- package/package.json +1 -1
- package/templates/backend/package.json +3 -3
- package/templates/backend/rutas/misc.js +51 -0
- package/templates/backend/servicios/Nucleo/Miscelaneas.js +176 -20
- package/templates/frontend/package.json +9 -8
- package/templates/frontend/public/Manual.md +1 -0
- package/templates/frontend/src/app/Componentes/Nucleo/gestion-actividad/gestion-actividad.component.ts +11 -3
- package/templates/frontend/src/app/Componentes/Nucleo/graficos/graficos.component.ts +2 -4
- package/templates/frontend/src/app/Componentes/Nucleo/manual/manual.component.css +318 -0
- package/templates/frontend/src/app/Componentes/Nucleo/manual/manual.component.html +43 -0
- package/templates/frontend/src/app/Componentes/Nucleo/manual/manual.component.ts +74 -0
- package/templates/frontend/src/app/Componentes/Nucleo/mensajes/mensajes.component.ts +5 -3
- package/templates/frontend/src/app/Componentes/Nucleo/reporte-de-incidencias/reporte-de-incidencias.component.ts +12 -4
- package/templates/frontend/src/app/Componentes/Nucleo/reporte-de-sugerencias/reporte-de-sugerencias.component.ts +12 -3
- package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.html +13 -10
- package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.ts +18 -6
- package/templates/frontend/src/app/Componentes/Nucleo/tarjeta/tarjeta.component.html +2 -2
- package/templates/frontend/src/app/Componentes/Nucleo/tarjeta/tarjeta.component.ts +9 -13
- package/templates/frontend/src/app/Componentes/Nucleo/tarjeta-personalizada/tarjeta-personalizada.component.ts +7 -9
- package/templates/frontend/src/app/Componentes/Nucleo/tarjeta-reporte/tarjeta-reporte.component.ts +1 -6
- package/templates/frontend/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.html +0 -2
- package/templates/frontend/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.ts +34 -57
- package/templates/frontend/src/app/Paginas/contenedor-principal/contenedor-principal.component.html +3 -3
- package/templates/frontend/src/app/Paginas/contenedor-principal/contenedor-principal.component.ts +37 -203
- package/templates/frontend/src/app/Paginas/gestion-de-reportes/gestion-de-reportes.component.html +14 -3
- package/templates/frontend/src/app/Paginas/gestion-de-reportes/gestion-de-reportes.component.ts +52 -14
- package/templates/frontend/src/app/app.routes.ts +4 -0
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
<div [class]="cantidadLugar">
|
|
29
29
|
<p>{{ (cantidadAMostrar !== 0 ? cantidadAMostrar : '') }}</p>
|
|
30
30
|
</div>
|
|
31
|
-
@if(
|
|
32
|
-
<hr
|
|
31
|
+
@if(cantidadMaxima && cantidadMaxima > 0) {
|
|
32
|
+
<hr #lineaRef class="linea" [matTooltip]="cantidad + ' / ' + cantidadMaxima" matTooltipPosition="above" />
|
|
33
33
|
}
|
|
34
34
|
<!-- <div class="pie">
|
|
35
35
|
<p>CONTINUAR</p>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AfterViewInit, Component, Input } from "@angular/core";
|
|
1
|
+
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from "@angular/core";
|
|
2
2
|
import { MatIconModule } from "@angular/material/icon";
|
|
3
3
|
import { MatCardModule } from "@angular/material/card";
|
|
4
4
|
import { MatTooltipModule } from "@angular/material/tooltip";
|
|
@@ -21,8 +21,12 @@ export class TarjetaComponent implements AfterViewInit {
|
|
|
21
21
|
@Input() cantidadLugar: string = "cantidad";
|
|
22
22
|
@Input() rutaASeguir: string = '';
|
|
23
23
|
@Input() cantidadMaxima: number | undefined;
|
|
24
|
-
@Input() cantidadAMostrar: number = 0;
|
|
25
24
|
@Input() ColorDeBorde: string = '';
|
|
25
|
+
@ViewChild('lineaRef') lineaRef?: ElementRef<HTMLHRElement>;
|
|
26
|
+
|
|
27
|
+
get cantidadAMostrar(): number {
|
|
28
|
+
return (this.cantidadMaxima ?? 0) - (this.cantidad ?? 0);
|
|
29
|
+
}
|
|
26
30
|
|
|
27
31
|
constructor(private ruta: Router) { }
|
|
28
32
|
|
|
@@ -30,18 +34,10 @@ export class TarjetaComponent implements AfterViewInit {
|
|
|
30
34
|
this.ruta.navigate([this.rutaASeguir]);
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
ngOnInit() {
|
|
34
|
-
this.cantidadAMostrar = (this.cantidadMaxima ? this.cantidadMaxima : 0) - (this.cantidad ? this.cantidad : 0);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
37
|
ngAfterViewInit(): void {
|
|
38
|
-
if (this.
|
|
39
|
-
|
|
40
|
-
if (this.
|
|
41
|
-
porcentaje = (this.cantidad / this.cantidadMaxima) * 100;
|
|
42
|
-
}
|
|
43
|
-
const linea = document.getElementById('porcentaje' + this.titulo) as HTMLHRElement;
|
|
44
|
-
linea.style.width = `${porcentaje}%`;
|
|
38
|
+
if (this.cantidadMaxima && this.cantidadMaxima > 0) {
|
|
39
|
+
const porcentaje = (this.cantidad / this.cantidadMaxima) * 100;
|
|
40
|
+
if (this.lineaRef?.nativeElement) this.lineaRef.nativeElement.style.width = `${porcentaje}%`;
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AfterViewInit, Component, EventEmitter, Input, Output } from "@angular/core";
|
|
1
|
+
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
|
|
2
2
|
import { MatIconModule } from "@angular/material/icon";
|
|
3
3
|
import { MatCardModule } from "@angular/material/card";
|
|
4
4
|
import { MatTooltipModule } from "@angular/material/tooltip";
|
|
@@ -11,7 +11,7 @@ import { Router } from "@angular/router";
|
|
|
11
11
|
templateUrl: "./tarjeta-personalizada.component.html",
|
|
12
12
|
styleUrl: "./tarjeta-personalizada.component.css"
|
|
13
13
|
})
|
|
14
|
-
export class TarjetaPersonalizadaComponent implements AfterViewInit {
|
|
14
|
+
export class TarjetaPersonalizadaComponent implements OnInit, AfterViewInit {
|
|
15
15
|
@Input() titulo: string = "";
|
|
16
16
|
@Input() descripcion: string = "";
|
|
17
17
|
@Input() icono: any = null;
|
|
@@ -25,15 +25,12 @@ export class TarjetaPersonalizadaComponent implements AfterViewInit {
|
|
|
25
25
|
@Input() Etiqueta: string = "CONTINUAR";
|
|
26
26
|
@Input() ColorDeBorde: string = "";
|
|
27
27
|
@Output() etiquetaClick = new EventEmitter<void>();
|
|
28
|
+
@ViewChild('porcentajeRef') porcentajeRef?: ElementRef<HTMLHRElement>;
|
|
28
29
|
|
|
29
30
|
constructor(private ruta: Router) { }
|
|
30
31
|
|
|
31
32
|
onClick() {
|
|
32
|
-
|
|
33
|
-
this.etiquetaClick.emit();
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
this.ruta.navigate([this.rutaASeguir]);
|
|
33
|
+
this.etiquetaClick.emit();
|
|
37
34
|
}
|
|
38
35
|
|
|
39
36
|
ngOnInit() {
|
|
@@ -46,8 +43,9 @@ export class TarjetaPersonalizadaComponent implements AfterViewInit {
|
|
|
46
43
|
if (this.cantidadMaxima) {
|
|
47
44
|
porcentaje = (this.cantidad / this.cantidadMaxima) * 100;
|
|
48
45
|
}
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
if (this.porcentajeRef?.nativeElement) {
|
|
47
|
+
this.porcentajeRef.nativeElement.style.width = `${porcentaje}%`;
|
|
48
|
+
}
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
}
|
package/templates/frontend/src/app/Componentes/Nucleo/tarjeta-reporte/tarjeta-reporte.component.ts
CHANGED
|
@@ -15,12 +15,7 @@ export class TarjetaReporteComponent {
|
|
|
15
15
|
@Input() ColorDeBorde: string = '';
|
|
16
16
|
@Output() GenerarReporte: EventEmitter<{ reporte: string }> = new EventEmitter();
|
|
17
17
|
|
|
18
|
-
constructor() { }
|
|
19
|
-
|
|
20
18
|
onClick() {
|
|
21
|
-
this.GenerarReporte.emit({reporte: this.reporteAGenerar});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
ngOnInit() {
|
|
19
|
+
this.GenerarReporte.emit({ reporte: this.reporteAGenerar });
|
|
25
20
|
}
|
|
26
21
|
}
|
|
@@ -132,11 +132,9 @@
|
|
|
132
132
|
<mat-icon>live_tv</mat-icon>
|
|
133
133
|
</button>
|
|
134
134
|
}
|
|
135
|
-
@if(EnlaceDelManual !== '-') {
|
|
136
135
|
<button class="botonDeNavegacion" matTooltip="Ayuda" title="Ayuda" (click)="irAAyuda()">
|
|
137
136
|
<mat-icon>help</mat-icon>
|
|
138
137
|
</button>
|
|
139
|
-
}
|
|
140
138
|
<button class="botonDeNavegacion" matTooltip="Reporte" title="Reporte" (click)="irASoporte()">
|
|
141
139
|
<mat-icon>support_agent</mat-icon>
|
|
142
140
|
</button>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpClient
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
2
|
import { Component, OnInit, OnDestroy, NgZone } from '@angular/core';
|
|
3
3
|
import { RouterOutlet, Router } from '@angular/router';
|
|
4
4
|
import { DatosGlobalesService } from '../../../datos-globales.service';
|
|
@@ -65,73 +65,57 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy {
|
|
|
65
65
|
}, 60000);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/
|
|
69
|
-
|
|
68
|
+
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/inicializar').subscribe((datos: any) => {
|
|
69
|
+
const body = datos.body;
|
|
70
|
+
|
|
71
|
+
this.TienePermiso = body.TienePermiso;
|
|
70
72
|
if (!this.TienePermiso) {
|
|
71
73
|
this.Entrar();
|
|
74
|
+
return;
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}).subscribe((datos: any) => {
|
|
87
|
-
this.Mensajes = datos.body;
|
|
88
|
-
})
|
|
89
|
-
});
|
|
90
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/obtenerDetalleDelModulo').subscribe((datos: any) => {
|
|
91
|
-
this.EnlaceDelManual = datos.body[0].EnlaceDelManual;
|
|
92
|
-
this.EnlaceDelVideo = datos.body[0].EnlaceDelVideo;
|
|
93
|
-
});
|
|
94
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'ConsentimientoInformado/ConsentimientoInformado').subscribe((datos: any) => {
|
|
95
|
-
if (datos.body.Aceptaciones === 0) {
|
|
96
|
-
const ConsentimientoInformadoId = datos.body.Consentimiento[0].ConsentimientoInformadoId;
|
|
76
|
+
|
|
77
|
+
this.Titulo = body.Titulo;
|
|
78
|
+
this.Modulo = body.Modulo;
|
|
79
|
+
this.Version = body.Version;
|
|
80
|
+
this.Descripcion = body.Descripcion;
|
|
81
|
+
this.Detalle = body.Detalle;
|
|
82
|
+
this.NombreUsuario = body.NombreUsuario || 'Perfil';
|
|
83
|
+
this.EnlaceDelManual = body.EnlaceDelManual;
|
|
84
|
+
this.EnlaceDelVideo = body.EnlaceDelVideo;
|
|
85
|
+
this.Mensajes = body.Notificaciones;
|
|
86
|
+
|
|
87
|
+
if (body.Consentimiento?.Aceptaciones === 0) {
|
|
88
|
+
const ConsentimientoInformadoId = body.Consentimiento.Consentimiento[0].ConsentimientoInformadoId;
|
|
97
89
|
this.dialog.open(MensajeConfirmacionHTMLComponent, {
|
|
98
90
|
data: {
|
|
99
|
-
titulo:
|
|
100
|
-
mensaje:
|
|
91
|
+
titulo: body.Consentimiento.Consentimiento[0].Titulo,
|
|
92
|
+
mensaje: body.Consentimiento.Consentimiento[0].Texto,
|
|
101
93
|
textoCerrar: 'Cancelar',
|
|
102
94
|
textoAceptar: 'Aceptar',
|
|
103
95
|
onClose: () => { this.datosGlobalesService.RedirigirAPortal() },
|
|
104
96
|
onAccept: () => {
|
|
105
|
-
this.http.post(`${this.datosGlobalesService.ObtenerURL()}ConsentimientoInformado/AceptarConsentimientoInformado
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
next: (datos: any) => {
|
|
109
|
-
// this.obtenerDatosParaPoblarLaTabla();
|
|
110
|
-
},
|
|
111
|
-
error: (error) => {
|
|
112
|
-
this.datosGlobalesService.RedirigirAPortal();
|
|
113
|
-
},
|
|
97
|
+
this.http.post(`${this.datosGlobalesService.ObtenerURL()}ConsentimientoInformado/AceptarConsentimientoInformado`,
|
|
98
|
+
{ ConsentimientoInformadoId }).subscribe({
|
|
99
|
+
error: () => { this.datosGlobalesService.RedirigirAPortal(); }
|
|
114
100
|
});
|
|
115
101
|
},
|
|
116
102
|
},
|
|
117
103
|
});
|
|
118
104
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let
|
|
122
|
-
|
|
123
|
-
const index = mensajesVisualizados.indexOf(datos.body[contador]['MensajeModularId']);
|
|
124
|
-
if (index === -1) {
|
|
105
|
+
|
|
106
|
+
const mensajesVisualizados = this.obtenerMensajesModularesVisualizados();
|
|
107
|
+
for (let i = 0; i < body.MensajesModulares.length; i++) {
|
|
108
|
+
if (!mensajesVisualizados.includes(body.MensajesModulares[i]['MensajeModularId'])) {
|
|
125
109
|
this.dialog.open(MensajeConfirmacionHTMLComponent, {
|
|
126
110
|
data: {
|
|
127
|
-
titulo:
|
|
128
|
-
mensaje:
|
|
111
|
+
titulo: body.MensajesModulares[i]['Titulo'],
|
|
112
|
+
mensaje: body.MensajesModulares[i]['Texto'],
|
|
129
113
|
textoAceptar: 'Cerrar',
|
|
130
114
|
onClose: () => { },
|
|
131
115
|
onAccept: () => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
localStorage.setItem('MensajesModularesVisualizados', JSON.stringify(
|
|
116
|
+
const vistos = this.obtenerMensajesModularesVisualizados();
|
|
117
|
+
vistos.push(body.MensajesModulares[i]['MensajeModularId']);
|
|
118
|
+
localStorage.setItem('MensajesModularesVisualizados', JSON.stringify(vistos));
|
|
135
119
|
},
|
|
136
120
|
},
|
|
137
121
|
});
|
|
@@ -171,14 +155,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy {
|
|
|
171
155
|
}
|
|
172
156
|
|
|
173
157
|
irAAyuda(): void {
|
|
174
|
-
|
|
175
|
-
// const link = document.createElement('a');
|
|
176
|
-
// link.href = 'assets/Ayuda.pdf';
|
|
177
|
-
// link.setAttribute('download', 'Ayuda.pdf');
|
|
178
|
-
// link.setAttribute('target', '_blank');
|
|
179
|
-
// document.body.appendChild(link);
|
|
180
|
-
// link.click();
|
|
181
|
-
// document.body.removeChild(link);
|
|
158
|
+
this.router.navigate(['/manual']);
|
|
182
159
|
}
|
|
183
160
|
|
|
184
161
|
irAVideo(): void {
|
package/templates/frontend/src/app/Paginas/contenedor-principal/contenedor-principal.component.html
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
<div cdkDrag>
|
|
4
4
|
@switch (tarjeta.type) {
|
|
5
5
|
@case ('single') {
|
|
6
|
-
<app-tarjeta [rutaASeguir]="tarjeta.rutaASeguir" [titulo]="tarjeta.titulo" [descripcion]="tarjeta.descripcion"
|
|
7
|
-
[icono]="tarjeta.icono" [ColorDeBorde]="tarjeta.ColorDeBorde ? tarjeta.ColorDeBorde : ''"
|
|
8
|
-
[cantidad]="tarjeta.cantidad ?? 0" [cantidadMaxima]="tarjeta.cantidadMaxima ?? 0"
|
|
6
|
+
<app-tarjeta [rutaASeguir]="$any(tarjeta).rutaASeguir" [titulo]="tarjeta.titulo" [descripcion]="tarjeta.descripcion"
|
|
7
|
+
[icono]="$any(tarjeta).icono" [ColorDeBorde]="tarjeta.ColorDeBorde ? tarjeta.ColorDeBorde : ''"
|
|
8
|
+
[cantidad]="$any(tarjeta).cantidad ?? 0" [cantidadMaxima]="$any(tarjeta).cantidadMaxima ?? 0">
|
|
9
9
|
</app-tarjeta>
|
|
10
10
|
}
|
|
11
11
|
@case ('multiple') {
|
package/templates/frontend/src/app/Paginas/contenedor-principal/contenedor-principal.component.ts
CHANGED
|
@@ -7,8 +7,6 @@ import { TarjetaPersonalizadaComponent } from "../../Componentes/Nucleo/tarjeta-
|
|
|
7
7
|
import { HttpClient } from "@angular/common/http";
|
|
8
8
|
import { DatosGlobalesService } from '../../datos-globales.service';
|
|
9
9
|
import { DragDropModule, CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
|
10
|
-
import { forkJoin, of } from 'rxjs';
|
|
11
|
-
import { catchError } from 'rxjs/operators';
|
|
12
10
|
|
|
13
11
|
interface BaseTarjetaConfig {
|
|
14
12
|
type: 'single' | 'multiple' | 'report' | 'custom';
|
|
@@ -70,217 +68,53 @@ export class ContenedorPrincipalComponent implements OnInit {
|
|
|
70
68
|
this.cantidadMaxima = 0;
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
type: 'single',
|
|
78
|
-
position: 10,
|
|
79
|
-
rutaASeguir: 'FRM-ModulosV2',
|
|
80
|
-
titulo: 'Módulos',
|
|
81
|
-
descripcion: 'Módulo para el mantenimiento de los módulosV2',
|
|
82
|
-
icono: 'dashboard_2',
|
|
83
|
-
ColorDeBorde: '#0B4FCE'
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
type: 'single',
|
|
87
|
-
position: 20,
|
|
88
|
-
rutaASeguir: 'tablaTareasProgramadas',
|
|
89
|
-
titulo: 'Tareas programadas',
|
|
90
|
-
descripcion: 'Módulo para el mantenimiento de las tareas programadas',
|
|
91
|
-
icono: 'grading'
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
type: 'multiple',
|
|
95
|
-
position: 30,
|
|
96
|
-
titulo: 'Permisos',
|
|
97
|
-
descripcion: 'Módulo para el mantenimiento de los permisos',
|
|
98
|
-
rutas: [
|
|
99
|
-
{ nombre: 'Permisos', ruta: 'tablaPermisos' },
|
|
100
|
-
{ nombre: 'Permisos de personas', ruta: 'tablaPermisosDePersonas' },
|
|
101
|
-
{ nombre: 'Permisos padres de personas', ruta: 'tablaPermisosDePersonasPadres' }
|
|
102
|
-
]
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
type: 'multiple',
|
|
106
|
-
position: 40,
|
|
107
|
-
titulo: 'Permisos extra',
|
|
108
|
-
descripcion: 'Módulo para el mantenimiento de los permisos extra',
|
|
109
|
-
rutas: [
|
|
110
|
-
{ nombre: 'Permisos extra', ruta: 'tablaPermisosExtra' },
|
|
111
|
-
{ nombre: 'Permisos extra de personas', ruta: 'tablaPermisosExtraDePersonas' },
|
|
112
|
-
]
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
type: 'single',
|
|
116
|
-
position: 50,
|
|
117
|
-
rutaASeguir: 'tablaMensajesInstitucionales',
|
|
118
|
-
titulo: 'Mensajes institucionales',
|
|
119
|
-
descripcion: 'Módulo para el mantenimiento de mensajes institucionales',
|
|
120
|
-
icono: 'mark_unread_chat_alt'
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
type: 'single',
|
|
124
|
-
position: 60,
|
|
125
|
-
rutaASeguir: 'tablaMensajesModulares',
|
|
126
|
-
titulo: 'Mensajes modulares',
|
|
127
|
-
descripcion: 'Módulo para el mantenimiento de mensajes modulares',
|
|
128
|
-
icono: 'mark_unread_chat_alt'
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
type: 'single',
|
|
132
|
-
position: 70,
|
|
133
|
-
rutaASeguir: 'tablaPeriodos',
|
|
134
|
-
titulo: 'Periodos',
|
|
135
|
-
descripcion: 'Módulo para el mantenimiento de periodos',
|
|
136
|
-
icono: 'edit_calendar'
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
type: 'single',
|
|
140
|
-
position: 80,
|
|
141
|
-
rutaASeguir: 'tablaSedes',
|
|
142
|
-
titulo: 'Sedes y recintos',
|
|
143
|
-
descripcion: 'Módulo para el mantenimiento de sedes y recintos',
|
|
144
|
-
icono: 'home_work'
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
type: 'single',
|
|
148
|
-
position: 90,
|
|
149
|
-
rutaASeguir: 'tablaFlujosAprobacion',
|
|
150
|
-
titulo: 'Flujos de aprobación',
|
|
151
|
-
descripcion: 'Módulo para el mantenimiento de flujos de aprobación, pasos y movimientos',
|
|
152
|
-
icono: 'library_add_check'
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
type: 'single',
|
|
156
|
-
position: 100,
|
|
157
|
-
rutaASeguir: 'tablaLocalidades',
|
|
158
|
-
titulo: 'Localidades',
|
|
159
|
-
descripcion: 'Módulo para la revisión de las diferentes localidades',
|
|
160
|
-
icono: 'location_on'
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
type: 'multiple',
|
|
164
|
-
position: 110,
|
|
165
|
-
titulo: 'Repositorios',
|
|
166
|
-
descripcion: 'Módulo para el mantenimiento de repositorios, variables del sistema y tareas programadas',
|
|
167
|
-
rutas: [
|
|
168
|
-
{ nombre: 'Consentimientos informados', ruta: 'tablaConsentimientosInformados' },
|
|
169
|
-
{ nombre: 'Repositorios', ruta: 'tablaRepositorios' },
|
|
170
|
-
{ nombre: 'Accesos a repositorios', ruta: 'tablaRepositoriosAccesos' },
|
|
171
|
-
{ nombre: 'Variables del sistema', ruta: 'tablaVariablesDeSistema' },
|
|
172
|
-
]
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
type: 'single',
|
|
176
|
-
position: 120,
|
|
177
|
-
rutaASeguir: 'gestionGrafico',
|
|
178
|
-
titulo: 'Gráfico de solicitudes mensuales',
|
|
179
|
-
descripcion: 'Módulo para la visualización del gráfico de solicitudes por el mes actual',
|
|
180
|
-
icono: 'leaderboard'
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
type: 'single',
|
|
184
|
-
position: 130,
|
|
185
|
-
rutaASeguir: 'gestionGraficoSesiones',
|
|
186
|
-
titulo: 'Gráfico de las sesiones',
|
|
187
|
-
descripcion: 'Módulo para la visualización del gráfico de sesiones',
|
|
188
|
-
icono: 'pie_chart'
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
type: 'single',
|
|
192
|
-
position: 140,
|
|
193
|
-
rutaASeguir: 'tablaAdministradores',
|
|
194
|
-
titulo: 'Administradores',
|
|
195
|
-
descripcion: 'Módulo para el mantenimiento de administradores',
|
|
196
|
-
icono: 'supervisor_account'
|
|
197
|
-
}
|
|
198
|
-
];
|
|
199
|
-
|
|
200
|
-
forkJoin({
|
|
201
|
-
permisoExtra: this.http.get(`${this.datosGlobalesService.ObtenerURL()}Personas/PermisoExtra`).pipe(
|
|
202
|
-
catchError(error => {
|
|
203
|
-
console.error('Problemas al intentar obtener los datos de PermisoExtra: ', error);
|
|
204
|
-
return of({ body: null });
|
|
205
|
-
})
|
|
206
|
-
),
|
|
207
|
-
// configuracion: this.http.get(`${this.datosGlobalesService.ObtenerURL()}ConfiguracionDeTarjetas/obtener`).pipe(
|
|
208
|
-
// catchError(error => {
|
|
209
|
-
// console.error('Error al obtener configuración de tarjetas:', error);
|
|
210
|
-
// return of({ body: [] });
|
|
211
|
-
// })
|
|
212
|
-
// )
|
|
213
|
-
}).subscribe({
|
|
214
|
-
next: (results: any) => {
|
|
215
|
-
// // 2. Handle extra permissions
|
|
216
|
-
// if (results.permisoExtra && results.permisoExtra.body) {
|
|
217
|
-
// const personasCard: TarjetaMultipleConfig = {
|
|
218
|
-
// type: 'multiple',
|
|
219
|
-
// position: 25,
|
|
220
|
-
// titulo: 'Personas',
|
|
221
|
-
// descripcion: 'Módulo para el mantenimiento de los datos relacionados con personas',
|
|
222
|
-
// rutas: [
|
|
223
|
-
// { nombre: 'Personas', ruta: 'tablaPersonas' },
|
|
224
|
-
// { nombre: 'Correos', ruta: 'tablaCorreosPersonas' },
|
|
225
|
-
// { nombre: 'Cuentas bancarias', ruta: 'tablaCuentasPersonas' },
|
|
226
|
-
// { nombre: 'Teléfonos', ruta: 'tablaTelefonosPersonas' },
|
|
227
|
-
// { nombre: 'Ubicación', ruta: 'tablaUbicacionPersona' },
|
|
228
|
-
// ]
|
|
229
|
-
// };
|
|
230
|
-
// if (!baseTarjetas.find(t => t.titulo === 'Personas')) {
|
|
231
|
-
// baseTarjetas.push(personasCard);
|
|
232
|
-
// }
|
|
233
|
-
// }
|
|
234
|
-
|
|
235
|
-
// 3. Apply saved configurations
|
|
236
|
-
if (results.configuracion && results.configuracion.body && results.configuracion.body.length > 0) {
|
|
237
|
-
const savedConfigs = results.configuracion.body;
|
|
238
|
-
baseTarjetas.forEach(tarjeta => {
|
|
239
|
-
const config = savedConfigs.find((c: any) => c.Titulo === tarjeta.titulo);
|
|
240
|
-
if (config) {
|
|
241
|
-
tarjeta.position = config.Posicion;
|
|
242
|
-
if (config.ColorDeBorde) {
|
|
243
|
-
tarjeta.ColorDeBorde = config.ColorDeBorde;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
this.tarjetas = baseTarjetas.sort((a, b) => a.position - b.position);
|
|
71
|
+
ngOnInit() {
|
|
72
|
+
this.http.get(`${this.datosGlobalesService.ObtenerURL()}misc/obtenerTarjetasDelContenedor`).subscribe({
|
|
73
|
+
next: (datos: any) => {
|
|
74
|
+
this.tarjetas = (datos.body ?? []).map((d: any) => this.mapearTarjeta(d));
|
|
249
75
|
},
|
|
250
76
|
error: (error) => {
|
|
251
|
-
console.error('Error
|
|
252
|
-
this.tarjetas =
|
|
77
|
+
console.error('Error al obtener las tarjetas del contenedor:', error);
|
|
78
|
+
this.tarjetas = [];
|
|
253
79
|
}
|
|
254
80
|
});
|
|
255
81
|
}
|
|
256
82
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
83
|
+
private mapearTarjeta(d: any): AnyTarjetaConfig {
|
|
84
|
+
const tipoMap: Record<string, AnyTarjetaConfig['type']> = {
|
|
85
|
+
'Única': 'single',
|
|
86
|
+
'Múltiple': 'multiple',
|
|
87
|
+
'Reporte': 'report',
|
|
88
|
+
'Personalizada': 'custom'
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const base = {
|
|
92
|
+
type: tipoMap[d.Tipo] ?? 'single',
|
|
93
|
+
position: d['Posición'],
|
|
94
|
+
titulo: d['Título'],
|
|
95
|
+
descripcion: d['Descripción'],
|
|
96
|
+
ColorDeBorde: d.ColorDeBorde
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
switch (d.Tipo) {
|
|
100
|
+
case 'Única':
|
|
101
|
+
return { ...base, type: 'single', rutaASeguir: d.RutaASeguir ?? '', icono: d['Ícono'] ?? '', cantidad: d.Cantidad, cantidadMaxima: d.CantidadMaxima } as TarjetaConfig;
|
|
102
|
+
case 'Múltiple':
|
|
103
|
+
return {
|
|
104
|
+
...base, type: 'multiple',
|
|
105
|
+
rutas: (d.Rutas ?? []).map((r: any) => ({ nombre: r.Nombre, ruta: r.Ruta }))
|
|
106
|
+
} as TarjetaMultipleConfig;
|
|
107
|
+
case 'Reporte':
|
|
108
|
+
return { ...base, type: 'report', reporteAGenerar: d.ReporteAGenerar ?? '', icono: d['Ícono'] ?? '' } as TarjetaReporteConfig;
|
|
109
|
+
case 'Personalizada':
|
|
110
|
+
return { ...base, type: 'custom', icono: d['Ícono'] ?? '', etiqueta: d.Etiqueta ?? '', accion: d['Acción'] ?? '' } as TarjetaPersonalizadaConfig;
|
|
111
|
+
default:
|
|
112
|
+
return base as any;
|
|
113
|
+
}
|
|
279
114
|
}
|
|
280
115
|
|
|
281
116
|
drop(event: CdkDragDrop<AnyTarjetaConfig[]>) {
|
|
282
117
|
moveItemInArray(this.tarjetas, event.previousIndex, event.currentIndex);
|
|
283
|
-
// Update positions based on new order
|
|
284
118
|
this.tarjetas.forEach((tarjeta, index) => {
|
|
285
119
|
tarjeta.position = (index + 1) * 10;
|
|
286
120
|
});
|
package/templates/frontend/src/app/Paginas/gestion-de-reportes/gestion-de-reportes.component.html
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
<h1>Reportería del módulo</h1>
|
|
2
2
|
<div class="contenido">
|
|
3
3
|
<app-tarjeta-reporte [reporteAGenerar]="'ElReporte1'" titulo="Reporte número uno"
|
|
4
|
-
descripcion="
|
|
5
|
-
|
|
6
|
-
</
|
|
4
|
+
descripcion="Descarga un CSV con los datos de prueba del módulo." icono="pie_chart" ColorDeBorde="#3498db"
|
|
5
|
+
(GenerarReporte)="GenerarReporte($event)">
|
|
6
|
+
</app-tarjeta-reporte>
|
|
7
|
+
|
|
8
|
+
<app-tarjeta-reporte [reporteAGenerar]="'ReportePersonasHTML'" titulo="Reporte de personas"
|
|
9
|
+
descripcion="Abre un reporte HTML con el listado completo de personas registradas en el sistema." icono="people"
|
|
10
|
+
ColorDeBorde="#2ecc71" (GenerarReporte)="GenerarReporte($event)">
|
|
11
|
+
</app-tarjeta-reporte>
|
|
12
|
+
|
|
13
|
+
<app-tarjeta-reporte [reporteAGenerar]="'ReportePDF'" titulo="Reporte PDF de ejemplo"
|
|
14
|
+
descripcion="Abre un reporte PDF con el listado completo de personas registradas en el sistema."
|
|
15
|
+
icono="picture_as_pdf" ColorDeBorde="#e74c3c" (GenerarReporte)="GenerarReporte($event)">
|
|
16
|
+
</app-tarjeta-reporte>
|
|
17
|
+
</div>
|
package/templates/frontend/src/app/Paginas/gestion-de-reportes/gestion-de-reportes.component.ts
CHANGED
|
@@ -17,20 +17,58 @@ export class GestionDeReportesComponent {
|
|
|
17
17
|
|
|
18
18
|
GenerarReporte(event: { reporte: string }) {
|
|
19
19
|
if (event.reporte === 'ElReporte1') {
|
|
20
|
-
this.
|
|
21
|
-
responseType: 'text'
|
|
22
|
-
}).subscribe({
|
|
23
|
-
next: (datos: any) => {
|
|
24
|
-
const blob = new Blob([decodeURIComponent(datos)], { type: 'text/csv;charset=utf-8;' });
|
|
25
|
-
const enlace = document.createElement('a');
|
|
26
|
-
enlace.href = URL.createObjectURL(blob);
|
|
27
|
-
enlace.download = 'datos.csv';
|
|
28
|
-
enlace.click();
|
|
29
|
-
},
|
|
30
|
-
error: (error) => {
|
|
31
|
-
console.error('Problemas al intentar descargar el reporte: ', error);
|
|
32
|
-
},
|
|
33
|
-
});
|
|
20
|
+
this.descargarCSV(`${this.datosGlobalesService.ObtenerURL()}misc/DatosParaReporteCSV`, 'datos.csv');
|
|
34
21
|
}
|
|
22
|
+
if (event.reporte === 'ReportePersonasHTML') {
|
|
23
|
+
this.abrirReporteHTML(`${this.datosGlobalesService.ObtenerURL()}Personas/reporteHTML`);
|
|
24
|
+
}
|
|
25
|
+
if (event.reporte === 'ReportePDF') {
|
|
26
|
+
this.abrirReportePDF(`${this.datosGlobalesService.ObtenerURL()}Personas/reportePDF`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private descargarCSV(url: string, nombreArchivo: string): void {
|
|
31
|
+
this.http.get(url, { responseType: 'text' }).subscribe({
|
|
32
|
+
next: (datos: any) => {
|
|
33
|
+
const blob = new Blob([decodeURIComponent(datos)], { type: 'text/csv;charset=utf-8;' });
|
|
34
|
+
const enlace = document.createElement('a');
|
|
35
|
+
enlace.href = URL.createObjectURL(blob);
|
|
36
|
+
enlace.download = nombreArchivo;
|
|
37
|
+
enlace.click();
|
|
38
|
+
URL.revokeObjectURL(enlace.href);
|
|
39
|
+
},
|
|
40
|
+
error: (error) => {
|
|
41
|
+
console.error('Problemas al intentar descargar el reporte: ', error);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private abrirReporteHTML(url: string): void {
|
|
47
|
+
this.http.get(url, { responseType: 'text' }).subscribe({
|
|
48
|
+
next: (html: string) => {
|
|
49
|
+
const nuevaPestana = window.open('', '_blank');
|
|
50
|
+
if (nuevaPestana) {
|
|
51
|
+
nuevaPestana.document.write(decodeURI(html));
|
|
52
|
+
nuevaPestana.document.close();
|
|
53
|
+
} else {
|
|
54
|
+
console.error('No se pudo abrir la nueva pestaña. Verifica que no esté bloqueada.');
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
error: (error) => {
|
|
58
|
+
console.error('Problemas al obtener el reporte HTML: ', error);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private abrirReportePDF(url: string): void {
|
|
64
|
+
this.http.get(url, { responseType: 'blob' }).subscribe({
|
|
65
|
+
next: (pdfBlob: Blob) => {
|
|
66
|
+
const urlBlob = window.URL.createObjectURL(pdfBlob);
|
|
67
|
+
window.open(urlBlob, '_blank');
|
|
68
|
+
},
|
|
69
|
+
error: (error) => {
|
|
70
|
+
console.error('Problemas al obtener el reporte PDF: ', error);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
35
73
|
}
|
|
36
74
|
}
|
|
@@ -9,6 +9,10 @@ export const routes: Routes = [
|
|
|
9
9
|
path: 'Actividad',
|
|
10
10
|
loadComponent: () => import('./Componentes/Nucleo/gestion-actividad/gestion-actividad.component').then(m => m.GestionActividadComponent)
|
|
11
11
|
},
|
|
12
|
+
{
|
|
13
|
+
path: 'manual',
|
|
14
|
+
loadComponent: () => import('./Componentes/Nucleo/manual/manual.component').then(m => m.ManualComponent)
|
|
15
|
+
},
|
|
12
16
|
{
|
|
13
17
|
path: 'tabla',
|
|
14
18
|
loadComponent: () => import('./Paginas/gestion-tabla/gestion-tabla.component').then(m => m.GestionTablaComponent)
|