utn-cli 2.0.42 → 2.0.43
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/commands/backend.js +7 -7
- package/package.json +1 -1
- package/templates/backend/InformacionDelModulo.json +1 -1
- package/templates/backend/servicios/InformacionDelModulo.js +2 -2
- package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.css +11 -0
- package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.html +11 -7
- package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.ts +78 -10
package/commands/backend.js
CHANGED
|
@@ -40,7 +40,7 @@ async function inicializarProyectoBackend() {
|
|
|
40
40
|
|
|
41
41
|
const NOMBRE_DEL_PROYECTO = await askAndReplace('NOMBRE_DEL_PROYECTO', '¿Cuál es el nombre del proyecto?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_PROYECTO');
|
|
42
42
|
await askAndReplace('DESCRIPCION_DEL_PROYECTO', '¿Cuál es la descripción del proyecto?: ', rutaDeInformacionDelModulo, 'DESCRIPCION_DEL_PROYECTO');
|
|
43
|
-
await askAndReplace('DETALLE_DEL_PROYECTO', '¿Cuál es detalle del proyecto?: ', rutaDeInformacionDelModulo, 'DETALLE_DEL_PROYECTO');
|
|
43
|
+
await askAndReplace('DETALLE_DEL_PROYECTO', '¿Cuál es el detalle del proyecto?: ', rutaDeInformacionDelModulo, 'DETALLE_DEL_PROYECTO');
|
|
44
44
|
|
|
45
45
|
const NOMBRE_DEL_CANONICO_DEL_PROYECTO = await askAndReplace('NOMBRE_DEL_CANONICO_DEL_PROYECTO', '¿Cuál es el nombre canónico del proyecto?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_CANONICO_DEL_PROYECTO', (val) => {
|
|
46
46
|
const oldFileName = path.join(process.cwd(), 'NOMBRE_DEL_CANONICO_DEL_PROYECTO.rest');
|
|
@@ -58,7 +58,7 @@ async function inicializarProyectoBackend() {
|
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
await askAndReplace('TIPO_DE_TARJETA', '¿Cuál es tipo de tarjeta? Posibles valores: Área, Proceso, Servicio: ', rutaDeInformacionDelModulo, 'TIPO_DE_TARJETA');
|
|
61
|
+
await askAndReplace('TIPO_DE_TARJETA', '¿Cuál es el tipo de tarjeta? Posibles valores: Área, Proceso, Servicio: ', rutaDeInformacionDelModulo, 'TIPO_DE_TARJETA');
|
|
62
62
|
await askAndReplace('NOMBRE_DEL_ROL', '¿Cuál es el nombre del rol?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_ROL');
|
|
63
63
|
|
|
64
64
|
const NOMBRE_DEL_REPOSITORIO_DE_BASE_DE_DATOS = await askAndReplace('NOMBRE_DEL_REPOSITORIO_DE_BASE_DE_DATOS', '¿Cuál es el nombre del repositorio de base de datos?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_REPOSITORIO_DE_BASE_DE_DATOS', (val) => {
|
|
@@ -82,17 +82,17 @@ async function inicializarProyectoBackend() {
|
|
|
82
82
|
await askAndReplace('NOMBRE_DEL_REPOSITORIO_DE_FRONTEND', '¿Cuál es el nombre del repositorio de frontend?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_REPOSITORIO_DE_FRONTEND');
|
|
83
83
|
await askAndReplace('NOMBRE_DEL_PERMISO', '¿Cuál es el nombre del permiso?: ', rutaDeInformacionDelModulo, 'NOMBRE_DEL_PERMISO');
|
|
84
84
|
await askAndReplace('DESCRIPCION_DEL_PERMISO', '¿Cuál es la descripción del permiso?: ', rutaDeInformacionDelModulo, 'DESCRIPCION_DEL_PERMISO');
|
|
85
|
-
await askAndReplace('MENU_PADRE', '¿Cuál es nombre canónico del menú padre?: ', rutaDeInformacionDelModulo, 'MENU_PADRE');
|
|
85
|
+
await askAndReplace('MENU_PADRE', '¿Cuál es el nombre canónico del menú padre?: ', rutaDeInformacionDelModulo, 'MENU_PADRE');
|
|
86
86
|
await askAndReplace('COLOR_DEL_MODULO', '¿Cuál es el color del módulo?: ', rutaDeInformacionDelModulo, 'COLOR_DEL_MODULO');
|
|
87
|
-
await askAndReplace('
|
|
87
|
+
await askAndReplace('CORREO_PARA_REPORTES', '¿Cuál es el correo para reportes?: ', rutaDeInformacionDelModulo, 'CORREO_PARA_REPORTES');
|
|
88
88
|
|
|
89
|
-
const nombre_de_desarrollador = await askAndReplace('nombre_de_desarrollador', '¿Cuál es el nombre
|
|
89
|
+
const nombre_de_desarrollador = await askAndReplace('nombre_de_desarrollador', '¿Cuál es el nombre del desarrollador?: ', path.join(process.cwd(), 'package.json'), 'nombre_de_desarrollador', (val) => {
|
|
90
90
|
reemplazarContenidoEnArchivo(path.join(process.cwd(), 'package.json'), 'nombre_de_desarrollador', `Para la Universidad Técnica Nacional por: ${val}`);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
await askAndReplace('CEDULA_DEL_DESARROLLADOR', '¿Cuál es el número de cédula del desarrollador?: ', rutaDeInformacionDelModulo, 'CEDULA_DEL_DESARROLLADOR');
|
|
94
94
|
|
|
95
|
-
const url_del_grupo = await askAndReplace('url_del_grupo', '¿Cuál es
|
|
95
|
+
const url_del_grupo = await askAndReplace('url_del_grupo', '¿Cuál es la URL del grupo en el Git?: ', path.join(process.cwd(), 'package.json'), 'url_del_grupo', (val) => {
|
|
96
96
|
reemplazarContenidoEnArchivo(path.join(process.cwd(), 'package.json'), 'url_del_grupo', val);
|
|
97
97
|
});
|
|
98
98
|
|
|
@@ -117,7 +117,7 @@ async function inicializarProyectoBackend() {
|
|
|
117
117
|
reemplazarContenidoEnArchivo(rutaDeInformacionDelModulo, 'BACKENDS_QUE_CONSUME_ESTE_MODULO', '');
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
await askAndReplace('VERSION', '¿Cuál es versión del módulo?: ', rutaDeInformacionDelModulo, 'VERSION');
|
|
120
|
+
await askAndReplace('VERSION', '¿Cuál es la versión del módulo?: ', rutaDeInformacionDelModulo, 'VERSION');
|
|
121
121
|
|
|
122
122
|
fs.writeFileSync(rutaDeInformacionDelModuloJson, JSON.stringify(informacionDelModuloJson, null, 2));
|
|
123
123
|
}
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"DESCRIPCION_DEL_PERMISO": "DESCRIPCION_DEL_PERMISO",
|
|
13
13
|
"MENU_PADRE": "MENU_PADRE",
|
|
14
14
|
"COLOR_DEL_MODULO": "COLOR_DEL_MODULO",
|
|
15
|
-
"
|
|
15
|
+
"CORREO_PARA_REPORTES": "CORREO_PARA_REPORTES",
|
|
16
16
|
"nombre_de_desarrollador": "nombre_de_desarrollador",
|
|
17
17
|
"CEDULA_DEL_DESARROLLADOR": "CEDULA_DEL_DESARROLLADOR",
|
|
18
18
|
"url_del_grupo": "url_del_grupo",
|
|
@@ -53,14 +53,14 @@ class InformacionDelModulo {
|
|
|
53
53
|
};
|
|
54
54
|
getUsuariosConAccesoInicial() {
|
|
55
55
|
// UsuariosConAccesoInicial es un arreglo de strings de la forma ['111050570', '111050570']
|
|
56
|
-
// Este arreglo se usa para asignar acceso a este
|
|
56
|
+
// Este arreglo se usa para asignar acceso a este módulo, suelen usarse las cédulas de los encargados del proyecto y el desarrollador
|
|
57
57
|
return ['111050570', '204540859', '602990078', '109840817', '206860639', '155821845336', 'CEDULA_DEL_DESARROLLADOR'];
|
|
58
58
|
};
|
|
59
59
|
getColorDelModulo() {
|
|
60
60
|
return 'COLOR_DEL_MODULO';
|
|
61
61
|
};
|
|
62
62
|
getCorreoParaReportes() {
|
|
63
|
-
return '
|
|
63
|
+
return 'CORREO_PARA_REPORTES';
|
|
64
64
|
};
|
|
65
65
|
getVersion() {
|
|
66
66
|
return 'VERSION';
|
package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.css
CHANGED
|
@@ -61,6 +61,17 @@ button:focus {
|
|
|
61
61
|
box-sizing: border-box;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
.zona-archivo.deshabilitado {
|
|
65
|
+
border-color: #bdc3c7;
|
|
66
|
+
background-color: #f8f9fa;
|
|
67
|
+
cursor: not-allowed;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.texto-limite {
|
|
71
|
+
color: #e74c3c;
|
|
72
|
+
font-weight: bold;
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
/* Centrado del mensaje vacío */
|
|
65
76
|
.mensaje-vacio {
|
|
66
77
|
display: flex;
|
package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.html
CHANGED
|
@@ -17,16 +17,20 @@
|
|
|
17
17
|
}
|
|
18
18
|
</div>
|
|
19
19
|
@if(EsEditable) {
|
|
20
|
-
<div class="zona-archivo" (click)="AbrirGestorDeArchivos()" (dragover)="ArrastrarAdentro($event)"
|
|
20
|
+
<div class="zona-archivo" [class.deshabilitado]="ListaArchivos.length >= CantidadMaximaArchivos" (click)="AbrirGestorDeArchivos()" (dragover)="ArrastrarAdentro($event)"
|
|
21
21
|
(dragleave)="ArrastrarAfuera($event)" (drop)="Soltar($event)">
|
|
22
|
-
@if(
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
@if(ListaArchivos.length >= CantidadMaximaArchivos) {
|
|
23
|
+
<p class="texto-limite">Límite de {{CantidadMaximaArchivos}} archivos alcanzado</p>
|
|
24
|
+
} @else {
|
|
25
|
+
@if(!Archivo){
|
|
26
|
+
<p class="texto">Arrastra y suelta un archivo aquí o <span class="texto-clic">haz clic para subir</span></p>
|
|
27
|
+
}
|
|
28
|
+
@else{
|
|
29
|
+
<p>Archivo seleccionado: {{ Archivo.name }}</p>
|
|
30
|
+
}
|
|
27
31
|
}
|
|
28
32
|
<!-- Input oculto para seleccionar archivos manualmente -->
|
|
29
|
-
<input type="file" #
|
|
33
|
+
<input type="file" #EntradaDeArchivo hidden (change)="ArchivoSeleccionado($event)" [accept]="FormatosPermitidos.join(',')">
|
|
30
34
|
</div>
|
|
31
35
|
} @else {
|
|
32
36
|
@if(ListaArchivos.length === 0) {
|
package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, ElementRef, inject, OnInit, ViewChild } from '@angular/core';
|
|
1
|
+
import { Component, ElementRef, inject, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
|
|
2
2
|
import { MatButtonModule } from '@angular/material/button';
|
|
3
3
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|
4
4
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
@@ -17,7 +17,10 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
17
17
|
readonly dialogRef = inject(MatDialogRef<SubirArchivoComponent>);
|
|
18
18
|
Archivo: any;
|
|
19
19
|
ListaArchivos: any[] = []
|
|
20
|
-
|
|
20
|
+
HaCargadoArchivos: boolean = false;
|
|
21
|
+
CantidadMaximaDeArchivos: number = 99;
|
|
22
|
+
@Output() HaCargadoArchivosChange = new EventEmitter<boolean>();
|
|
23
|
+
@ViewChild('EntradaDeArchivo') EntradaDeArchivo!: ElementRef<HTMLInputElement>;
|
|
21
24
|
readonly data = inject(MAT_DIALOG_DATA);
|
|
22
25
|
Permiso = '--Permiso=' + this.data.Permiso;
|
|
23
26
|
Etiqueta = this.data.Etiqueta + this.Permiso;
|
|
@@ -39,12 +42,16 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
39
42
|
if (this.data.FormatosPermitidos) {
|
|
40
43
|
this.FormatosPermitidos = this.data.FormatosPermitidos;
|
|
41
44
|
}
|
|
45
|
+
if (this.data.CantidadMaximaDeArchivos) {
|
|
46
|
+
this.CantidadMaximaDeArchivos = this.data.CantidadMaximaDeArchivos;
|
|
47
|
+
}
|
|
42
48
|
this.ListarArchivos(this.Etiqueta)
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
ArrastrarAdentro(event: DragEvent) {
|
|
46
52
|
event.preventDefault();
|
|
47
53
|
event.stopPropagation();
|
|
54
|
+
if (this.ListaArchivos.length >= this.CantidadMaximaDeArchivos) return;
|
|
48
55
|
const archivoZona = event.target as HTMLElement;
|
|
49
56
|
archivoZona.classList.add('arrastrar');
|
|
50
57
|
}
|
|
@@ -59,6 +66,20 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
59
66
|
event.stopPropagation();
|
|
60
67
|
const archivoZona = event.target as HTMLElement;
|
|
61
68
|
archivoZona.classList.remove('arrastrar');
|
|
69
|
+
|
|
70
|
+
if (this.ListaArchivos.length >= this.CantidadMaximaDeArchivos) {
|
|
71
|
+
this.dialog.open(MensajeConfirmacionComponent, {
|
|
72
|
+
data: {
|
|
73
|
+
titulo: 'Límite alcanzado',
|
|
74
|
+
mensaje: 'Se ha alcanzado la cantidad máxima de archivos permitidos (' + this.CantidadMaximaDeArchivos + ').',
|
|
75
|
+
textoAceptar: 'Continuar',
|
|
76
|
+
onClose: () => { },
|
|
77
|
+
onAccept: () => { },
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
62
83
|
if (event.dataTransfer?.files.length && this.EsEditable) {
|
|
63
84
|
const archivoArrastrado = event.dataTransfer.files[0];
|
|
64
85
|
if (this.ValidarFormato(archivoArrastrado)) {
|
|
@@ -67,7 +88,7 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
67
88
|
this.dialog.open(MensajeConfirmacionComponent, {
|
|
68
89
|
data: {
|
|
69
90
|
titulo: 'Formato de archivo incorrecto',
|
|
70
|
-
mensaje: 'El formato de archivo no permitido. Los formatos permitidos son: ' + this.FormatosPermitidos.join(', '),
|
|
91
|
+
mensaje: 'El formato de archivo no está permitido. Los formatos permitidos son: ' + this.FormatosPermitidos.join(', '),
|
|
71
92
|
textoAceptar: 'Continuar',
|
|
72
93
|
onClose: () => { },
|
|
73
94
|
onAccept: () => { },
|
|
@@ -78,14 +99,37 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
78
99
|
}
|
|
79
100
|
|
|
80
101
|
ArchivoSeleccionado(event: Event) {
|
|
102
|
+
if (this.ListaArchivos.length >= this.CantidadMaximaDeArchivos) {
|
|
103
|
+
this.dialog.open(MensajeConfirmacionComponent, {
|
|
104
|
+
data: {
|
|
105
|
+
titulo: 'Límite alcanzado',
|
|
106
|
+
mensaje: 'Se ha alcanzado la cantidad máxima de archivos permitidos (' + this.CantidadMaximaDeArchivos + ').',
|
|
107
|
+
textoAceptar: 'Continuar',
|
|
108
|
+
onClose: () => { },
|
|
109
|
+
onAccept: () => { },
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
const entrada = event.target as HTMLInputElement;
|
|
113
|
+
entrada.value = '';
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
81
117
|
const entrada = event.target as HTMLInputElement;
|
|
82
118
|
if (entrada.files?.length) {
|
|
83
119
|
const archivoSeleccionado = entrada.files[0];
|
|
84
120
|
if (this.ValidarFormato(archivoSeleccionado)) {
|
|
85
121
|
this.Archivo = archivoSeleccionado;
|
|
86
122
|
} else {
|
|
87
|
-
|
|
88
|
-
|
|
123
|
+
this.dialog.open(MensajeConfirmacionComponent, {
|
|
124
|
+
data: {
|
|
125
|
+
titulo: 'Formato de archivo incorrecto',
|
|
126
|
+
mensaje: 'El formato de archivo no está permitido. Los formatos permitidos son: ' + this.FormatosPermitidos.join(', '),
|
|
127
|
+
textoAceptar: 'Continuar',
|
|
128
|
+
onClose: () => { },
|
|
129
|
+
onAccept: () => { },
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
entrada.value = '';
|
|
89
133
|
}
|
|
90
134
|
}
|
|
91
135
|
}
|
|
@@ -99,13 +143,35 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
99
143
|
}
|
|
100
144
|
|
|
101
145
|
AbrirGestorDeArchivos() {
|
|
102
|
-
if (this.EsEditable) {
|
|
103
|
-
this.
|
|
146
|
+
if (this.EsEditable && this.ListaArchivos.length < this.CantidadMaximaDeArchivos) {
|
|
147
|
+
this.EntradaDeArchivo.nativeElement.click();
|
|
148
|
+
} else if (this.ListaArchivos.length >= this.CantidadMaximaDeArchivos) {
|
|
149
|
+
this.dialog.open(MensajeConfirmacionComponent, {
|
|
150
|
+
data: {
|
|
151
|
+
titulo: 'Límite alcanzado',
|
|
152
|
+
mensaje: 'Se ha alcanzado la cantidad máxima de archivos permitidos (' + this.CantidadMaximaDeArchivos + ').',
|
|
153
|
+
textoAceptar: 'Continuar',
|
|
154
|
+
onClose: () => { },
|
|
155
|
+
onAccept: () => { },
|
|
156
|
+
},
|
|
157
|
+
});
|
|
104
158
|
}
|
|
105
159
|
}
|
|
106
160
|
|
|
107
161
|
SubirArchivo() {
|
|
108
162
|
if (this.Archivo) {
|
|
163
|
+
if (this.ListaArchivos.length >= this.CantidadMaximaDeArchivos) {
|
|
164
|
+
this.dialog.open(MensajeConfirmacionComponent, {
|
|
165
|
+
data: {
|
|
166
|
+
titulo: 'Límite alcanzado',
|
|
167
|
+
mensaje: 'Se ha alcanzado la cantidad máxima de archivos permitidos (' + this.CantidadMaximaDeArchivos + ').',
|
|
168
|
+
textoAceptar: 'Continuar',
|
|
169
|
+
onClose: () => { },
|
|
170
|
+
onAccept: () => { },
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
109
175
|
let archivo = new FormData();
|
|
110
176
|
archivo.append("file", this.Archivo);
|
|
111
177
|
this.CargarArchivo(archivo, this.Etiqueta)
|
|
@@ -121,7 +187,7 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
121
187
|
this.ListarArchivos(Etiqueta)
|
|
122
188
|
},
|
|
123
189
|
error: (error) => {
|
|
124
|
-
console.error('Ocurrió un error
|
|
190
|
+
console.error('Ocurrió un error al guardar el archivo:', error);
|
|
125
191
|
}
|
|
126
192
|
})
|
|
127
193
|
}
|
|
@@ -131,9 +197,11 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
131
197
|
.subscribe({
|
|
132
198
|
next: (data: any) => {
|
|
133
199
|
this.ListaArchivos = data.body;
|
|
200
|
+
this.HaCargadoArchivos = this.ListaArchivos.length > 0;
|
|
201
|
+
this.HaCargadoArchivosChange.emit(this.HaCargadoArchivos);
|
|
134
202
|
},
|
|
135
203
|
error: (error) => {
|
|
136
|
-
console.error('Ocurrió un error
|
|
204
|
+
console.error('Ocurrió un error al listar los archivos:', error);
|
|
137
205
|
}
|
|
138
206
|
})
|
|
139
207
|
}
|
|
@@ -159,7 +227,7 @@ export class SubirArchivoComponent implements OnInit {
|
|
|
159
227
|
this.ListarArchivos(this.Etiqueta);
|
|
160
228
|
},
|
|
161
229
|
error: (error) => {
|
|
162
|
-
console.error('Ocurrió un error
|
|
230
|
+
console.error('Ocurrió un error al borrar el archivo:', error);
|
|
163
231
|
}
|
|
164
232
|
})
|
|
165
233
|
}
|