utn-cli 2.1.39 → 2.1.41
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 +1 -1
- package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.css +65 -0
- package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.html +17 -0
- package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.ts +41 -0
- package/templates/frontend/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.html +8 -19
- package/templates/frontend/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.ts +103 -14
package/package.json
CHANGED
package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.css
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.instruccion {
|
|
2
|
+
font-size: 0.875rem;
|
|
3
|
+
color: #555;
|
|
4
|
+
margin: 0 0 1rem 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.lista-items {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
gap: 0.5rem;
|
|
11
|
+
min-width: 280px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.item {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: 0.75rem;
|
|
18
|
+
padding: 0.75rem 1rem;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
background: #f5f8ff;
|
|
21
|
+
border-left: 4px solid #1976d2;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.handle {
|
|
25
|
+
color: #999;
|
|
26
|
+
cursor: grab;
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.handle:active {
|
|
31
|
+
cursor: grabbing;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.item-icono {
|
|
35
|
+
color: #1976d2;
|
|
36
|
+
flex-shrink: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.item-etiqueta {
|
|
40
|
+
flex: 1;
|
|
41
|
+
font-size: 0.95rem;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.cdk-drag-preview {
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
gap: 0.75rem;
|
|
48
|
+
padding: 0.75rem 1rem;
|
|
49
|
+
border-radius: 8px;
|
|
50
|
+
background: white;
|
|
51
|
+
border-left: 4px solid #1976d2;
|
|
52
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.cdk-drag-placeholder {
|
|
56
|
+
opacity: 0.3;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.cdk-drag-animating {
|
|
60
|
+
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.lista-items.cdk-drop-list-dragging .item:not(.cdk-drag-placeholder) {
|
|
64
|
+
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
|
65
|
+
}
|
package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.html
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<h2 mat-dialog-title>Reordenar menú</h2>
|
|
2
|
+
<mat-dialog-content>
|
|
3
|
+
<p class="instruccion">Arrastrá los elementos para cambiar el orden.</p>
|
|
4
|
+
<div cdkDropList (cdkDropListDropped)="drop($event)" class="lista-items">
|
|
5
|
+
@for (item of items; track item.id) {
|
|
6
|
+
<div cdkDrag class="item">
|
|
7
|
+
<mat-icon cdkDragHandle class="handle">drag_indicator</mat-icon>
|
|
8
|
+
<mat-icon class="item-icono">{{ item.icono }}</mat-icon>
|
|
9
|
+
<span class="item-etiqueta">{{ item.etiqueta }}</span>
|
|
10
|
+
</div>
|
|
11
|
+
}
|
|
12
|
+
</div>
|
|
13
|
+
</mat-dialog-content>
|
|
14
|
+
<mat-dialog-actions>
|
|
15
|
+
<button mat-button (click)="cancelar()">Cancelar</button>
|
|
16
|
+
<button mat-flat-button color="primary" (click)="guardar()">Guardar</button>
|
|
17
|
+
</mat-dialog-actions>
|
package/templates/frontend/src/app/Componentes/Nucleo/reordenar-menu/reordenar-menu.component.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Component, Inject } from '@angular/core';
|
|
2
|
+
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogTitle, MatDialogContent, MatDialogActions } from '@angular/material/dialog';
|
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
5
|
+
import { DragDropModule, CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
|
6
|
+
|
|
7
|
+
export interface ItemDeMenuDialog {
|
|
8
|
+
id: string;
|
|
9
|
+
etiqueta: string;
|
|
10
|
+
icono: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-reordenar-menu',
|
|
15
|
+
standalone: true,
|
|
16
|
+
imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButtonModule, MatIconModule, DragDropModule],
|
|
17
|
+
templateUrl: './reordenar-menu.component.html',
|
|
18
|
+
styleUrl: './reordenar-menu.component.css'
|
|
19
|
+
})
|
|
20
|
+
export class ReordenarMenuComponent {
|
|
21
|
+
items: ItemDeMenuDialog[];
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
@Inject(MAT_DIALOG_DATA) public data: { items: ItemDeMenuDialog[] },
|
|
25
|
+
private dialogRef: MatDialogRef<ReordenarMenuComponent>
|
|
26
|
+
) {
|
|
27
|
+
this.items = [...data.items];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
drop(event: CdkDragDrop<ItemDeMenuDialog[]>): void {
|
|
31
|
+
moveItemInArray(this.items, event.previousIndex, event.currentIndex);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
guardar(): void {
|
|
35
|
+
this.dialogRef.close(this.items);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
cancelar(): void {
|
|
39
|
+
this.dialogRef.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -130,27 +130,16 @@
|
|
|
130
130
|
</button>
|
|
131
131
|
|
|
132
132
|
<mat-menu #menuAplicaciones="matMenu">
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
@if(TienePermiso) {
|
|
138
|
-
<button mat-menu-item (click)="irAActividad()" title="Actividad de la cuenta">
|
|
139
|
-
<mat-icon>history</mat-icon>
|
|
140
|
-
<span>Actividad de la cuenta</span>
|
|
141
|
-
</button>
|
|
142
|
-
<button mat-menu-item (click)="irAEstadisticasDelModulo()" title="Estadísticas del módulo">
|
|
143
|
-
<mat-icon>bar_chart</mat-icon>
|
|
144
|
-
<span>Estadísticas del módulo</span>
|
|
133
|
+
@for (item of itemsDeMenuVisibles; track item.id) {
|
|
134
|
+
<button mat-menu-item (click)="item.accion()" [title]="item.etiqueta">
|
|
135
|
+
<mat-icon>{{ item.icono }}</mat-icon>
|
|
136
|
+
<span>{{ item.etiqueta }}</span>
|
|
145
137
|
</button>
|
|
146
138
|
}
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
<button mat-menu-item (click)="irADeclaracionIA()" title="Declaración de uso de inteligencia artificial">
|
|
152
|
-
<mat-icon>smart_toy</mat-icon>
|
|
153
|
-
<span>Declaración de IA</span>
|
|
139
|
+
<mat-divider></mat-divider>
|
|
140
|
+
<button mat-menu-item (click)="abrirDialogReordenarMenu()" title="Reordenar elementos del menú">
|
|
141
|
+
<mat-icon>sort</mat-icon>
|
|
142
|
+
<span>Reordenar</span>
|
|
154
143
|
</button>
|
|
155
144
|
</mat-menu>
|
|
156
145
|
|
|
@@ -6,17 +6,23 @@ 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 {
|
|
10
|
-
import {
|
|
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';
|
|
13
|
-
import { EstadisticasDelModuloComponent } from '../../../Componentes/Nucleo/estadisticas-del-modulo/estadisticas-del-modulo.component';
|
|
9
|
+
import { MatDividerModule } from '@angular/material/divider';
|
|
10
|
+
import type { ItemDeMenuDialog } from '../../../Componentes/Nucleo/reordenar-menu/reordenar-menu.component';
|
|
14
11
|
|
|
15
12
|
import { MatMenuModule } from '@angular/material/menu';
|
|
16
13
|
|
|
14
|
+
interface ItemDeMenu {
|
|
15
|
+
id: string;
|
|
16
|
+
etiqueta: string;
|
|
17
|
+
icono: string;
|
|
18
|
+
accion: () => void;
|
|
19
|
+
requierePermiso: boolean;
|
|
20
|
+
posicion: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
@Component({
|
|
18
24
|
selector: 'app-contenedor-componentes',
|
|
19
|
-
imports: [RouterOutlet, MatIconModule, MatTooltipModule, CommonModule, MatMenuModule],
|
|
25
|
+
imports: [RouterOutlet, MatIconModule, MatTooltipModule, CommonModule, MatMenuModule, MatDividerModule],
|
|
20
26
|
templateUrl: './contenedor-componentes.component.html',
|
|
21
27
|
styleUrl: './contenedor-componentes.component.css'
|
|
22
28
|
})
|
|
@@ -41,6 +47,12 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
41
47
|
public AnimarUsuariosActivos: boolean = true;
|
|
42
48
|
private intervaloUsuarios: any;
|
|
43
49
|
|
|
50
|
+
public itemsDeMenu: ItemDeMenu[] = [];
|
|
51
|
+
|
|
52
|
+
get itemsDeMenuVisibles(): ItemDeMenu[] {
|
|
53
|
+
return this.itemsDeMenu.filter(i => !i.requierePermiso || this.TienePermiso);
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
get esDashboard(): boolean { return this.router.url === '/'; }
|
|
45
57
|
get tieneTarjetas(): boolean { return this.datosGlobalesService.cantidadDeTarjetas$.value > 0; }
|
|
46
58
|
get filtro(): string { return this.datosGlobalesService.filtroDeTarjetas$.value; }
|
|
@@ -69,7 +81,79 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
69
81
|
return datos ? JSON.parse(datos) : [];
|
|
70
82
|
}
|
|
71
83
|
|
|
84
|
+
private inicializarItemsDeMenu(): void {
|
|
85
|
+
this.itemsDeMenu = [
|
|
86
|
+
{ id: 'nav_sugerencias', etiqueta: 'Sugerencias', icono: 'lightbulb', accion: () => this.irASugerencias(), requierePermiso: false, posicion: 10 },
|
|
87
|
+
{ id: 'nav_actividad', etiqueta: 'Actividad de la cuenta', icono: 'history', accion: () => this.irAActividad(), requierePermiso: true, posicion: 20 },
|
|
88
|
+
{ id: 'nav_estadisticas', etiqueta: 'Estadísticas del módulo', icono: 'bar_chart', accion: () => this.irAEstadisticasDelModulo(), requierePermiso: true, posicion: 30 },
|
|
89
|
+
{ id: 'nav_accesibilidad', etiqueta: 'Accesibilidad', icono: 'accessibility', accion: () => this.irAAccesibilidad(), requierePermiso: false, posicion: 40 },
|
|
90
|
+
{ id: 'nav_declaracion_ia', etiqueta: 'Declaración de IA', icono: 'smart_toy', accion: () => this.irADeclaracionIA(), requierePermiso: false, posicion: 50 },
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private cargarOrdenDelMenu(): void {
|
|
95
|
+
this.http.get(`${this.datosGlobalesService.ObtenerURL()}ConfiguracionDeTarjetas/obtener`).subscribe({
|
|
96
|
+
next: (datos: any) => {
|
|
97
|
+
const config: { Titulo: string; Posicion: number }[] = datos.body ?? [];
|
|
98
|
+
const navConfig = config.filter((c: any) => c.Titulo.startsWith('nav_'));
|
|
99
|
+
if (navConfig.length === 0) return;
|
|
100
|
+
navConfig.forEach((c: any) => {
|
|
101
|
+
const item = this.itemsDeMenu.find(i => i.id === c.Titulo);
|
|
102
|
+
if (item) item.posicion = c.Posicion;
|
|
103
|
+
});
|
|
104
|
+
this.itemsDeMenu.sort((a, b) => a.posicion - b.posicion);
|
|
105
|
+
},
|
|
106
|
+
error: () => { }
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async abrirDialogReordenarMenu(): Promise<void> {
|
|
111
|
+
const itemsVisibles: ItemDeMenuDialog[] = this.itemsDeMenuVisibles.map(i => ({
|
|
112
|
+
id: i.id,
|
|
113
|
+
etiqueta: i.etiqueta,
|
|
114
|
+
icono: i.icono
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
const { ReordenarMenuComponent } = await import('../../../Componentes/Nucleo/reordenar-menu/reordenar-menu.component');
|
|
118
|
+
this.dialog.open(ReordenarMenuComponent, { data: { items: itemsVisibles } })
|
|
119
|
+
.afterClosed()
|
|
120
|
+
.subscribe((resultado: ItemDeMenuDialog[] | undefined) => {
|
|
121
|
+
if (!resultado) return;
|
|
122
|
+
this.persistirOrdenDelMenu(resultado);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private persistirOrdenDelMenu(itemsOrdenados: ItemDeMenuDialog[]): void {
|
|
127
|
+
const idsOrdenados = itemsOrdenados.map(i => i.id);
|
|
128
|
+
const itemsNoVisibles = this.itemsDeMenu.filter(i => !idsOrdenados.includes(i.id));
|
|
129
|
+
const itemsVisiblesReordenados = idsOrdenados
|
|
130
|
+
.map(id => this.itemsDeMenu.find(i => i.id === id)!)
|
|
131
|
+
.filter(Boolean);
|
|
132
|
+
|
|
133
|
+
itemsVisiblesReordenados.forEach((item, index) => {
|
|
134
|
+
item.posicion = (index + 1) * 10;
|
|
135
|
+
});
|
|
136
|
+
itemsNoVisibles.forEach((item, index) => {
|
|
137
|
+
item.posicion = (itemsVisiblesReordenados.length + index + 1) * 10;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
this.itemsDeMenu = [...itemsVisiblesReordenados, ...itemsNoVisibles];
|
|
141
|
+
|
|
142
|
+
const Configuraciones = this.itemsDeMenu.map(i => ({
|
|
143
|
+
Titulo: i.id,
|
|
144
|
+
Posicion: i.posicion,
|
|
145
|
+
ColorDeBorde: null
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
this.http.post(`${this.datosGlobalesService.ObtenerURL()}ConfiguracionDeTarjetas/actualizar`, {
|
|
149
|
+
Configuraciones
|
|
150
|
+
}).subscribe({ error: () => { } });
|
|
151
|
+
}
|
|
152
|
+
|
|
72
153
|
ngOnInit() {
|
|
154
|
+
this.inicializarItemsDeMenu();
|
|
155
|
+
this.cargarOrdenDelMenu();
|
|
156
|
+
|
|
73
157
|
const url = window.location.href.toLowerCase();
|
|
74
158
|
if (url.includes('calidad')) {
|
|
75
159
|
this.claseDelContenedor = 'contenedor calidad';
|
|
@@ -86,7 +170,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
86
170
|
}, 60000);
|
|
87
171
|
});
|
|
88
172
|
|
|
89
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/inicializar').subscribe((datos: any) => {
|
|
173
|
+
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/inicializar').subscribe(async (datos: any) => {
|
|
90
174
|
const body = datos.body;
|
|
91
175
|
|
|
92
176
|
this.TienePermiso = body.TienePermiso;
|
|
@@ -108,6 +192,8 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
108
192
|
this.EnlaceDelVideo = body.EnlaceDelVideo;
|
|
109
193
|
this.Mensajes = body.Notificaciones;
|
|
110
194
|
|
|
195
|
+
const { MensajeConfirmacionHTMLComponent } = await import('../../../Componentes/Nucleo/mensaje-confirmacion-html/mensaje-confirmacion-html');
|
|
196
|
+
|
|
111
197
|
if (body.Consentimiento?.Aceptaciones === 0) {
|
|
112
198
|
const ConsentimientoInformadoId = body.Consentimiento.Consentimiento[0].ConsentimientoInformadoId;
|
|
113
199
|
this.dialog.open(MensajeConfirmacionHTMLComponent, {
|
|
@@ -172,10 +258,10 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
172
258
|
}
|
|
173
259
|
|
|
174
260
|
irAMensajes(): void {
|
|
175
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/obtenerNotificaciones').subscribe((datos: any) => {
|
|
176
|
-
|
|
177
|
-
this.dialog.open(MensajesComponent, { data });
|
|
178
|
-
})
|
|
261
|
+
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/obtenerNotificaciones').subscribe(async (datos: any) => {
|
|
262
|
+
const { MensajesComponent } = await import('../../../Componentes/Nucleo/mensajes/mensajes.component');
|
|
263
|
+
this.dialog.open(MensajesComponent, { data: datos.body });
|
|
264
|
+
});
|
|
179
265
|
}
|
|
180
266
|
|
|
181
267
|
irAAyuda(): void {
|
|
@@ -194,7 +280,8 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
194
280
|
window.open(this.EnlaceDelVideo, '_blank', 'noopener,noreferrer');
|
|
195
281
|
}
|
|
196
282
|
|
|
197
|
-
irASoporte(): void {
|
|
283
|
+
async irASoporte(): Promise<void> {
|
|
284
|
+
const { ReporteDeIncidenciasComponent } = await import('../../../Componentes/Nucleo/reporte-de-incidencias/reporte-de-incidencias.component');
|
|
198
285
|
this.dialog.open(ReporteDeIncidenciasComponent);
|
|
199
286
|
}
|
|
200
287
|
|
|
@@ -221,12 +308,14 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
|
|
|
221
308
|
})
|
|
222
309
|
}
|
|
223
310
|
|
|
224
|
-
irASugerencias(): void {
|
|
311
|
+
async irASugerencias(): Promise<void> {
|
|
312
|
+
const { ReporteDeSugerenciasComponent } = await import('../../../Componentes/Nucleo/reporte-de-sugerencias/reporte-de-sugerencias.component');
|
|
225
313
|
this.dialog.open(ReporteDeSugerenciasComponent);
|
|
226
314
|
}
|
|
227
315
|
|
|
228
316
|
irAEstadisticasDelModulo(): void {
|
|
229
|
-
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/obtenerVistas').subscribe((datos: any) => {
|
|
317
|
+
this.http.get(this.datosGlobalesService.ObtenerURL() + 'misc/obtenerVistas').subscribe(async (datos: any) => {
|
|
318
|
+
const { EstadisticasDelModuloComponent } = await import('../../../Componentes/Nucleo/estadisticas-del-modulo/estadisticas-del-modulo.component');
|
|
230
319
|
this.dialog.open(EstadisticasDelModuloComponent, { data: datos.body });
|
|
231
320
|
});
|
|
232
321
|
}
|