Merge branch 'desarrollo' into 'master'

Desarrollo

See merge request !2
parents 390d0eee acbf6245
......@@ -24,6 +24,7 @@ import { GlobalUserService } from 'src/app/core/http/user/global-user.service'
import { LoginUsuario } from './modules/main/Models/Login/loginUsuario';
import { OAuthService } from 'angular-oauth2-oidc';
import { HttpClient } from '@angular/common/http';
import { GlobalUser } from './types/user.types';
@Component({
......@@ -33,6 +34,8 @@ import { HttpClient } from '@angular/common/http';
})
export class AppComponent implements OnInit {
public isLoggedIn = false;
constructor(
private configService: ConfigService,
private renderer: Renderer2,
......@@ -42,7 +45,7 @@ export class AppComponent implements OnInit {
@Inject(LOCALE_ID) private localeId: string,
private layoutService: LayoutService,
private route: ActivatedRoute,
private navigationService: NavigationService,
public navigationService: NavigationService,
private splashScreenService: SplashScreenService,
private readonly matIconRegistry: MatIconRegistry,
private readonly domSanitizer: DomSanitizer,
......@@ -150,76 +153,107 @@ export class AppComponent implements OnInit {
});
// this.setInterval();
this.authService.globalUser$.subscribe(user => {
if (user) {
this.generateMenu(user); // Llamada al método que genera el menú dinámicamente
}
});
}
private generateMenu(user: GlobalUser): void {
const userEmail = user.correoInstitucional;
let menuOptions = [];
// Se agrega opciones específicas basadas en el correo electrónico
if (userEmail === 'jamolina13@espe.edu.ec' || userEmail === 'jacaceres1@espe.edu.ec' || userEmail === 'aczambrano3@espe.edu.ec') {
menuOptions.push(
{
type: 'link',
label: 'Lineas Operativas',
route: 'main/lineas',
icon: 'mat:format_list_numbered'
},
{
type: 'link',
label: 'Asignación Comisión',
route: 'main/Asignar-Comision',
icon: 'mat:fact_check'
},
{
type: 'link',
label: 'Configuraciones',
route: 'main/configuraciones',
icon: 'mat:settings'
}, {
type: 'link',
label: 'Usuarios',
route: 'main/PrincipalUsuarios',
icon: 'mat:settings'
},
{
type: 'link',
label: 'Convocatorias',
route: 'main/Convocatorias',
icon: 'mat:home'
},
{
type: 'link',
label: 'Programas',
route: 'main/Programas',
icon: 'mat:content_paste'
}
,
{
type: 'link',
label: 'Proyectos',
route: 'main/ListaProyectos',
icon: 'mat:home'
},
{
type: 'link',
label: 'Reporte Proyectos',
route: 'main/presupuesto',
icon: 'mat:settings'
},
{
type: 'link',
label: 'Aprobación Vicerrectorado',
route: 'main/ejemplo',
icon: 'mat:settings'
}
);
} else if (userEmail === 'jvzambrano4@espe.edu.ec') {
menuOptions.push(
{
type: 'link',
label: 'Proyectos',
route: 'main/ListaProyectos',
icon: 'mat:home'
}
);
}
this.navigationService.items = [
{
type: 'subheading',
label: 'Opciones',
children: [
{
type: 'link',
label: 'Lineas Operativas',
route: 'main/lineas',
icon: 'mat:format_list_numbered'
},
{
type: 'link',
label: 'Asignación Comisión',
route: 'main/Asignar-Comision',
icon: 'mat:fact_check'
},
{
type: 'link',
label: 'Configuraciones',
route: 'main/configuraciones',
icon: 'mat:settings'
}, {
type: 'link',
label: 'Usuarios',
route: 'main/PrincipalUsuarios',
icon: 'mat:settings'
},
{
type: 'link',
label: 'Convocatorias',
route: 'main/Convocatorias',
icon: 'mat:home'
},
{
type: 'link',
label: 'Programas',
route: 'main/Programas',
icon: 'mat:content_paste'
}
,
{
type: 'link',
label: 'Proyectos',
route: 'main/ListaProyectos',
icon: 'mat:home'
},
{
type: 'link',
label: 'Reporte Proyectos',
route: 'main/presupuesto',
icon: 'mat:settings'
},
{
type: 'link',
label: 'Aprobación Vicerrectorado',
route: 'main/ejemplo',
icon: 'mat:settings'
}
]
children: menuOptions
},
];
// this.setInterval();
}
public getNavigationService(): NavigationService {
return this.navigationService;
}
ngOnInit(): void {
this.authService.login();
}
login(): void {
......
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { AuthorizationService } from './AuthorizationService';
import { AuthService } from './auth.service';
import { MatDialog } from '@angular/material/dialog';
import { AccesoDenegadoComponent } from 'src/app/modules/main/pages/programa/opciones/AccesoDenegado/AccesoDenegado.component';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
formularioEnviado: boolean;
constructor(private authorizationService: AuthorizationService,
private router: Router,
private authService: AuthService,
private dialog: MatDialog
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree {
const requiredEmails = route.data['requiredEmails'] as string[];
const userCurrentEmail = this.authService.email;
if (this.authorizationService.hasAccess(requiredEmails)) {
return true;
} else {
console.log("Access denied for:", userCurrentEmail);
this.openModal();
return false;
}
}
openModal() {
const dialogRef = this.dialog.open(AccesoDenegadoComponent, {
width: '400px',
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
console.log('La ventana modal se ha cerrado');
this.formularioEnviado = true;
});
}
}
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class AuthorizationService {
private userEmail: string[] = [];
private perfiles: string[] = [];
setUserEmail(email: string[]) {
this.userEmail = email;
}
setperfiles(perfiles: string[]) {
this.perfiles = perfiles;
}
hasAccess(requiredEmail: string[]): boolean {
return requiredEmail.some(email => this.userEmail.includes(email));
}
hasAccessPerfiles(requiredPerfil: string[]): boolean {
return requiredPerfil.some(perfiles => this.perfiles.includes(perfiles));
}
}
......@@ -8,24 +8,35 @@ import { GlobalUser } from 'src/app/types/user.types';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { throwError, timer } from 'rxjs';
import { catchError, switchMap, timeout } from 'rxjs/operators';
import { AuthorizationService } from './AuthorizationService';
import { AccesoNoAutorizadoComponent } from 'src/app/modules/main/pages/programa/opciones/AccesoNoAutorizado/AccesoNoAutorizado.component';
@Injectable({
providedIn: 'root',
})
export class AuthService {
public isUiEnabled: boolean = false;
public isUiEnabled: boolean = false;
private isVerifying: boolean = false;
private globalUserSubject: BehaviorSubject<GlobalUser> =
new BehaviorSubject<GlobalUser>(null);
globalUser$: Observable<GlobalUser> = this.globalUserSubject.asObservable();
private userProfilesSubject: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
userProfiles$: Observable<string[]> = this.userProfilesSubject.asObservable();
formularioEnviado: boolean;
constructor(
private oAuthService: OAuthService,
private authorizationService: AuthorizationService,
private globalUserService: GlobalUserService,
private httpClient: HttpClient,
private router: Router
private router: Router,
private dialog: MatDialog
) {
this.configureOauthService();
}
......@@ -45,11 +56,15 @@ export class AuthService {
}
get username(): string {
return this.oAuthService.getIdentityClaims()['sub'];
}
get email(): string {
return this.oAuthService.getIdentityClaims()['email'];
}
login() {
if (!this.oAuthService.hasValidAccessToken()) {
this.oAuthService.initImplicitFlow();
......@@ -59,6 +74,8 @@ export class AuthService {
if (this.oAuthService.getIdentityClaims()) {
this.getGlobalUser();
//this.sendTokenToBackend();
const emails = [this.email];
this.authorizationService.setUserEmail(emails);
}
}
......@@ -76,25 +93,55 @@ export class AuthService {
}
private getGlobalUser() {
const email = this.oAuthService.getIdentityClaims()['email'];
this.isUiEnabled = false; // Deshabilitar la interfaz
const email = this.oAuthService.getIdentityClaims()['email'];
this.httpClient.get<boolean>(`http://localhost:8080/api/v1.0/users/by-email/${email}`).subscribe(
(exists: boolean) => {
(exists: boolean) => {
this.isVerifying = false; // Restaurar la bandera de verificación
if (exists) {
// Existe el email en la bdd
this.globalUserService.getUserByUsername(this.tokenClaims.username).subscribe(user => {
this.setGlobalUser(user);
this.isUiEnabled = true; // Habilitar la interfaz una vez que se completa la verificación
this.setGlobalUser(user);
this.getUserProfiles(email);
});
}
},
(error) => {
this.isUiEnabled = false;
this.logout();
this.openModal();
console.error('Error al verificar el email del usuario', error);
}
);
}
openModal() {
const dialogRef = this.dialog.open(AccesoNoAutorizadoComponent, {
width: '400px',
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
this.logout();
console.log('La ventana modal se ha cerrado');
});
}
private getUserProfiles(email: string) {
this.httpClient.get<string[]>(`http://localhost:8080/api/v1.0/usuario/findPerfilesByUsuarioEmail/${email}`).subscribe(
(profiles: string[]) => {
this.setGlobalUserProfiles(profiles); // Actualiza los perfiles del usuario
this.isUiEnabled = true; // Habilitar la interfaz una vez que se completó la verificación
},
(error) => {
console.error('Error al obtener los perfiles del usuario', error);
}
);
}
private setGlobalUserProfiles(profiles: string[]) {
this.userProfilesSubject.next(profiles);
}
private setGlobalUser(user: GlobalUser) {
......@@ -155,29 +202,6 @@ export class AuthService {
return typeof idToken['sub'] !== 'undefined' ? idToken['sub'].toString() : '';
}
}
/**
//Enviar token
sendTokenToBackend() {
const token = this.oAuthService.getAccessToken();
console.log("Token:"+ token)
if (token) {
// Configura las cabeceras de la solicitud con el token
const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
// Realiza la solicitud HTTP al backend
this.httpClient.post('http://localhost:8080/api/v1.0/api/token', {}, { headers })
.subscribe(
(response) => {
// Maneja la respuesta del backend
console.log('Token enviado al backend:', response);
},
(error) => {
// Maneja el error en caso de que la solicitud falle
console.error('Error al enviar el token al backend:', error);
}
);
}
}
*/
}
export class docompar{
UZYTAVDOCOMPAR_CODE?: number;
UZYTAVINSTPROY_ID?: number;
UZYTAVDOCOMPAR_NOMBRE_DOC?: string;
UZYTAVDOCOMPAR_NOMBRE_URL?: string;
UZYTAVDOCOMPAR_FECHA_CREA?: Date;
uzytavdocompar_code?: number;
uzytavinstproy_id?: number;
uzytavdocompar_nombre_doc?: string;
uzytavdocompar_nombre_url?: string;
uzytavdocompar_fecha_crea?: Date;
}
export class EvaluacionProy{
uzytavevalproy_id?:number;
uzytavcabevalp_id?:number;
uzytavaloruzytparametros_id?:number;
uzytavevalproy_puntaje?:number;
uzytavparaeva_id?:number;
uzytavevalproy_observ?:string;
}
export class ResponsableProg{
uzytavresponsable_prog_id?: number;
uzytusuario_id_docente:number;
uzytavtipres_id:number;
stvsubj_code_dpto?:string;
uzytavprograma_v_id:number;
uzytavresponsable_prog_g_orden:number;
uzytavproyec_id?:number;
uzytavresponsable_prog_g_horas_planif:number;
stvmajr_code:string;
uzytavresponsable_prog_g_nro_certificados:number;
uzytavresponsable_prog_g_fecha_creacion:Date;
uzytavresponsable_prog_g_estado:string;
uzytavactaresponsa_code:number;
uzytavresponsable_prog_g_verificar:string;
uzytavresponsable_prog_g_verfecha:Date;
uzytavresponsable_prog_g_responsable:string;
uzytavresponsable_prog_g_calificacion:number;
}
\ No newline at end of file
export class TiPres{
uzytavtipres_id:number;
uzytavtipres_descrip:number;
uzytavtipres_orden:number;
}
\ No newline at end of file
This diff is collapsed.
......@@ -68,9 +68,6 @@ import { EditComisionEvaluacionComponent } from './pages/Seccion-configuraciones
import { AddIntegrantesComisionComponent } from './pages/Seccion-configuraciones/Comision de Evaluacion/Integrantes de la Comision/add-integrantes-comision/add-integrantes-comision.component';
import { EditIntegrantesComisionComponent } from './pages/Seccion-configuraciones/Comision de Evaluacion/Integrantes de la Comision/edit-integrantes-comision/edit-integrantes-comision.component';
import { IntegrantesComisionComponent } from './pages/Seccion-configuraciones/Comision de Evaluacion/Integrantes de la Comision/integrantes-comision/integrantes-comision.component';
import { ConvocatoriasAgregarComponent } from './pages/convocatorias/convocatorias-agregar/convocatorias-agregar.component';
import { ConvocatoriasEditarComponent } from './pages/convocatorias/convocatorias-editar/convocatorias-editar.component';
import { ConvocatoriasListarComponent } from './pages/convocatorias/convocatorias-listar/convocatorias-listar.component';
import { CatalogoPartidasComponent } from './pages/Seccion-configuraciones/Catalogo Partidas Presupuestarias/catalogo/catalogo-partidas/catalogo-partidas.component';
import { EditCatalogoPartidasComponent } from './pages/Seccion-configuraciones/Catalogo Partidas Presupuestarias/catalogo/edit-catalogo-partidas/edit-catalogo-partidas.component';
import { AddCatalogoPartidasComponent } from './pages/Seccion-configuraciones/Catalogo Partidas Presupuestarias/catalogo/add-catalogo-partidas/add-catalogo-partidas.component';
......@@ -92,7 +89,6 @@ import { LineasComponent } from './pages/Lineas/Lineas.component';
import { PartidasPresupuestarias } from './Models/partidas-presupuestarias';
import { lineaOpe } from './Models/lineas-operativas';
import { CalificacionComiComponent } from './pages/calificacion-comi/calificacion-comi.component';
import { MenusComponent } from './pages/Seccion-configuraciones/menus/menus.component';
import { AgregarProgramaComponent } from './pages/programa/agregar-programa/agregar-programa.component';
import { ListarProgramaComponent } from './pages/programa/listar-programa/listar-programa.component';
......@@ -199,14 +195,8 @@ import { ListCompromisoComponent } from './pages/Proyectos/Inicio Ejecución/com
import { instproy } from './Models/instproy';
import { ListDocumentosComponent } from './pages/Proyectos/Inicio Ejecución/compromiso participacion/list-documentos/list-documentos.component';
import { AddDocumentosComponent } from './pages/Proyectos/Inicio Ejecución/compromiso participacion/add-documentos/add-documentos.component';
import { CartaCompromisoComuComponent } from './pages/Proyectos/Inicio Ejecución/carta compromiso comunidad/carta-compromiso-comu/carta-compromiso-comu.component';
import { ListInstiComponent } from './pages/Proyectos/Cierre/numerico de beneficiarios/list-insti/list-insti.component';
import { EditInstiComponent } from './pages/Proyectos/Cierre/numerico de beneficiarios/edit-insti/edit-insti.component';
import { ActaCompromisoCarrerasComponent } from './pages/Proyectos/Acta de Compromiso de Carreras/acta-compromiso-carreras/acta-compromiso-carreras.component';
import { ActaConsejoDepartamentoComponent } from './pages/Proyectos/Acta de Consejo de Departamento/acta-consejo-departamento/acta-consejo-departamento.component';
import { ActaDirectorProyectoComponent } from './pages/Proyectos/Acta Compromiso Director Proyecto/acta-director-proyecto/acta-director-proyecto.component';
import { ListarActaCompromisoCarrerasComponent } from './pages/Proyectos/Acta de Compromiso de Carreras/listar-acta-compromiso-carreras/listar-acta-compromiso-carreras.component';
import { ListarActaConsejoDepartamentoComponent } from './pages/Proyectos/Acta de Consejo de Departamento/listar-acta-consejo-departamento/listar-acta-consejo-departamento.component';
import { PdfComponent } from './pages/Proyectos/pdf/pdf.component';
import { ListObjetivosEjecComponent } from './pages/Proyectos/Cierre/objetivos ejecutados/list-objetivos-ejec/list-objetivos-ejec.component';
import { EditObjetivosEjecComponent } from './pages/Proyectos/Cierre/objetivos ejecutados/edit-objetivos-ejec/edit-objetivos-ejec.component';
......@@ -224,15 +214,32 @@ import { actproy } from './Models/actproy';
import { detactproy } from './Models/detactproy';
import { EditInformeBodyComponent } from './pages/Proyectos/Ejecución/informes de avance/edit-informe-body/edit-informe-body.component';
import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de avance/add-informe/add-informe.component';
import { CabEvalProyService } from './services/cabecera-eval-proye/cab-eval-proy.service';
import { ActaDirectorProyectoComponent } from './pages/Proyectos/Acta Compromiso Director Proyecto/acta-director-proyecto/acta-director-proyecto.component';
import { ActaConsejoDepartamentoComponent } from './pages/Proyectos/Acta de Consejo de Departamento/acta-consejo-departamento/acta-consejo-departamento.component';
import { ActaCompromisoCarrerasComponent } from './pages/Proyectos/Acta de Compromiso de Carreras/acta-compromiso-carreras/acta-compromiso-carreras.component';
import { AddImagenesComponent } from './pages/programa/opciones/diagnostico y problema/anexos e imagenes/add-imagenes/add-imagenes.component';
import { ListImagenesComponent } from './pages/programa/opciones/diagnostico y problema/anexos e imagenes/list-imagenes/list-imagenes.component';
import { DesignarEvaluadorComponent } from './pages/Proyectos/Evaluación/designar-evaluador/designar-evaluador.component';
import { ConvocatoriasAgregarComponent } from './pages/convocatorias/convocatorias-agregar/convocatorias-agregar.component';
import { ConvocatoriasEditarComponent } from './pages/convocatorias/convocatorias-editar/convocatorias-editar.component';
import { ConvocatoriasListarComponent } from './pages/convocatorias/convocatorias-listar/convocatorias-listar.component';
import { AsignacionEstudiantesComponent } from './pages/Proyectos/Inicio Ejecución/Asignacion Estudiantes/asignacion-estudiantes/asignacion-estudiantes.component';
import { ListarDocentesAsignadosComponent } from './pages/Proyectos/Inicio Ejecución/Asignacion Docentes/listar-docentes-asignados/listar-docentes-asignados.component';
import { AsignacionDocentesComponent } from './pages/Proyectos/Inicio Ejecución/Asignacion Docentes/asignacion-docentes/asignacion-docentes.component';
import { AddCalificacionVinculacionComponent } from './pages/Calificacion Comision Vinculacion/add-calificacion-vinculacion/add-calificacion-vinculacion.component';
import { AccesoDenegadoComponent } from './pages/programa/opciones/AccesoDenegado/AccesoDenegado.component';
import { AccesoNoAutorizadoComponent } from './pages/programa/opciones/AccesoNoAutorizado/AccesoNoAutorizado.component';
import { ErroresComponent } from './pages/programa/opciones/errores/errores.component';
import { MatTooltipModule } from '@angular/material/tooltip';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [
AsignacionDocentesComponent,
ActaCompromisoCarrerasComponent,
ActaConsejoDepartamentoComponent,
ActaDirectorProyectoComponent,
ListCompromisoComponent,
ListarActaCompromisoCarrerasComponent,
ListarActaConsejoDepartamentoComponent,
AddCronogramaActiComponent,
AddHitosComponent,
InicialProyectoComponent,
......@@ -315,7 +322,6 @@ import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de av
ConvocatoriasAgregarComponent,
ConvocatoriasEditarComponent,
ConvocatoriasListarComponent,
CalificacionComiComponent,
MenusComponent,
AgregarProgramaComponent,
CoberturaComponent,
......@@ -381,7 +387,6 @@ import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de av
ListCompromisoComponent,
ListDocumentosComponent,
AddDocumentosComponent,
CartaCompromisoComuComponent,
ListInstiComponent,
EditInstiComponent,
PdfComponent,
......@@ -397,9 +402,18 @@ import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de av
ErrorTextoComponent,
ComisionAsigComponent,
EditInformeBodyComponent,
AddInformeComponent
AddInformeComponent,
AddCalificacionVinculacionComponent,
AddImagenesComponent,
ListImagenesComponent,
DesignarEvaluadorComponent,
ListarDocentesAsignadosComponent,
AccesoDenegadoComponent,
AccesoNoAutorizadoComponent,
ErroresComponent
],
imports: [
MatTooltipModule,
MatTreeModule,
CKEditorModule,
FullCalendarModule,
......@@ -429,7 +443,8 @@ import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de av
MatFormFieldModule,
MatCardModule,
MatButtonModule,
MatRadioModule
MatRadioModule,
MatAutocompleteModule
],
providers: [
seguim,
......@@ -454,7 +469,9 @@ import { AddInformeComponent } from './pages/Proyectos/Ejecución/informes de av
planvprograma,
programaeplanv,
actproy,
detactproy
detactproy,
CabEvalProyService,
]
})
export class MainModule {
......
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
}
\ No newline at end of file
<div class="contenedor-dos">
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<!-- Control de fechas inicio -->
<div class="save-button">
<button mat-raised-button class="botones" color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button class="botones"
[disabled]="myForm.invalid" color="primary" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button class="botones" color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="input-container">
<mat-form-field>
<mat-label>Fecha:</mat-label>
<input matInput [matDatepicker]="pickerInicio" placeholder="Seleccione una fecha"
formControlName="fechaInicio" required>
<mat-datepicker-toggle matSuffix [for]="pickerInicio"></mat-datepicker-toggle>
<mat-datepicker #pickerInicio></mat-datepicker>
<mat-error
*ngIf="myForm.get('fechaInicio').invalid && (myForm.get('fechaInicio').dirty || myForm.get('fechaInicio').touched)">
Por favor, ingrese la fecha de Inicio.
</mat-error>
</mat-form-field>
</div>
<div class="input-container">
<mat-form-field>
<mat-label>Descripción:</mat-label>
<input matInput formControlName="descripcion" required>
<mat-error
*ngIf="myForm.get('descripcion').invalid && (myForm.get('descripcion').dirty || myForm.get('descripcion').touched)">
Por favor, ingrese la descripción.
</mat-error>
</mat-form-field>
</div>
<div class="container">
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- Nro Column -->
<ng-container matColumnDef="Nro" class="Column1">
<th class="Column1 negrita" mat-header-cell *matHeaderCellDef mat-sort-header> Nro </th>
<td class="Column1" mat-cell *matCellDef="let i = index"> {{ i+1 }}
</td>
</ng-container>
<ng-container matColumnDef="Parametro" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header>
Parámetro</th>
<td class="Column" mat-cell *matCellDef="let dato">
{{dato.uzytavparaeva_descrip}}
</td>
</ng-container>
<ng-container [formGroup]="dynamicForm" (ngSubmit)="onSubmit()" matColumnDef="Valoracion"
class="Column" >
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header> Valoración</th>
<td class="Column" mat-cell *matCellDef="let dato" let i=index>
<mat-form-field class="form-field">
<mat-label>Seleccione un Item</mat-label>
<mat-select [formControlName]="'valoracion' + dato.uzytavparaeva_id">
<mat-option *ngFor="let opcion of dato.opcionesRespuesta"
[value]="opcion.uzytavaloruzytparametros_id">
{{ opcion.uzytavalorpar_descrip }}
</mat-option>
</mat-select>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="Puntaje" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header> Puntaje </th>
<td class="Column" mat-cell *matCellDef="let dato">
{{ getSelectedPuntaje(dato.uzytavparaeva_id) }}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</div>
</div>
</form>
</div>
\ No newline at end of file
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { AddCalificacionVinculacionComponent } from './add-calificacion-vinculacion.component';
describe('AddCalificacionVinculacionComponent', () => {
let component: AddCalificacionVinculacionComponent;
let fixture: ComponentFixture<AddCalificacionVinculacionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddCalificacionVinculacionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddCalificacionVinculacionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, Validators, FormGroup, FormControl, FormArray, AbstractControl } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { EnvioFormularioComponent } from '../../programa/opciones/envio-formulario/envio-formulario.component';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import { ParametrosEvaluacion } from '../../../Models/parametro-evaluacion';
import { ParametrosEvaService } from '../../../services/parametros-evaluacion/parametros-eva.service';
import { MostrarOcultarService } from '../../../services/mostrar-ocultar.service';
import { Proyectos } from '../../../Models/proyectos';
import { OpcionesRespuesta } from '../../../Models/opciones-respuesta';
import { OpcionesRespuestaService } from '../../../services/opciones-respuesta/opciones-respuesta.service';
import { Observable, forkJoin } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { CabeEvalProy } from '../../../Models/cabevalp';
import { UsuariosService } from '../../../services/usuarios/usuarios.service';
import { Usuario } from '../../../Models/usuario';
import { CabEvalProyService } from '../../../services/cabecera-eval-proye/cab-eval-proy.service';
import { EvaluacionProy } from '../../../Models/eval-proy';
import { EvaluacionProyectoService } from '../../../services/evaluacion-proyecto/evaluacion-proyecto.service';
@Component({
selector: 'app-add-calificacion-vinculacion',
templateUrl: './add-calificacion-vinculacion.component.html',
styleUrls: ['./add-calificacion-vinculacion.component.css']
})
export class AddCalificacionVinculacionComponent implements OnInit {
cambio: boolean = false;
dynamicForm: FormGroup; // Declare a FormGroup
idRecuperado: number;
myForm: FormGroup;
enviarSolicitud = false;
formularioEnviado: boolean
dataSource: MatTableDataSource<ParametrosEvaluacion>;
parametrosEvaluacion: any[] = [];
proyecto: Proyectos;
usuario: Usuario;
cabeceraEvalProy: CabeEvalProy
cabeceraEvalProyEdit: CabeEvalProy
evaluacionProy: EvaluacionProy
opcionesRespuesta!: OpcionesRespuesta[];
selectedParametroId: number;
opcionesArray$: Observable<OpcionesRespuesta[]>;
data: any[] = []; // Datos de la tabla
// Añade esto en tu componente
puntajes: { [key: number]: number } = {}; // Objeto para almacenar los puntajes
items: FormArray;
valoracionControls: FormControl[] = [];
displayedColumns: string[] = [
'Nro',
'Parametro',
'Valoracion',
'Puntaje'
];
@ViewChild(MatTable) table: MatTable<any>;
constructor(
private formBuilder: FormBuilder,
private dialog: MatDialog,
private parametrosEvaService: ParametrosEvaService,
private mostrarOcultarService: MostrarOcultarService,
private opcionesRespuestaService: OpcionesRespuestaService,
private datosUsuarioService: UsuariosService,
private cabEvalProyService: CabEvalProyService,
private evaluacionProyectoService: EvaluacionProyectoService,
) {
this.proyecto = new Proyectos();
this.dataSource = new MatTableDataSource<ParametrosEvaluacion>([]);
this.cabeceraEvalProy = new CabeEvalProy();
this.cabeceraEvalProyEdit = new CabeEvalProy();
this.usuario = new Usuario();
this.evaluacionProy = new EvaluacionProy()
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'), 10);
this.proyecto = this.mostrarOcultarService.editProyecto;
this.obtenerParametrosIniciales(this.proyecto.uzytavconparaeva_id);
this.initializeForm()
this.obtenerDatosUsuario()
this.myForm = this.formBuilder.group({
fechaInicio: [{ value: '', disabled: true }, Validators.required],
descripcion: [{ value: '', disabled: true }, Validators.required],
});
// Obtener los parámetros iniciales y asignar los valores al formulario
}
initializeForm() {
this.dynamicForm = this.formBuilder.group({});
this.dynamicForm.disable(); // Disable all form controls
}
obtenerDatosCabecera() {
this.cabEvalProyService.obtenerParametrosId(this.proyecto.uzytusuario_id).subscribe(
usuario => {
this.cabeceraEvalProyEdit = usuario;
this.myForm.patchValue({
fechaInicio: this.cabeceraEvalProyEdit.uzytavcabevalp_fec_crea,
descripcion: this.cabeceraEvalProyEdit.uzytavcabevalp_observa,
});
},
error => {
console.log('Error al obtener los parámetros:', error);
}
);
}
obtenerParametrosIniciales(id: number) {
if (id != undefined && id != null)
this.parametrosEvaService.obtenerParametrosIniciales(id).subscribe(data => {
if (data !== undefined) {
const parametrosWithOpciones$: Observable<ParametrosEvaluacion>[] = data.map(parametro => {
return this.obtenerOpcionesRespuesta(parametro.uzytavparaeva_id).pipe(
map(opciones => {
this.createDynamicFormControls(opciones);
return {
...parametro,
opcion: opciones,
opcionesRespuesta: opciones // Agrega una propiedad opcionesRespuesta al objeto parametro
};
})
);
});
forkJoin(parametrosWithOpciones$).subscribe(parametros => {
this.parametrosEvaluacion = parametros;
this.dataSource.data = parametros;
});
}
});
else {
console.log("envíe un id valido")
}
}
createDynamicFormControls(opciones: OpcionesRespuesta[]) {
opciones.forEach(opcion => {
this.dynamicForm.addControl('valoracion' + opcion.uzytavparaeva_id,
this.formBuilder.control({ value: opcion.uzytavaloruzytparametros_id, disabled: true },
[Validators.required]));
});
this.dynamicForm.disable();
}
getSelectedPuntaje(uzytavparaeva_id: number): number {
const controlName = 'valoracion' + uzytavparaeva_id;
const selectedValueId = this.dynamicForm.get(controlName)?.value;
// Encuentra las opcionesRespuesta específicas para el parámetro actual
const opcionesRespuesta = this.parametrosEvaluacion.find(parametro =>
parametro.uzytavparaeva_id === uzytavparaeva_id)?.opcionesRespuesta;
if (selectedValueId !== null && selectedValueId !== undefined && opcionesRespuesta) {
const selectedOpcion = opcionesRespuesta.find(opcion =>
opcion.uzytavaloruzytparametros_id === selectedValueId);
if (selectedOpcion) {
return selectedOpcion.uzytavalorpar_puntaje;
} else {
return 0;
}
} else {
return 0;
}
}
obtenerOpcionesRespuesta(id: number) {
return this.opcionesRespuestaService.obtenerParametrosId(id).pipe(
tap(opciones => {
this.opcionesRespuesta = opciones; // Carga los datos en opcionesRespuesta
})
);
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
this.formularioEnviado = true;
});
}
obtenerDatosUsuario() {
this.datosUsuarioService.obtenerDatosUsuario().
subscribe(data => {
this.usuario = data
},
error => {
console.log('Error al obtener los parámetros:', error);
}
);
}
onSubmit() {
if (this.myForm.valid && this.dynamicForm.valid) {
this.cabeceraEvalProy.uzytavproyec_id = this.idRecuperado;
this.cabeceraEvalProy.uzytavcabevalp_fec_crea = this.myForm.value.apellido;
this.cabeceraEvalProy.uzytavcabevalp_observa = this.myForm.value.apellido;
this.cabeceraEvalProy.uzytusuario_id = this.usuario.uzytusuario_id;
console.log("usuario que califica ", this.usuario.uzytusuario_id)
this.cabEvalProyService.guardarParametros(this.cabeceraEvalProy).subscribe(() => {
this.enviarEvaluacion(this.cabEvalProyService.obtenerId())
console.log("cabecera enviada ", this.cabeceraEvalProy)
this.openModal()
this.guardar()
});
}
}
enviarEvaluacion(idCabecera: number) {
if (!this.enviarSolicitud) {
this.enviarSolicitud = true;
// Iterar a través de las opciones de respuesta
this.opcionesRespuesta.forEach(opcion => {
const controlName = 'valoracion' + opcion.uzytavparaeva_id;
console.log("formcontrol enviad", controlName)
const selectedValueId = this.dynamicForm.get(controlName)?.value;
if (selectedValueId !== null && selectedValueId !== undefined) {
// Crear el objeto EvaluacionProy con los valores necesarios
const evaluacionProy: EvaluacionProy = {
uzytavcabevalp_id: idCabecera,
uzytavaloruzytparametros_id: selectedValueId,
uzytavparaeva_id: opcion.uzytavparaeva_id
// Agregar otros campos si es necesario
};
this.evaluacionProyectoService.guardarParametros(evaluacionProy).subscribe(() => {
console.log("enviado evalproy", evaluacionProy);
});
}
});
}
}
cambiar() {
this.cambio = true;
this.myForm.enable();
this.dynamicForm.enable();
}
cancelado() {
this.cambio = false;
this.myForm.disable();
this.dynamicForm.disable();
}
guardar() {
this.cambio = false;
this.myForm.disable();
this.dynamicForm.disable();
}
}
......@@ -24,7 +24,7 @@
<div class="tope">
<div class="card-grid">
<div class="card" *ngFor="let linea of lineas">
<mat-card>
<mat-card (click)="getLinea(linea.uzytavlineaoperativa_DESCRIP)">
<img
mat-card-image
[src]="getImagen(linea.uzytavlineaoperativa_DESCRIP)" />
......
......@@ -51,4 +51,27 @@ export class LineasComponent implements OnInit {
return '';
}
}
getLinea(nombre: string){
switch (nombre) {
case 'Proyecto Social':
return this.router.navigate(['main/ListaProyectos']);
case 'Prácticas Preprofesionales ':
return this.router.navigate(['main/ListaProyectos']);
case 'Divulgación y resultados de aplicación C&C':
return this.router.navigate(['main/ListaProyectos']);
case 'Innovación Social y Abierta':
return this.router.navigate(['main/ListaProyectos']);
case 'Transferencia de Conocimiento y Tecnología':
return this.router.navigate(['main/ListaProyectos']);
case 'Consultoría y Servicios Especializados':
return this.router.navigate(['main/ListaProyectos']);
case 'Emprendimiento':
return this.router.navigate(['main/ListaProyectos']);
case 'Educación Continua':
return this.router.navigate(['main/ListaProyectos']);
default:
return '';
}
}
}
......@@ -30,6 +30,12 @@
font-weight: bold;
}
.separator {
margin: 0 5px;
opacity: 0;
pointer-events: none;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
......@@ -56,23 +62,6 @@
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
......@@ -152,5 +141,6 @@
display: flex;
flex-direction: column;
margin-bottom: 16px;
align-items: center;
}
\ No newline at end of file
<div class="contenedor-dos">
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" [disabled]="!archivoEsPDFValido" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part1_url == null && !cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
<!-- Control de PDF -->
<div class="input-container">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" (change)="onFileChange($event)"
formControlName="archivo">
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part1_url == null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
</div>
<button class="input-container" *ngIf="proyecto.uzytavproyec_com_part1_url != null && !cambio">
<img src="../../../../../../../assets/img/icons/pdf.png" style="width: 50px; height: 50px;"
(click)="verPDF(proyecto.uzytavproyec_com_part1_url,proyecto.uzytavproyec_com_part1_nom)"
aria-placeholder="Ver PDF">Descargar PDF
</button>
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part1_url != null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
</form>
</div>
\ No newline at end of file
</div>
......@@ -13,6 +13,10 @@ import { ProyectosService } from 'src/app/modules/main/services/proyectos/proyec
import { ProyectoComponent } from '../../Proyectos/Proyecto/Proyecto.component';
import { Proyectos } from 'src/app/modules/main/Models/proyectos';
import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Datos espe/datos-espe.service';
import { MostrarOcultarService } from 'src/app/modules/main/services/mostrar-ocultar.service';
import { saveAs } from 'file-saver';
import { ErroresComponent } from '../../../programa/opciones/errores/errores.component';
import { ErrorTextoComponent } from '../../errores/error-texto/error-texto.component';
@Component({
selector: 'app-acta-director-proyecto',
......@@ -20,7 +24,7 @@ import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Da
styleUrls: ['./acta-director-proyecto.component.css']
})
export class ActaDirectorProyectoComponent implements OnInit {
archivoEsPDFValido: boolean = false;
myForm: FormGroup;
selectedFile: File | null = null;
file: File;
......@@ -29,7 +33,8 @@ export class ActaDirectorProyectoComponent implements OnInit {
formularioEnviado: boolean
cambio: boolean;
proyecto: Proyectos
showPdfButton: number = 0; // 0 para ocultar, 1 para mostrar
public idRecuperado
constructor(
private formBuilder: FormBuilder,
private proyectosService: ProyectosService,
......@@ -38,12 +43,16 @@ export class ActaDirectorProyectoComponent implements OnInit {
private datosCompartidos: Actualiza_datosService,
private idCompartido: Compartir_idService,
private datosEspeService: DatosEspeService,
private mostrarOcultarService: MostrarOcultarService,
) {
this.proyecto = new Proyectos();
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'), 10);
this.proyecto = this.mostrarOcultarService.editProyecto;
this.cambio = false;
this.myForm = this.formBuilder.group({
archivo: [{ value: '', disabled: true }, Validators.required],
......@@ -61,14 +70,43 @@ export class ActaDirectorProyectoComponent implements OnInit {
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
this.file = fileList[0];
if (!this.validarArchivo(this.file)) {
this.openModalError('¡Por favor, selecciona un archivo PDF!');
return;
} else {
this.archivoEsPDFValido = true;
}
}
}
validarArchivo(file: File): boolean {
const fileName = file.name;
return fileName.toLocaleLowerCase().endsWith('.pdf');
}
/*
onFileChange(event: any) {
// Obtener el archivo seleccionado
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
const file = fileList[0];
const fileName = file.name;
if (!fileName.toLocaleLowerCase().endsWith('.pdf')) {
this.openModalError('¡Por favor, selecciona un archivo PDF!');
this.archivoEsPDFValido = false; // Establecer a false si no es un PDF
} else {
this.archivoEsPDFValido = true; // Establecer a true si es un PDF
// Continúa con el manejo del archivo si es un PDF
}
}
}
*/
openModal() {
openModal(mensaje: string) {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
width: '400px',
disableClose: true
disableClose: true,
data: { mensaje: mensaje }
});
dialogRef.afterClosed().subscribe(result => {
......@@ -78,25 +116,26 @@ export class ActaDirectorProyectoComponent implements OnInit {
async onSubmit() {
if (this.myForm.valid) {
this.proyecto.uzytavproyec_id = this.idCompartido.getIdGuardado();
this.proyecto.uzytavproyec_id = this.idRecuperado;
const pdfData = await this.enviarPDF();
this.proyecto.uzytavproyec_com_part1_url = pdfData.idPDF;
this.proyecto.uzytavproyec_com_part1_nom = pdfData.filename;
this.proyectosService.modificarParametros(this.proyecto.uzytavproyec_id, this.proyecto).subscribe(
response => {
this.openModal();
console.log('Datos Actualizados', this.proyecto);
this.myForm.disable();
this.cambio = false;
},
error => {
console.log(error)
}
);
if (pdfData.idPDF !== null && pdfData.idPDF !== undefined) {
this.proyecto.uzytavproyec_com_part1_url = pdfData.idPDF;
this.proyecto.uzytavproyec_com_part1_nom = pdfData.filename;
this.proyectosService.modificarParametros(this.proyecto.uzytavproyec_id, this.proyecto).subscribe(
response => {
this.openModal('El PDF ha sido Enviado');
console.log('Datos Actualizados', this.proyecto);
this.myForm.disable();
this.cambio = false;
},
error => {
}
);
}
}
}
async enviarPDF() {
const formData = new FormData();
formData.append('files', this.file);
......@@ -109,11 +148,50 @@ export class ActaDirectorProyectoComponent implements OnInit {
filename: response.fileName
};
} catch (error) {
console.error('Error al guardar el PDF en el servidor:', error);
throw error;
this.openModalError('¡Este PDF ya se ha subido!');
return {
idPDF: null,
filename: ''
};
}
}
verPDF(id: string, nombre: string) {
console.log("uid pasado ", id)
console.log("nombre pasado ", nombre)
this.datosEspeService.verPDF(id, nombre).subscribe(
(response: any) => {
if (response) {
const contentDispositionHeader = response.headers.get('content-disposition');
const filename = this.getFilenameFromResponse(contentDispositionHeader);
const blob = new Blob([response.body], { type: 'application/pdf' });
saveAs(blob, nombre);
} else {
console.error('No se pudieron obtener las cabeceras de la respuesta.');
}
},
error => {
console.error('Error al obtener el PDF:', error);
return {
idPDF: null,
filename: null
};
}
);
}
getFilenameFromResponse(contentDispositionHeader: string | null): string {
if (contentDispositionHeader) {
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDispositionHeader);
if (matches != null && matches[1]) {
return matches[1].replace(/['"]/g, '');
}
}
return 'document.pdf'; // Nombre predeterminado si no se puede obtener el nombre del archivo
}
cambiar() {
this.cambio = true;
this.myForm.get('archivo').enable();
......@@ -122,4 +200,16 @@ export class ActaDirectorProyectoComponent implements OnInit {
this.cambio = false;
this.myForm.disable();
}
openModalError(texto: string) {
const dialogRef = this.dialog.open(ErrorTextoComponent, {
disableClose: true,
data: { mensaje: texto }
});
dialogRef.afterClosed().subscribe(result => {
console.log('La ventana modal se ha cerrado');
this.formularioEnviado = true;
});
}
}
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
}
\ No newline at end of file
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
.separator {
margin: 0 5px;
opacity: 0;
pointer-events: none;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
align-items: center;
}
<div class="contenedor-dos">
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" [disabled]="!archivoEsPDFValido" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part2_url == null && !cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
<!-- Control de PDF -->
<div class="input-container">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" (change)="onFileChange($event)"
formControlName="archivo">
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part2_url == null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
</div>
<button class="input-container" *ngIf="proyecto.uzytavproyec_com_part2_url != null && !cambio">
<img src="../../../../../../../assets/img/icons/pdf.png" style="width: 50px; height: 50px;"
(click)="verPDF(proyecto.uzytavproyec_com_part2_url,proyecto.uzytavproyec_com_part2_nom)"
aria-placeholder="Ver PDF">Descargar PDF
</button>
<div class="input-container" *ngIf="proyecto.uzytavproyec_com_part2_url != null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
</form>
</div>
\ No newline at end of file
</div>
......@@ -13,6 +13,9 @@ import { ProyectosService } from 'src/app/modules/main/services/proyectos/proyec
import { ProyectoComponent } from '../../Proyectos/Proyecto/Proyecto.component';
import { Proyectos } from 'src/app/modules/main/Models/proyectos';
import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Datos espe/datos-espe.service';
import { saveAs } from 'file-saver';
import { MostrarOcultarService } from 'src/app/modules/main/services/mostrar-ocultar.service';
import { ErrorTextoComponent } from '../../errores/error-texto/error-texto.component';
@Component({
selector: 'app-acta-compromiso-carreras',
......@@ -20,7 +23,7 @@ import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Da
styleUrls: ['./acta-compromiso-carreras.component.css']
})
export class ActaCompromisoCarrerasComponent implements OnInit {
archivoEsPDFValido: boolean = false;
myForm: FormGroup;
selectedFile: File | null = null;
file: File;
......@@ -29,7 +32,7 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
formularioEnviado: boolean
cambio: boolean;
proyecto: Proyectos
public idRecuperado
constructor(
private formBuilder: FormBuilder,
private proyectosService: ProyectosService,
......@@ -38,12 +41,16 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
private datosCompartidos: Actualiza_datosService,
private idCompartido: Compartir_idService,
private datosEspeService: DatosEspeService,
private mostrarOcultarService: MostrarOcultarService,
) {
this.proyecto = new Proyectos();
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'),10);
this.proyecto = this.mostrarOcultarService.editProyecto;
this.cambio = false;
this.myForm = this.formBuilder.group({
archivo: [{ value: '', disabled: true }, Validators.required],
......@@ -61,9 +68,19 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
this.file = fileList[0];
if (!this.validarArchivo(this.file)) {
this.openModalError('¡Por favor, selecciona un archivo PDF!');
return;
} else {
this.archivoEsPDFValido = true;
}
}
}
validarArchivo(file: File): boolean {
const fileName = file.name;
return fileName.toLocaleLowerCase().endsWith('.pdf');
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
......@@ -79,7 +96,7 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
async onSubmit() {
if (this.myForm.valid) {
this.proyecto.uzytavproyec_id = this.idCompartido.getIdGuardado();
this.proyecto.uzytavproyec_id = this.idRecuperado;
const pdfData = await this.enviarPDF();
this.proyecto.uzytavproyec_com_part2_url = pdfData.idPDF;
this.proyecto.uzytavproyec_com_part2_nom = pdfData.filename;
......@@ -91,7 +108,6 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
this.cambio = false;
},
error => {
console.log(error)
}
);
}
......@@ -109,11 +125,43 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
filename: response.fileName
};
} catch (error) {
console.error('Error al guardar el PDF en el servidor:', error);
throw error;
this.openModalError('¡Este PDF ya se ha subido!');
return {
idPDF: null,
filename: ''
};
}
}
verPDF(id: string, nombre: string) {
console.log("uid pasado ", id)
console.log("nombre pasado ", nombre)
this.datosEspeService.verPDF(id, nombre).subscribe(
(response: any) => {
if (response) {
const contentDispositionHeader = response.headers.get('content-disposition');
const filename = this.getFilenameFromResponse(contentDispositionHeader);
const blob = new Blob([response.body], { type: 'application/pdf' });
saveAs(blob, nombre);
} else {
console.error('No se pudieron obtener las cabeceras de la respuesta.');
}
},
error => {
console.error('Error al obtener el PDF:', error);
}
);
}
getFilenameFromResponse(contentDispositionHeader: string | null): string {
if (contentDispositionHeader) {
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDispositionHeader);
if (matches != null && matches[1]) {
return matches[1].replace(/['"]/g, '');
}
}
return 'document.pdf'; // Nombre predeterminado si no se puede obtener el nombre del archivo
}
cambiar() {
this.cambio = true;
this.myForm.get('archivo').enable();
......@@ -123,4 +171,16 @@ export class ActaCompromisoCarrerasComponent implements OnInit {
this.myForm.disable();
}
openModalError(texto: string) {
const dialogRef = this.dialog.open(ErrorTextoComponent, {
disableClose: true,
data: { mensaje: texto }
});
dialogRef.afterClosed().subscribe(result => {
console.log('La ventana modal se ha cerrado');
this.formularioEnviado = true;
});
}
}
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
}
\ No newline at end of file
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
.separator {
margin: 0 5px;
opacity: 0;
pointer-events: none;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
align-items: center;
}
<div class="contenedor-dos">
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" [disabled]="!archivoEsPDFValido" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="input-container" *ngIf="proyecto.uzytavproyec_aprob_con_dep_url == null && !cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
<div class="input-container" *ngIf="proyecto.uzytavproyec_aprob_con_dep_url == null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
<button class="input-container" *ngIf="proyecto.uzytavproyec_aprob_con_dep_url != null && !cambio">
<img src="../../../../../../../assets/img/icons/pdf.png" style="width: 50px; height: 50px;"
(click)="verPDF(proyecto.uzytavproyec_aprob_con_dep_url,proyecto.uzytavproyec_aprob_con_dep_nom)"
aria-placeholder="Ver PDF">Descargar PDF
</button>
<!-- Control de PDF -->
<div class="input-container">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" (change)="onFileChange($event)"
formControlName="archivo">
</div>
<div class="input-container" *ngIf="proyecto.uzytavproyec_aprob_con_dep_url != null && cambio">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" accept=".pdf" (change)="onFileChange($event)" formControlName="archivo">
</div>
</form>
</div>
\ No newline at end of file
</div>
......@@ -13,6 +13,9 @@ import { ProyectosService } from 'src/app/modules/main/services/proyectos/proyec
import { ProyectoComponent } from '../../Proyectos/Proyecto/Proyecto.component';
import { Proyectos } from 'src/app/modules/main/Models/proyectos';
import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Datos espe/datos-espe.service';
import { MostrarOcultarService } from 'src/app/modules/main/services/mostrar-ocultar.service';
import { saveAs } from 'file-saver';
import { ErrorTextoComponent } from '../../errores/error-texto/error-texto.component';
@Component({
selector: 'app-acta-consejo-departamento',
......@@ -20,7 +23,7 @@ import { DatosEspeService } from 'src/app/modules/main/services/APIs Externas/Da
styleUrls: ['./acta-consejo-departamento.component.css']
})
export class ActaConsejoDepartamentoComponent implements OnInit {
archivoEsPDFValido: boolean = false;
myForm: FormGroup;
selectedFile: File | null = null;
file: File;
......@@ -29,6 +32,8 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
formularioEnviado: boolean
cambio: boolean;
proyecto: Proyectos
public idRecuperado;
showPdfButton: number = 0; // 0 para ocultar, 1 para mostrar
constructor(
private formBuilder: FormBuilder,
......@@ -38,15 +43,19 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
private datosCompartidos: Actualiza_datosService,
private idCompartido: Compartir_idService,
private datosEspeService: DatosEspeService,
private mostrarOcultarService: MostrarOcultarService,
) {
this.proyecto = new Proyectos();
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'),10);
this.proyecto = this.mostrarOcultarService.editProyecto;
this.cambio = false;
this.myForm = this.formBuilder.group({
archivo: [{ value: '', disabled: true }, Validators.required],
archivo: [{ value: "", disabled: true }, Validators.required],
});
}
......@@ -61,9 +70,20 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
const fileList: FileList = event.target.files;
if (fileList.length > 0) {
this.file = fileList[0];
if (!this.validarArchivo(this.file)) {
this.openModalError('¡Por favor, selecciona un archivo PDF!');
return;
} else {
this.archivoEsPDFValido = true;
}
}
}
validarArchivo(file: File): boolean {
const fileName = file.name;
return fileName.toLocaleLowerCase().endsWith('.pdf');
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
......@@ -78,8 +98,7 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
async onSubmit() {
if (this.myForm.valid) {
this.proyecto.uzytavproyec_id = this.idCompartido.getIdGuardado();
this.proyecto.uzytavproyec_id = this.idRecuperado;
const pdfData = await this.enviarPDF();
this.proyecto.uzytavproyec_aprob_con_dep_url = pdfData.idPDF;
this.proyecto.uzytavproyec_aprob_con_dep_nom = pdfData.filename;
......@@ -91,7 +110,6 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
this.cambio = false;
},
error => {
console.log(error)
}
);
}
......@@ -109,11 +127,47 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
filename: response.fileName
};
} catch (error) {
console.error('Error al guardar el PDF en el servidor:', error);
throw error;
this.openModalError('¡Este PDF ya se ha subido!');
return {
idPDF: null,
filename: ''
};
}
}
verPDF(id: string, nombre: string) {
console.log("uid pasado ", id)
console.log("nombre pasado ", nombre)
this.datosEspeService.verPDF(id, nombre).subscribe(
(response: any) => {
if (response) {
const contentDispositionHeader = response.headers.get('content-disposition');
const filename = this.getFilenameFromResponse(contentDispositionHeader);
const blob = new Blob([response.body], { type: 'application/pdf' });
saveAs(blob, nombre);
} else {
console.error('No se pudieron obtener las cabeceras de la respuesta.');
}
},
error => {
console.error('Error al obtener el PDF:', error);
}
);
}
getFilenameFromResponse(contentDispositionHeader: string | null): string {
if (contentDispositionHeader) {
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDispositionHeader);
if (matches != null && matches[1]) {
return matches[1].replace(/['"]/g, '');
}
}
return 'document.pdf'; // Nombre predeterminado si no se puede obtener el nombre del archivo
}
cambiar() {
this.cambio = true;
this.myForm.get('archivo').enable();
......@@ -123,4 +177,17 @@ export class ActaConsejoDepartamentoComponent implements OnInit {
this.myForm.disable();
}
openModalError(texto: string) {
const dialogRef = this.dialog.open(ErrorTextoComponent, {
disableClose: true,
data: { mensaje: texto }
});
dialogRef.afterClosed().subscribe(result => {
console.log('La ventana modal se ha cerrado');
this.formularioEnviado = true;
});
}
}
......@@ -35,6 +35,7 @@ export class ObjetivosProvincialesComponent implements OnInit {
private ubicacionesS: UbicacionesService,
private mostrarOcultarService: MostrarOcultarService
) {
this.dataSource = new MatTableDataSource<ZonaDetalle>([]);
}
......@@ -92,13 +93,13 @@ export class ObjetivosProvincialesComponent implements OnInit {
obtenerParroquias() {
obtenerCantones() {
this.ubicacionesS.obtenerCant().subscribe(cant => {
this.cantones = cant;
});
}
obtenerCantones() {
obtenerParroquias() {
this.ubicacionesS.obtenerParro().subscribe(parro => {
this.parroquias = parro;
});
......@@ -129,12 +130,15 @@ export class ObjetivosProvincialesComponent implements OnInit {
}
getParroquiaNombre(parroquiaId: string): string {
const parroquia = this.parroquias.find(p => p.uzytparroquia_id === parroquiaId);
if (parroquia) {
const nombre = parroquia.uzytparroquia_nombre.toLowerCase();
return nombre.charAt(0).toUpperCase() + nombre.slice(1);
if(parroquiaId != null){
const parroquia = this.parroquias.find(p => p.uzytparroquia_id === parroquiaId);
if (parroquia) {
const nombre = parroquia.uzytparroquia_nombre.toLowerCase();
return nombre.charAt(0).toUpperCase() + nombre.slice(1);
}
return 'n/a';
}
return '';
return 'N/A';
}
eliminarParametro(id: number) {
......
......@@ -308,3 +308,9 @@ button:hover {
flex-direction: column;
margin-bottom: 16px;
}
.estilo-edi {
background-color: white;
color: #5bb02c;
}
......@@ -39,7 +39,8 @@
myForm.get('objetivos').touched)">
Por favor, ingrese un objetivo.
</mat-error>
<mat-icon matSuffix matTooltip="Ingrese el Objetivo el cual corresponde a cada opción" class="estilo-edi">help_outline</mat-icon>
</mat-form-field>
</div>
</div>
</form>
\ No newline at end of file
</form>
......@@ -65,7 +65,8 @@ export class ObjetivosZonaComponent implements OnInit {
this.mostrarObjetivosZona = true
console.log("en el componente agregar se inicializa como : ", this.mostrarObjetivosZona)
this.obtenerProvincia(this.zonaDM.uzytprovincia_id);
this.obtenerCanton(this.zonaDM.uzytcanton_id)
this.obtenerCanton(this.zonaDM.uzytcanton_id);
this.obtenerParroquia(this.zonaDM.uzytparroquia_id);
this.initializeForm();
}
......
<div class="container">
<div class="area-busqueda">
<mat-radio-group [(ngModel)]="selectedOption" (ngModelChange)="resetForm()">
<mat-radio-button value="Nacional">Nacional</mat-radio-button>
<!--<mat-radio-button value="Nacional">Nacional</mat-radio-button>-->
<mat-radio-button value="Provincial">Provincial</mat-radio-button>
<mat-radio-button value="Cantonal">Cantonal</mat-radio-button>
<mat-radio-button value="Parroquial">Parroquial</mat-radio-button>
......@@ -10,11 +10,11 @@
<div class="contenedor-dos" *ngIf="mostrarFormulario">
<!--formulario 1-->
<form class="formulario" [formGroup]="myForm" *ngIf="selectedOption !== 'Nacional'" (ngSubmit)="onSubmit()">
<form class="formulario" [formGroup]="myFormProvincia" *ngIf="selectedOption !== 'Nacional'" (ngSubmit)="onSubmit()">
<!--Boton para guardar-->
<div class="save-button" *ngIf="selectedOption === 'Provincial'">
<button mat-raised-button color="primary" [disabled]="myForm.invalid">Guardar</button>
<button mat-raised-button color="primary" [disabled]="myFormProvincia.invalid">Guardar</button>
</div>
<mat-form-field *ngIf="selectedOption === 'Provincial'" class="form-field">
......@@ -29,9 +29,9 @@
</form>
<!--Fomulario 2-->
<form class="formulario" [formGroup]="myForm" *ngIf="selectedOption !== 'Nacional'" (ngSubmit)="onSubmit2()">
<form class="formulario" [formGroup]="myFormCanton" *ngIf="selectedOption !== 'Nacional'" (ngSubmit)="onSubmit2()">
<div class="save-button" *ngIf="selectedOption === 'Cantonal'">
<button mat-raised-button color="primary" [disabled]="myForm.invalid">Guardar</button>
<button mat-raised-button color="primary" [disabled]="myFormCanton.invalid">Guardar</button>
</div>
<mat-form-field
*ngIf="selectedOption === 'Cantonal'"
......@@ -59,10 +59,10 @@
</mat-form-field>
</form>
<!--formulario 3-->
<form *ngIf="selectedOption !== 'Nacional'" class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit3()">
<form *ngIf="selectedOption !== 'Nacional'" class="formulario" [formGroup]="myFormParro" (ngSubmit)="onSubmit3()">
<div class="save-button" *ngIf="selectedOption === 'Parroquial'">
<button mat-raised-button color="primary" [disabled]="myForm.invalid">Guardar</button>
<button mat-raised-button color="primary" [disabled]="myFormParro.invalid">Guardar</button>
</div>
<mat-form-field *ngIf="selectedOption === 'Parroquial'" class="form-field">
<mat-label>Provincias</mat-label>
......
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Canton } from 'src/app/modules/main/Models/Ubicaciones/canton';
import { Parroquia } from 'src/app/modules/main/Models/Ubicaciones/parroquia';
......@@ -22,7 +22,9 @@ import { Actualiza_datosService } from 'src/app/modules/main/services/actualiza_
export class CoberturaProyectoComponent implements OnInit {
selectedOption: string;
myForm: FormGroup;
myFormProvincia: FormGroup;
myFormCanton: FormGroup;
myFormParro: FormGroup;
provincia!: Provincia[];
selectedProvincia: string;
......@@ -56,10 +58,19 @@ export class CoberturaProyectoComponent implements OnInit {
private datosCompartidos: Actualiza_datosService
) {
this.formularioEnviado = false;
this.myForm = this.formBuilder.group({
provincia: [''],
cantones: [''],
parroquias: ['']
this.myFormProvincia = this.formBuilder.group({
provincia: ['', Validators.required]
});
this.myFormCanton = this.formBuilder.group({
provincia: ['', Validators.required],
cantones: ['',Validators.required]
});
this.myFormParro = this.formBuilder.group({
provincia: ['', Validators.required],
cantones: ['',Validators.required],
parroquias: ['',Validators.required]
});
}
......@@ -89,10 +100,10 @@ export class CoberturaProyectoComponent implements OnInit {
enviarSolicitud = false;
onSubmit() {
if (this.myForm.valid && !this.enviarSolicitud) {
if (this.myFormProvincia.valid && !this.enviarSolicitud) {
this.zonaM.uzytavproyec_id = this.idRecuparado;
console.log("back ",this.zonaM.uzytavproyec_id)
const provinciasSeleccionadas = this.myForm.value.provincia;
const provinciasSeleccionadas = this.myFormProvincia.value.provincia;
// Ejecutar todas las operaciones de guardado en paralelo
forkJoin(
......@@ -109,7 +120,7 @@ export class CoberturaProyectoComponent implements OnInit {
).subscribe(responses => {
console.log('Datos Enviados');
this.zonaS.parametrosActualizados.next();
this.openModal();
this.openModal('Se han agregado la(s) Provincia(s)');
this.formularioGuardado.emit();
this.datosCompartidos.actualizarDatos(this.zonaM);
});
......@@ -117,10 +128,10 @@ export class CoberturaProyectoComponent implements OnInit {
}
onSubmit2() {
if (this.myForm.valid && !this.enviarSolicitud) {
if (this.myFormCanton.valid && !this.enviarSolicitud) {
this.zonaM.uzytavproyec_id = this.idRecuparado;
console.log("back ",this.zonaM.uzytavproyec_id)
const cantonesSeleccionados = this.myForm.value.cantones;
const cantonesSeleccionados = this.myFormCanton.value.cantones;
forkJoin(
cantonesSeleccionados.map(canton => {
const zonaMCopia = {...this.zonaM};
......@@ -131,7 +142,7 @@ export class CoberturaProyectoComponent implements OnInit {
).subscribe(responses => {
console.log('Datos Enviados');
this.zonaS.parametrosActualizados.next();
this.openModal();
this.openModal('Se han agregado el/los Canton(es)');
this.formularioGuardado.emit();
this.datosCompartidos.actualizarDatos(this.zonaM);
});
......@@ -139,12 +150,12 @@ export class CoberturaProyectoComponent implements OnInit {
}
onSubmit3() {
if (this.myForm.valid) {
if (this.myFormParro.valid) {
this.zonaM.uzytavproyec_id = this.idRecuparado;
console.log("back ",this.zonaM.uzytavproyec_id)
const parroquiasSeleccionadas = this.myForm.value.parroquias;
const provinciaSeleccionada = this.myForm.value.provincia;
const parroquiasSeleccionadas = this.myFormParro.value.parroquias;
const provinciaSeleccionada = this.myFormParro.value.provincia;
console.log('pruea: ',parroquiasSeleccionadas);
forkJoin(
parroquiasSeleccionadas.map(parroquia => {
......@@ -157,8 +168,8 @@ export class CoberturaProyectoComponent implements OnInit {
).subscribe(responses => {
console.log('Datos Enviados');
this.zonaS.parametrosActualizados.next();
this.openModal();
this.myForm.reset();
this.openModal('Se han agregado la(s) Parroquia(s)');
this.myFormParro.reset();
this.formularioGuardado.emit();
this.datosCompartidos.actualizarDatos(this.zonaM);
});
......@@ -167,16 +178,19 @@ export class CoberturaProyectoComponent implements OnInit {
resetForm() {
this.myForm.reset();
this.myFormParro.reset();
this.myFormCanton.reset();
this.myFormProvincia.reset();
this.selectedProvincia = null;
this.selectedCanton = null;
this.selectedParroquiaId = null;
}
//Abrir la ventana modal para actuaizar y mostrar.
openModal() {
openModal(mensaje: string) {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
disableClose: true,
data: {mensaje: mensaje}
});
dialogRef.afterClosed().subscribe(result => {
......
......@@ -3,7 +3,7 @@
.form-row {
display: flex;
}
.form-column {
flex: 1;
margin: 0 10px;
......@@ -27,16 +27,20 @@
.example-radio-button {
margin: 5px;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.form-column mat-form-field {
display: block;
margin-bottom: 16px;
width: 100%;
}
\ No newline at end of file
.estilo-edi {
background-color: white;
color: #5bb02c;
}
......@@ -16,10 +16,11 @@
{{ programa.uzytavprograma_vnombre }}
</mat-option>
</mat-select>
<mat-error *ngIf="myForm.get('programa').invalid && (myForm.get('programa').dirty
<mat-error *ngIf="myForm.get('programa').invalid && (myForm.get('programa').dirty
|| myForm.get('programa').touched)">
Por favor, ingrese un programa.
</mat-error>
<mat-icon matSuffix matTooltip="Seleccione el programa al cual se va enlazar el proyecto" class="estilo-edi">help_outline</mat-icon>
</mat-form-field>
<div class="form-row">
<div class="form-column">
......@@ -30,9 +31,10 @@
<input matInput formControlName="codigo">
</mat-form-field>
<mat-form-field>
<mat-label>Nombre</mat-label>
<input matInput placeholder="Nombre del Proyecto" formControlName="nombreP">
<mat-icon matSuffix matTooltip="Nombre del Proyecto Postulante" class="estilo-edi">help_outline</mat-icon>
</mat-form-field>
<mat-form-field>
......@@ -44,18 +46,18 @@
<mat-label>Departamento</mat-label>
<input matInput formControlName="departamento" [value]="(usuario.departamento$ | async)">
</mat-form-field>
<mat-form-field>
<mat-label>Seleccionar Carrera</mat-label>
<mat-select [(value)]="selectedCarreraId" formControlName="carrera">
<mat-select [(value)]="selectedCarreraId" formControlName="carrera">
<mat-option *ngFor="let carrera of carrera" [value]="carrera.codigo_CARRERA">
{{ carrera.nombre_CARRERA }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="form-field">
<mat-label>Población Beneficiada</mat-label>
<mat-select formControlName="poblacion" multiple>
......@@ -125,4 +127,4 @@
<ng-container *ngIf="guardarFormulario">
<app-edit-datos-generales-proyecto ></app-edit-datos-generales-proyecto>
</ng-container>
\ No newline at end of file
</ng-container>
......@@ -186,7 +186,7 @@ export class AddDatosGeneralesComponent implements OnInit {
this.proyectosService.modificarParametros(this.idGuardado, this.proyectos).subscribe(response => {
console.log("codigo proyecto actualizado", this.proyectos.uzytavproyec_codigo)
});
this.router.navigate(['main/Proyecto']);
this.router.navigate(['main/editar-proyecto']);
});
} catch (error) {
......
......@@ -19,7 +19,7 @@
</mat-option>
</mat-select>
<mat-error *ngIf="myForm.get('programa').invalid && (myForm.get('programa').dirty
<mat-error *ngIf="myForm.get('programa').invalid && (myForm.get('programa').dirty
|| myForm.get('programa').touched)">
Por favor, ingrese un programa.
</mat-error>
......@@ -38,6 +38,7 @@
<mat-form-field>
<mat-label>Nombre</mat-label>
<input matInput placeholder="Nombre del Proyecto" formControlName="nombreP">
<mat-icon matSuffix matTooltip="Nombre del Proyecto Postulante" class="estilo-edi">help_outline</mat-icon>
</mat-form-field>
......@@ -64,7 +65,7 @@
Por favor, ingrese una carrera.
</mat-error>
</mat-form-field>
<mat-form-field class="form-field">
......@@ -74,7 +75,7 @@
{{ poblacion.uzytavpobla_tipo }}
</mat-option>
</mat-select>
<mat-error *ngIf="myForm.get('poblacion').invalid && (myForm.get('poblacion').dirty
<mat-error *ngIf="myForm.get('poblacion').invalid && (myForm.get('poblacion').dirty
|| myForm.get('poblacion').touched)">
Por favor, ingrese una población.
</mat-error>
......@@ -98,7 +99,7 @@
<input matInput [matDatepicker]="pickerInicio" formControlName="fechaIni">
<mat-datepicker-toggle matSuffix [for]="pickerInicio"></mat-datepicker-toggle>
<mat-datepicker #pickerInicio></mat-datepicker>
<mat-error *ngIf="myForm.get('fechaIni').invalid && (myForm.get('fechaIni').dirty
<mat-error *ngIf="myForm.get('fechaIni').invalid && (myForm.get('fechaIni').dirty
|| myForm.get('fechaIni').touched)">
Por favor, ingrese una fecha.
</mat-error>
......@@ -141,7 +142,7 @@
<input matInput [matDatepicker]="pickerFin" formControlName="fechaFin">
<mat-datepicker-toggle matSuffix [for]="pickerFin"></mat-datepicker-toggle>
<mat-datepicker #pickerFin></mat-datepicker>
<mat-error *ngIf="myForm.get('fechaFin').invalid && (myForm.get('fechaFin').dirty
<mat-error *ngIf="myForm.get('fechaFin').invalid && (myForm.get('fechaFin').dirty
|| myForm.get('fechaFin').touched)">
Por favor, ingrese una fecha.
</mat-error>
......@@ -153,4 +154,4 @@
</mat-card-content>
</mat-card>
</form>
</div>
\ No newline at end of file
</div>
......@@ -19,3 +19,9 @@
.editor-separator {
margin-top: 15px;
}
.error-message {
color: red;
font-size: 14px;
margin-top: 5px;
}
......@@ -23,3 +23,13 @@
.custom-ckeditor {
height: 400px;
}
.error-message {
color: red;
font-size: 14px;
margin-top: 5px;
}
.estilo-edi {
background-color: white;
color: #5bb02c;
}
<div class="container">
<form class="example-form" [formGroup]="myForm" (ngSubmit)="onSubmit()" >
<form class="example-form" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<mat-card>
<mat-card-header>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio"
(click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="cambio"
>Guardar</button>
[disabled]="myForm.invalid">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio"
(click)="cancelado()">Cancelar</button>
......@@ -16,13 +16,30 @@
<div>
<label class="label-negrita"> Bienes:</label>
<ckeditor formControlName="bienes" class="custom-ckeditor" [disabled]="!isEditorEnabled" [style.height]="editorHeight" [editor]="Editor"></ckeditor>
<ckeditor formControlName="bienes" class="custom-ckeditor"
[disabled]="!isEditorEnabled" [style.height]="editorHeight"
[editor]="Editor"></ckeditor>
<div *ngIf="myForm.get('bienes').hasError('maxlength')"
class="error-message">
El contenido no puede exceder los 3000 caracteres.
</div>
<div *ngIf="myForm.get('bienes').hasError('required') && (myForm.get('bienes').touched || myForm.dirty)" class="error-message">
Este campo es requerido.
</div>
</div>
<div class="editor-separator"></div>
<div>
<label class="label-negrita"> Servicos:</label>
<ckeditor formControlName="servicios" class="custom-ckeditor" [disabled]="!isEditorEnabled" [style.height]="editorHeight" [editor]="Editor"></ckeditor>
<ckeditor formControlName="servicios" class="custom-ckeditor"
[disabled]="!isEditorEnabled" [style.height]="editorHeight"
[editor]="Editor"></ckeditor>
<div *ngIf="myForm.get('servicios').hasError('maxlength')"
class="error-message">
El contenido no puede exceder los 3000 caracteres.
</div>
<div *ngIf="myForm.get('servicios').hasError('required') && (myForm.get('servicios').touched || myForm.dirty)" class="error-message">
Este campo es requerido.
</div>
</div>
</mat-card-content>
......
......@@ -28,7 +28,7 @@ export class EditEntregablesComponent implements OnInit {
private compartiId: Compartir_idService,
private mostrarOcultarService: MostrarOcultarService,
private dialog: MatDialog
) {}
) { }
cambiar() {
this.cambio = true;
......@@ -38,16 +38,25 @@ export class EditEntregablesComponent implements OnInit {
cancelado() {
this.cambio = false;
this.isEditorEnabled = false;
this.myForm.get('bienes').setValue('');
this.myForm.get('servicios').setValue('');
this.myForm.get('bienes').markAsPristine();
this.myForm.get('bienes').markAsUntouched();
this.myForm.get('servicios').markAsPristine()
this.myForm.get('servicios').markAsUntouched();
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'),10);
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'), 10);
this.proyectos = new Proyectos();
this.obtenerRegistros();
this.myForm = this.formBuilder.group({
bienes: [this.proyectos.uzytavproyec_bienes],
servicios: [this.proyectos.uzytavproyec_servicios]
bienes: [this.proyectos.uzytavproyec_bienes, [Validators.required, Validators.maxLength(3000)]],
servicios: [this.proyectos.uzytavproyec_servicios, [Validators.required, Validators.maxLength(3000)]]
});
}
......@@ -73,7 +82,7 @@ export class EditEntregablesComponent implements OnInit {
this.proyectosService.modificarParametros(this.idRecuperado, this.proyectos).subscribe(response => {
this.cambio = false;
this.isEditorEnabled = false;
this.openModal();
this.openModal('Se han enviado los Entregables del Proyecto');
});
} catch (error) {
......@@ -82,9 +91,10 @@ export class EditEntregablesComponent implements OnInit {
}
}
openModal() {
openModal(mensaje: string) {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
disableClose: true,
data: {mensaje: mensaje}
});
dialogRef.afterClosed().subscribe(result => {
......
......@@ -24,7 +24,7 @@
<!-- Control de PDF -->
<div class="input-container">
<label>Subir Archivo</label>
<input type="file" id="uzytavconvoca_digital" (change)="onFileChange($event)"
<input type="file" id="uzytavconvoca_digital" accept="image/*" (change)="onFileChange($event)"
formControlName="archivo">
</div>
......
......@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators, FormGroup } from '@angular/forms';
import { AnexosImagenes } from 'src/app/modules/main/Models/anexos-imagenes';
import { AnexosImagenesService } from 'src/app/modules/main/services/anexos-imagenes/anexos-imagenes.service';
import { ConvocatoriaService } from 'src/app/modules/main/services/convocatoria/convocatoria.service';
import { EnvioFormularioComponent } from '../../../../programa/opciones/envio-formulario/envio-formulario.component';
import { MatDialog } from '@angular/material/dialog';
import { Actualiza_datosService } from 'src/app/modules/main/services/actualiza_datos/actualiza_datos.service';
......
......@@ -3,7 +3,7 @@
.form-row {
display: flex;
}
.form-column {
flex: 1;
margin: 0 10px;
......@@ -41,16 +41,62 @@
.example-radio-button {
margin: 5px;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.form-column mat-form-field {
display: block;
margin-bottom: 16px;
width: 100%;
}
\ No newline at end of file
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
max-width: 400px;
width: 100%;
text-align: center;
position: relative;
}
.success-icon {
font-size: 80px;
color: #006400;
margin-right: 1em;
}
.modal-content p {
margin-bottom: 20px;
}
.modal-content button {
background-color: #2196f3;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
}
.modal-content button:hover {
background-color: #0c7cd5;
}
<div class="container">
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<mat-card>
<mat-card-header>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="!cambio" (click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="!cambio"
(click)="cambiar()">Editar</button>
<button mat-raised-button color="primary" *ngIf="cambio">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
<button mat-raised-button color="warn" *ngIf="cambio"
(click)="cancelado()">Cancelar</button>
</div>
</mat-card-header>
......@@ -16,9 +20,12 @@
<h3>Tipo Directos</h3>
<mat-form-field>
<mat-label>Hombres</mat-label>
<input matInput type="number" placeholder="Hombres" formControlName="HombresD" required
(change)="calcularTotal()" min="0" (change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('HombresD').invalid && (myForm.get('HombresD').dirty
<input matInput type="number" placeholder="Hombres"
formControlName="HombresD" required
(change)="calcularTotal()" min="0" (change)="calcularTotal()"
min="0" pattern="[0-9]+">
<mat-error
*ngIf="myForm.get('HombresD').invalid && (myForm.get('HombresD').dirty
|| myForm.get('HombresD').touched)">
Por favor, ingrese la cantidad de hombres directos.
</mat-error>
......@@ -26,20 +33,24 @@
<mat-form-field>
<mat-label>Mujeres</mat-label>
<input matInput type="number" placeholder="Mujeres" formControlName="MujeresD" required
(change)="calcularTotal()" min="0" (change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('MujeresD').invalid && (myForm.get('MujeresD').dirty
<input matInput type="number" placeholder="Mujeres"
formControlName="MujeresD" required
(change)="calcularTotal()" min="0" (change)="calcularTotal()"
min="0" pattern="[0-9]+">
<mat-error
*ngIf="myForm.get('MujeresD').invalid && (myForm.get('MujeresD').dirty
|| myForm.get('MujeresD').touched)">
Por favor, ingrese la cantidad de Mujeres directas.
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Niños</mat-label>
<input matInput type="number" formControlName="Niños" formControlName="ninosD" required
<input matInput type="number" formControlName="Niños"
formControlName="ninosD" required
(change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('ninosD').invalid && (myForm.get('ninosD').dirty
<mat-error
*ngIf="myForm.get('ninosD').invalid && (myForm.get('ninosD').dirty
|| myForm.get('ninosD').touched)">
Por favor, ingrese la cantidad de Niños directos.
</mat-error>
......@@ -47,32 +58,38 @@
<mat-form-field>
<mat-label>Personas con Capacidades Especiales</mat-label>
<input matInput type="number" formControlName="Personas con Capacidades Especiales"
formControlName="PersonasD" required (change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('PersonasD').invalid && (myForm.get('PersonasD').dirty
<input matInput type="number"
formControlName="Personas con Capacidades Especiales"
formControlName="PersonasD" required (change)="calcularTotal()"
min="0" pattern="[0-9]+">
<mat-error
*ngIf="myForm.get('PersonasD').invalid && (myForm.get('PersonasD').dirty
|| myForm.get('PersonasD').touched)">
Por favor, ingrese la cantidad de Personas con Capacidades Especiales directas.
Por favor, ingrese la cantidad de Personas con Capacidades
Especiales directas.
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Total Directos</mat-label>
<input matInput type="number" class="deshabilitado" formControlName="Total Directos"
formControlName="TotalD" required
(change)="calcularTotal()" min="0" pattern="[0-9]+" [value]="totalDirectos">
<input matInput type="number" class="deshabilitado"
formControlName="Total Directos"
formControlName="TotalD" required
(change)="calcularTotal()" min="0" pattern="[0-9]+"
[value]="totalDirectos">
</mat-form-field>
</div>
<div>
<h3>Tipo Indirectos</h3>
<mat-form-field>
<mat-label>Hombres</mat-label>
<input matInput type="number" placeholder="Hombres" formControlName="HombresI" required
<input matInput type="number" placeholder="Hombres"
formControlName="HombresI" required
(change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('HombresI').invalid && (myForm.get('HombresI').dirty
<mat-error
*ngIf="myForm.get('HombresI').invalid && (myForm.get('HombresI').dirty
|| myForm.get('HombresI').touched)">
Por favor, ingrese la cantidad de hombres indirectos.
</mat-error>
......@@ -80,20 +97,23 @@
<mat-form-field>
<mat-label>Mujeres</mat-label>
<input matInput type="number" placeholder="Mujeres" formControlName="MujeresI" required
<input matInput type="number" placeholder="Mujeres"
formControlName="MujeresI" required
(change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('MujeresI').invalid && (myForm.get('MujeresI').dirty
<mat-error
*ngIf="myForm.get('MujeresI').invalid && (myForm.get('MujeresI').dirty
|| myForm.get('MujeresI').touched)">
Por favor, ingrese la cantidad de Mujeres indirectas.
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Niños</mat-label>
<input matInput type="number" formControlName="Niños" formControlName="ninosI" required
<input matInput type="number" formControlName="Niños"
formControlName="ninosI" required
(change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('ninosI').invalid && (myForm.get('ninosI').dirty
<mat-error
*ngIf="myForm.get('ninosI').invalid && (myForm.get('ninosI').dirty
|| myForm.get('ninosI').touched)">
Por favor, ingrese la cantidad de Niños directos.
</mat-error>
......@@ -101,22 +121,29 @@
<mat-form-field>
<mat-label>Personas con Capacidades Especiales</mat-label>
<input matInput type="number" formControlName="Personas con Capacidades Especiales"
formControlName="PersonasI" required (change)="calcularTotal()" min="0" pattern="[0-9]+">
<mat-error *ngIf="myForm.get('PersonasI').invalid && (myForm.get('PersonasI').dirty
<input matInput type="number"
formControlName="Personas con Capacidades Especiales"
formControlName="PersonasI" required (change)="calcularTotal()"
min="0" pattern="[0-9]+">
<mat-error
*ngIf="myForm.get('PersonasI').invalid && (myForm.get('PersonasI').dirty
|| myForm.get('PersonasI').touched)">
Por favor, ingrese la cantidad de Personas con Capacidades Especiales Indirectas.
Por favor, ingrese la cantidad de Personas con Capacidades
Especiales Indirectas.
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Total Indirectos</mat-label>
<input matInput class="deshabilitado" type="number" formControlName="Total Indirectos" formControlName="TotalI" required
(change)="calcularTotal()" min="0" pattern="[0-9]+" [value]="totalIndirectos">
<input matInput class="deshabilitado" type="number"
formControlName="Total Indirectos" formControlName="TotalI"
required
(change)="calcularTotal()" min="0" pattern="[0-9]+"
[value]="totalIndirectos">
</mat-form-field>
</div>
</mat-card-content>
</mat-card>
</form>
</div>
\ No newline at end of file
</div>
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
......@@ -16,6 +17,7 @@ import { PoblacionProyectoService } from 'src/app/modules/main/services/poblacio
import { ProgramaService } from 'src/app/modules/main/services/programa/programa.service';
import { ProyectosService } from 'src/app/modules/main/services/proyectos/proyectos.service';
import { UsuariosService } from 'src/app/modules/main/services/usuarios/usuarios.service';
import { EnvioFormularioComponent } from '../../../../programa/opciones/envio-formulario/envio-formulario.component';
@Component({
selector: 'app-add-identificacion-poblacion',
......@@ -26,18 +28,21 @@ export class AddIdentificacionPoblacionComponent implements OnInit {
myForm: FormGroup;
proyecto: Proyectos;
formularioEnviado:boolean;
cambio: boolean;
public idRecuperado;
usuario: Usuario;
totalDirectos: number;
totalIndirectos: number;
mensajeNoDatos: string = '';
@ViewChild('modalNoDatos') modalNoDatosTemplate!: TemplateRef<any>;
constructor(
private formBuilder: FormBuilder,
private ID_compartido: Compartir_idService,
private proyectosService: ProyectosService,
private mostrarOcultarService: MostrarOcultarService,
private dialog: MatDialog
) {
this.proyecto = new Proyectos();
}
......@@ -126,6 +131,7 @@ export class AddIdentificacionPoblacionComponent implements OnInit {
this.proyectosService.modificarParametros(this.proyecto.uzytavproyec_id, this.proyecto).subscribe(response => {
console.log('Datos Actualizados', this.proyecto);
this.myForm.disable();
this.openModal();
this.cambio = false;
//his.openModal();
//this.guardarFormulario = true;
......@@ -136,5 +142,15 @@ export class AddIdentificacionPoblacionComponent implements OnInit {
}
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
width: '400px',
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
console.log('La ventana modal se ha cerrado');
this.formularioEnviado = true;
});
}
}
<div class="container">
<form class="example-form" [formGroup]="myForm" (ngSubmit)="onSubmit()" >
<form class="example-form" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<mat-card>
<mat-card-header>
<div class="save-button">
......@@ -17,14 +17,30 @@
<div>
<label class="label-negrita"> Descripción de la situación actual del
área de intervención del proyecto:</label>
<ckeditor formControlName="diagnostico" [style.height]="editorHeight" [disabled]="!isEditorEnabled" [editor]="Editor"></ckeditor>
<ckeditor formControlName="diagnostico" [style.height]="editorHeight"
[disabled]="!isEditorEnabled" [editor]="Editor"></ckeditor>
<div *ngIf="myForm.get('diagnostico').hasError('maxlength')"
class="error-message">
El contenido no puede exceder los 3000 caracteres.
</div>
<div *ngIf="myForm.get('diagnostico').hasError('required') && (myForm.get('diagnostico').touched || myForm.dirty)" class="error-message">
Este campo es requerido.
</div>
</div>
<div class="editor-separator"></div>
<div>
<label class="label-negrita"> Identificación, descripción y
diagnóstico del problema:</label>
<ckeditor formControlName="identificacion" [style.height]="editorHeight" [disabled]="!isEditorEnabled" [editor]="Editor"></ckeditor>
<ckeditor formControlName="identificacion"
[style.height]="editorHeight" [disabled]="!isEditorEnabled"
[editor]="Editor"></ckeditor>
<div *ngIf="myForm.get('identificacion').hasError('maxlength')"
class="error-message">
El contenido no puede exceder los 3000 caracteres.
</div>
<div *ngIf="myForm.get('identificacion').hasError('required') && (myForm.get('identificacion').touched || myForm.dirty)" class="error-message">
Este campo es requerido.
</div>
</div>
</mat-card-content>
......
......@@ -19,3 +19,15 @@
.editor-separator {
margin-top: 15px;
}
.editor-separator{
margin-top: 4%;
}
.error-message {
color: red;
font-size: 14px;
margin-top: 5px;
}
......@@ -40,6 +40,15 @@ export class EditDiagnosticoComponent implements OnInit {
cancelado() {
this.cambio = false;
this.isEditorEnabled = false;
this.myForm.get('diagnostico').setValue('');
this.myForm.get('identificacion').setValue('');
this.myForm.get('diagnostico').markAsPristine();
this.myForm.get('diagnostico').markAsUntouched();
this.myForm.get('identificacion').markAsPristine()
this.myForm.get('identificacion').markAsUntouched();
}
ngOnInit(): void {
......@@ -48,8 +57,8 @@ export class EditDiagnosticoComponent implements OnInit {
this.obtenerRegistros();
this.myForm = this.formBuilder.group({
diagnostico: [this.proyectos.uzytavproyec_diagnostico],
identificacion: [this.proyectos.uzytavproyec_situactual]
diagnostico: [this.proyectos.uzytavproyec_diagnostico, [Validators.required, Validators.maxLength(3000)]],
identificacion: [this.proyectos.uzytavproyec_situactual, [Validators.required, Validators.maxLength(3000)]]
});
}
......@@ -76,7 +85,7 @@ export class EditDiagnosticoComponent implements OnInit {
this.proyectosService.modificarParametros(this.idRecuperado, this.proyectos).subscribe(response => {
this.cambio = false;
this.isEditorEnabled = false;
this.openModal();
this.openModal('Se ha enviado el Diagnostico y Problema del Proyecto');
});
} catch (error) {
console.error('Error al enviar los datos:', error);
......@@ -84,9 +93,10 @@ export class EditDiagnosticoComponent implements OnInit {
}
}
openModal() {
openModal(mensaje: string) {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
disableClose: true,
data: {mensaje: mensaje}
});
dialogRef.afterClosed().subscribe(result => {
......
......@@ -4,13 +4,95 @@
<mat-label *ngIf="ocultar"><strong>Seleccione una Actividad</strong></mat-label>
<mat-form-field class="form-field" *ngIf="ocultar">
<mat-label>Seleccione un Item</mat-label>
<mat-select formControlName="Actividades">
<mat-select formControlName="Actividades"
(selectionChange)="obtenerActi($event.value)">
<mat-option *ngFor="let item of objetivosE"
[value]="item.uzytavobjetivo_programa_id">
{{ item.uzytavobjetivo_programaobjetivo_proy}}
</mat-option>
</mat-select>
</mat-form-field>
<div class="save-button">
<button mat-raised-button color="primary" *ngIf="ocultar"
(click)="AgregarF()" [disabled]="myForm.get('Actividades').invalid">Agregar</button>
<button mat-raised-button color="primary" *ngIf="showDataAdd"
[disabled]="myForm.invalid">Guardar</button>
<span class="separator"></span>
<button mat-raised-button color="warn" *ngIf="showDataAdd"
(click)="cancelarF()">Cancelar</button>
</div>
<div *ngIf="showDataAdd">
<mat-form-field class="form-field">
<mat-label>Fecha (dd/mm/aa)</mat-label>
<input matInput [matDatepicker]="picker" formControlName="fecha">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<mat-form-field class="form-field">
<mat-label>Observación</mat-label>
<input matInput formControlName="observa">
<mat-error *ngIf="myForm.get('observa').hasError('required') && myForm.get('observa').touched">Esta Campo es requerido</mat-error>
</mat-form-field>
<!--seccion de la tabla-->
<mat-card class="card">
<table mat-table [dataSource]="objetivosA" class="mat-elevation-z8">
<ng-container matColumnDef="Nro">
<th mat-header-cell *matHeaderCellDef> Nro </th>
<td mat-cell *matCellDef="let i = index"> {{ i+1 }} </td>
</ng-container>
<ng-container matColumnDef="actividad">
<th mat-header-cell *matHeaderCellDef> Actividad </th>
<td mat-cell *matCellDef="let actividad"> {{
actividad.uzytavobjetivo_programaobjetivo_proy }} </td>
</ng-container>
<ng-container matColumnDef="fechaIni">
<th mat-header-cell *matHeaderCellDef> Fecha Inicio </th>
<td mat-cell *matCellDef="let actividad"> {{
formatFecha(actividad.uzytavobjetivo_programafec_ini) }} </td>
</ng-container>
<ng-container matColumnDef="fechaFin">
<th mat-header-cell *matHeaderCellDef> Fecha Fin </th>
<td mat-cell *matCellDef="let actividad"> {{
formatFecha(actividad.uzytavobjetivo_programafec_fin) }} </td>
</ng-container>
<div [formGroup]="dynamicForm" (ngSubmit)="onUpdate()">
<ng-container matColumnDef="resultado">
<th mat-header-cell *matHeaderCellDef> Resultado </th>
<td mat-cell *matCellDef="let actividad">
<input matInput type="number" [formControlName]="'resultado' + actividad.uzytavobjetivo_programa_id"
placeholder="Resultado">
</td>
</ng-container>
<ng-container matColumnDef="avance">
<th mat-header-cell *matHeaderCellDef> Avance </th>
<td mat-cell *matCellDef="let actividad">
<input matInput type="number" [formControlName]="'porcentaje' + actividad.uzytavobjetivo_programa_id" placeholder="Avance">
</td>
</ng-container>
<ng-container matColumnDef="observacion">
<th mat-header-cell *matHeaderCellDef> Observación </th>
<td mat-cell *matCellDef="let actividad">
<input matInput type="number" [formControlName]="'observacion' + actividad.uzytavobjetivo_programa_id"
placeholder="Observación">
</td>
</ng-container>
</div>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</mat-card>
</div>
</form>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { objetivoprograma } from 'src/app/modules/main/Models/objetivoPrograma';
import { Actualiza_datosService } from 'src/app/modules/main/services/actualiza_datos/actualiza_datos.service';
import { Objetivo_programaService } from 'src/app/modules/main/services/objetivo_programa/objetivo_programa.service';
import { format } from 'date-fns';
import { EnvioFormularioComponent } from '../../../../programa/opciones/envio-formulario/envio-formulario.component';
import { MatDialog } from '@angular/material/dialog';
import { Informes_avanceService } from 'src/app/modules/main/services/informes_avance/informes_avance.service';
import { actproy } from 'src/app/modules/main/Models/actproy';
import * as moment from 'moment';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import { detactproy } from 'src/app/modules/main/Models/detactproy';
@Component({
selector: 'vex-add-informe',
templateUrl: './add-informe.component.html',
......@@ -12,25 +19,46 @@ import { Objetivo_programaService } from 'src/app/modules/main/services/objetivo
export class AddInformeComponent implements OnInit {
myForm: FormGroup;
dynamicForm: FormGroup;
showData: boolean = false;
ShowDataAdd: boolean = false;
showDataAdd: boolean = false;
ocultar: boolean = true;
idRecuperado: number;
//arreglo para la tabla
actividadesFormArray: FormArray;
//arreglos
objetivosE: objetivoprograma[]=[];
detactproy!: detactproy ;
objetivosE: objetivoprograma[] = [];
objetivosA: objetivoprograma[] = [];
cabecera: actproy[] = [];
formularioEnviado: boolean;
formControlsMap: { [key: number]: FormGroup };
displayedColumns: string[] = [
'Nro',
'actividad',
'fechaIni',
'fechaFin',
'resultado',
'avance',
'observacion'
];
constructor(
private objetS: Objetivo_programaService,
private datosCompartidos: Actualiza_datosService,
private formBuilder: FormBuilder
private formBuilder: FormBuilder,
private dialog: MatDialog,
private informeS: Informes_avanceService,
private cabeM: actproy,
private bodyM: detactproy
) {
this.myForm = this.formBuilder.group({
Actividades: ['', Validators.required]
});
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'),10);
this.initializeForm();
this.formControlsMap = {};
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'), 10);
this.datosCompartidos.datos$.subscribe(() => {
this.obtenerRegistros();
});
......@@ -40,24 +68,167 @@ export class AddInformeComponent implements OnInit {
});
}
obtenerRegistros(){
this.objetS.registrosRelacionadosConProyecto(this.idRecuperado).subscribe(data =>{
this.objetivosE = data.filter( item => item.uzytavobjetivo_programatipo === 3);
console.log('impresión del arreglo', this.objetivosE)
initializeForm() {
//this.actividadesFormArray = this.formBuilder.array([]);
this.myForm = this.formBuilder.group({
Actividades: ['', Validators.required],
observa: ['', Validators.required],
fecha: [{ value: new Date(), disabled: true }],
});
this.dynamicForm = this.formBuilder.group({});
}
obtenerRegistros() {
// Obtener los registros de objetivoprograma relacionados con el proyecto
this.objetS.registrosRelacionadosConProyecto(this.idRecuperado).subscribe(objetivosData => {
// Filtrar los registros de objetivoprograma según el primer filtro
this.objetivosE = objetivosData.filter(item => item.uzytavobjetivo_programatipo === 3);
//controles para los inputs en el form
// Obtener los registros de cabecera relacionados con el proyecto
this.informeS.obtenerCabecera().subscribe(cabeceraData => {
this.cabecera = cabeceraData.filter(item => item.uzytavproyec_id === this.idRecuperado);
// Filtrar nuevamente los registros de objetivoprograma excluyendo aquellos que ya tienen cabecera
this.objetivosE = this.objetivosE.filter(objetivo =>
!this.cabecera.some(cab => cab.uzytavobjetivo_programa_id === objetivo.uzytavobjetivo_programa_id)
);
});
/*// Filtrar los registros de objetivoprograma excluyendo aquellos que ya están en actproy
this.objetivosE = this.objetivosE.filter(objetivo =>
!this.cabecera.some(act => act.uzytavobjetivo_programa_id === objetivo.uzytavobjetivo_programa_id)
);*/
});
}
obtenerActi(id: number) {
this.objetS.obtenerParametros().subscribe(data => {
this.objetivosA = data.map(obje => {
// Create dynamic form control
this.createDynamicFormControls(obje.uzytavobjetivo_programa_id);
return obje
});
this.objetivosA = data.filter(item => item.uzytavproyec_id === this.idRecuperado && item.uzytavobjetivo_programatipo === 4 && item.uzytavobjetivo_programa_id_padre === id);
});
}
createDynamicFormControls(opciones: number) {
this.dynamicForm.addControl('resultado' + opciones,
this.formBuilder.control({ value: "", disabled: false },
[Validators.required]));
this.dynamicForm.addControl('porcentaje' + opciones,
this.formBuilder.control({ value: "", disabled: false },
[Validators.required]));
this.dynamicForm.addControl('observacion' + opciones,
this.formBuilder.control({ value: "", disabled: false },
[Validators.required]));
}
/*
actividadForm(actividad: any): FormGroup {
return this.formBuilder.group({
resultado: [' ', Validators.required],
avance: [' ', Validators.required],
observacion: [' ', Validators.required]
});
}
*/
AgregarF() {
this.showDataAdd = true;
this.ocultar = false;
}
cancelarF() {
this.showDataAdd = false;
this.ocultar = true;
this.myForm.get('Actividades').reset();
this.myForm.reset();
}
onUpdate() {
if (this.myForm.valid) {
this.cabeM.uzytavproyec_id = this.idRecuperado;
const fechaIni = moment(this.myForm.get('fecha').value).utc().toDate();
const fechaHoraIni = new Date(fechaIni);
fechaHoraIni.setUTCHours(fechaHoraIni.getUTCHours() - 5);
AgregarF(){
this.cabeM.uzytavactproy_fech_regis = fechaHoraIni;
this.cabeM.uzytavobjetivo_programa_id = this.myForm.get('Actividades').value;
this.cabeM.uzytavactproy_observa = this.myForm.get('observa').value;
this.informeS.guardarCabecera(this.cabeM).subscribe(response => {
this.guardarBody(this.informeS.obtenerIdCabe());
this.cancelarF();
this.datosCompartidos.actualizarDatos(this.cabeM);
this.openModal();
});
}
}
cancelarF(){
guardarBody(id: number){
if (this.myForm.valid) {
this.bodyM.uzytavactproy_id = id;
console.log('arreglo', this.objetivosA)
this.objetivosA.forEach(
opcion => {
const controlNameResultado = 'resultado' + opcion.uzytavobjetivo_programa_id;
const controlNamePorcentaje = 'porcentaje' + opcion.uzytavobjetivo_programa_id;
const controlNameObservacion = 'observacion' + opcion.uzytavobjetivo_programa_id;
const selectedValueId = this.dynamicForm.get(controlNameResultado)?.value;
const selectedValueIdPorcentaje = this.dynamicForm.get(controlNamePorcentaje)?.value;
const selectedValueIdObservacion = this.dynamicForm.get(controlNameObservacion)?.value;
if (selectedValueId !== null && selectedValueId !== undefined && selectedValueIdPorcentaje !== null && selectedValueIdPorcentaje !== undefined && selectedValueIdObservacion !== null && selectedValueIdObservacion !== undefined) {
// Crear el objeto EvaluacionProy con los valores necesarios
const detactproy: detactproy = {
uzytavactproy_id: id,
uzytavobjetivo_programa_id: opcion.uzytavobjetivo_programa_id,
uzytavdetactproyporcent: selectedValueIdPorcentaje,
uzytavdetactproyobserva: selectedValueIdObservacion,
uzytavdetactproyresultado: selectedValueId
// Agregar otros campos si es necesario
};
this.informeS.guardarParametros(detactproy).subscribe(() => {
});
}
});
}
}
onUpdate(){
formatFecha(fecha: Date): string {
if (fecha === null) {
console.log('Agregar fecha:')
} else {
const dateObj = new Date(fecha);
return format(dateObj, 'dd-MM-yyyy');
}
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
this.formularioEnviado = true;
});
}
}
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<!-- Control de fechas inicio -->
<div class="save-button">
<button mat-raised-button class="botones" color="primary" [disabled]="myForm.invalid">Guardar</button>
<span class="separator"></span>
<button mat-raised-button class="botones" color="warn" (click)="cancelado()">Cancelar</button>
</div>
<mat-form-field class="form-field">
<mat-label>Fecha (dd/mm/aa)</mat-label>
<input matInput [matDatepicker]="picker" formControlName="fecha">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="input-container">
<mat-form-field class="example-full-width">
<mat-label>Observaciones</mat-label>
<input matInput placeholder="Ingresar el valor ejecutado durante el desarrollo del Proyecto" formControlName="observacion">
<mat-error *ngIf="myForm.get('observacion').hasError('required') && myForm.get('observacion').touched">Esta Campo es requerido</mat-error>
</mat-form-field>
</div>
</div>
</form>
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { actproy } from 'src/app/modules/main/Models/actproy';
import { Actualiza_datosService } from 'src/app/modules/main/services/actualiza_datos/actualiza_datos.service';
import { Compartir_idService } from 'src/app/modules/main/services/compartir_id/compartir_id.service';
import { Informes_avanceService } from 'src/app/modules/main/services/informes_avance/informes_avance.service';
import { MostrarOcultarService } from 'src/app/modules/main/services/mostrar-ocultar.service';
import { EnvioFormularioComponent } from '../../../../programa/opciones/envio-formulario/envio-formulario.component';
@Component({
selector: 'vex-edit-informe',
......@@ -7,21 +14,62 @@ import { FormBuilder, FormGroup } from '@angular/forms';
styleUrls: ['./edit-informe.component.css']
})
export class EditInformeComponent implements OnInit {
idRecuperado: number;
myForm: FormGroup;
formularioEnviado: boolean;
cabe: actproy;
idRecuperado: number;
mostrarObje: boolean = false;
constructor(
private formBuilder: FormBuilder
private formBuilder: FormBuilder,
private dialog: MatDialog,
private idCompartido: Compartir_idService,
private informeS: Informes_avanceService,
private mostrarOcultarSerivce: MostrarOcultarService,
private datosCompartidos: Actualiza_datosService,
private cabeM: actproy
) {
this.myForm = this.formBuilder.group({
fecha: [''],
observacion: [''],
});
}
ngOnInit(): void {
this.idRecuperado = parseInt(localStorage.getItem('proyectoId'),10);
this.cabe = this.mostrarOcultarSerivce.editCabecera;
this.idRecuperado = this.idCompartido.getCabe();
this.initializeForm();
this.mostrarObje = true;
}
initializeForm(){
this.myForm = this.formBuilder.group({
fecha: [{ value: this.cabe.uzytavactproy_fech_regis, disabled: true}, Validators.required],
observacion: [{ value: this.cabe.uzytavactproy_observa, disabled: false}, Validators.required],
});
}
onSubmit(){
if(this.myForm.valid){
this.cabeM.uzytavactproy_observa = this.myForm.get('observacion').value;
this.informeS.modificarParametrosCabecera(this.cabeM.uzytavactproy_id, this.cabeM).subscribe(response => {
this.openModal();
this.idCompartido.ocultarFormulario3();
this.datosCompartidos.actualizarDatos(this.cabeM);
});
}
}
cancelado(){
this.idCompartido.ocultarFormulario3();
this.mostrarObje = false;
this.myForm.enable();
this.myForm.reset();
}
openModal() {
const dialogRef = this.dialog.open(EnvioFormularioComponent, {
disableClose: true
});
dialogRef.afterClosed().subscribe(result => {
this.formularioEnviado = true;
});
}
}
......@@ -31,16 +31,16 @@
<td>
{{i+1}}
</td>
<td>{{item.uzytavactproy_fech_regis}}</td>
<td>{{formatFecha(item.uzytavactproy_fech_regis)}}</td>
<td>{{item.uzytavactproy_observa}}</td>
<td>
<button>
<mat-icon color="primary"
(click)="editarCabecera(item.uzytavactproy_id)">edit</mat-icon>
<mat-icon color="warn"
(click)="eliminarHeader(item.uzytavactproy_id)">delete</mat-icon>
</button>
<button>
<mat-icon color="warn"
(click)="eliminar(item.uzytavactproy_id)">delete</mat-icon>
<mat-icon color="azul"
(click)="editarCabecera(item.uzytavactproy_id)">edit</mat-icon>
</button>
</td>
</tr>
......@@ -58,7 +58,6 @@
<th class="Column1 negrita">Porcentaje</th>
<th class="Column1 negrita">Observación</th>
<th class="Column1 negrita">Resultados</th>
<th class="Column1 negrita">Editar</th>
</tr>
</thead>
<tbody>
......@@ -70,12 +69,6 @@
<td>{{acti.uzytavdetactproyporcent}}</td>
<td>{{acti.uzytavdetactproyobserva}}</td>
<td>{{acti.uzytavdetactproyresultado}}</td>
<td>
<button>
<mat-icon color="primary"
(click)="editarBody(acti.uzytavdetactproy_id)">edit</mat-icon>
</button>
</td>
</ng-container>
</tr>
</tbody>
......
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { format } from 'date-fns';
import { actproy } from 'src/app/modules/main/Models/actproy';
import { detactproy } from 'src/app/modules/main/Models/detactproy';
import { objetivoprograma } from 'src/app/modules/main/Models/objetivoPrograma';
......@@ -97,11 +98,11 @@ export class ListInformeComponent implements OnInit {
}
editarBody(id: number){
this.idCompartido.mostrarFormulario5();
this.idCompartido.mostrarFormulario4();
const registroSeleccionado = this.body.find(
item => item.uzytavdetactproy_id === id
);
this.idCompartido.setCabe(id);
this.idCompartido.setBody(id);
this.mostrarOcultarService.editBody = registroSeleccionado;
}
......@@ -110,4 +111,25 @@ export class ListInformeComponent implements OnInit {
this.activitySection.nativeElement.scrollIntoView({ behavior: 'smooth' });
}
}
eliminarHeader(id: number){
const confirmacion = confirm('¿Desea eliminar el registro?');
if (confirmacion) {
this.informeS.eliminarParametrosCabecera(id).subscribe(
() => {
console.log('El registro se ha eliminado');
this.obtenerRegistros();
},
(error) => {
// No mostrar el error en la consola
console.log('Error durante el tratamiento al registro');
}
);
}
}
formatFecha(fecha: Date): string {
const dateObj = new Date(fecha);
return format(dateObj, 'dd-MM-yyyy');
}
}
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 10px;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 1%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
margin-top: 30px;
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.buscar {
cursor: pointer;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 16px;
}
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet" />
<div class="contenedor">
<div class="contedor-dos">
<ng-template #modalNoDatos let-modal>
<div class="modal-container">
<h2>Información</h2>
<p>{{ mensajeNoDatos }}</p>
<button mat-button (click)="cerrarModalNoDatos()">Cerrar</button>
</div>
</ng-template>
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<div class="input-container">
<mat-form-field>
<mat-label>Nombre:</mat-label>
<mat-select formControlName="nombreI"
placeholder="Nombre del Proyecto"
(selectionChange)="onUsuario($event.value)">
<mat-option *ngFor="let item2 of usuario" [value]="item2.uzytusuario_id">{{
item2.uzytusuario_apellidos+ ', '+item2.uzytusuario_nombres}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="input-container">
<mat-form-field class="example-full-width">
<mat-label>Nombre:</mat-label>
<input matInput formControlName="nombre" required>
</mat-form-field>
</div>
<div class="input-container">
<mat-form-field class="example-full-width">
<mat-label>Apellido:</mat-label>
<input matInput formControlName="apellido" required>
</mat-form-field>
</div>
<button mat-raised-button color="primary" [disabled]="myForm.invalid">Guardar</button>
</form>
</div>
</div>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DesignarEvaluadorComponent } from './designar-evaluador.component';
describe('DesignarEvaluadorComponent', () => {
let component: DesignarEvaluadorComponent;
let fixture: ComponentFixture<DesignarEvaluadorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DesignarEvaluadorComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(DesignarEvaluadorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Perfil } from 'src/app/modules/main/Models/perfil';
import { PerfilUsuario } from 'src/app/modules/main/Models/perfil_usuario';
import { Usuario } from 'src/app/modules/main/Models/usuario';
import { PerfilUsuarioService } from 'src/app/modules/main/services/PerfilUsuario/perfil-usuario.service';
import { PerfilService } from 'src/app/modules/main/services/perfiles/perfil.service';
import { UsuariosService } from 'src/app/modules/main/services/usuarios/usuarios.service';
@Component({
selector: 'vex-designar-evaluador',
templateUrl: './designar-evaluador.component.html',
styleUrls: ['./designar-evaluador.component.css']
})
export class DesignarEvaluadorComponent implements OnInit {
usuario: Usuario[] = [];
myForm: FormGroup;
mensajeNoDatos: string = '';
searchTerm: string;
userData: any;
mostrarModalNoDatos: boolean = false;
@ViewChild('modalNoDatos') modalNoDatosTemplate!: TemplateRef<any>;
constructor(
private formBuilder: FormBuilder,
private dialog: MatDialog,
private usuarioS: UsuariosService,
private perfilS: PerfilService,
private perfilUserS: PerfilUsuarioService
) {
}
ngOnInit(): void {
this.obtenerDatos();
this.myForm = this.formBuilder.group({
nombreI: ['', Validators.required],
nombre: [{ value: '', disabled: true }, Validators.required],
apellido: [{ value: '', disabled: true }, Validators.required],
});
}
onSubmit() {
}
obtenerDatos() {
this.usuarioS.obtenerParametros().subscribe(data => {
this.usuario = data;
});
}
onUsuario(selectedUserID: number) {
const selectedUser = this.usuario.find(item => item.uzytusuario_id === selectedUserID);
if(selectedUser){
this.myForm.get('nombre')?.setValue(selectedUser.uzytusuario_nombres);
this.myForm.get('apellido')?.setValue(selectedUser.uzytusuario_apellidos);
}
}
abrirModalNoDatos(mensaje: string) {
this.mensajeNoDatos = mensaje;
this.dialog.open(this.modalNoDatosTemplate);
}
cerrarModalNoDatos() {
this.dialog.closeAll();
}
}
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
}
/* Estilos para el formulario */
.formulario {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
max-width: 96%;
margin: 0 auto;
background-color: white;
border-radius: 10px;
}
.botones{
width: 100px;
height: 40px;
text-align: center;
padding: 0;
}
/* Estilos para la columna única */
.columna-unico {
width: 100%;
box-sizing: border-box;
padding-right: 0;
padding-left: 0;
}
/* Estilos para los labels */
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
/* Estilos para los inputs y selects */
input[type="text"],
select {
width: 100%;
padding: 10px;
border: none;
border-bottom: 1px solid #ccc;
background-color: transparent;
font-size: 16px;
margin-bottom: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #4caf50;
}
/* Estilos para los mensajes de error */
.error-message {
color: red;
font-size: 14px;
margin-top: 4px;
}
/* Estilos para el botón */
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: rgb(71, 127, 75);
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: rgb(90, 159, 95);
}
/* Estilos para el contenedor principal */
.contenedor {
width: 96%;
margin-left: 2%;
margin-right: 2%;
margin-top: 10%;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
background-color: #ffffff;
position: relative;
z-index: 1;
}
/* Estilos para el contenedor del formulario */
.contenedor-dos {
padding: 0.9375rem 20px;
position: relative;
}
/* Estilos para el título sobremontado */
.sobremontado {
position: relative;
width: 96%;
top: -20px;
left: 2%;
background-color: #477f4b;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
margin-bottom: -50px;
z-index: 2;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}
/* Estilos para el icono de instituciones */
.icono-instituciones {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
font-size: 20px;
}
.volver{
position: absolute;
top: 25%;
right: 10px;
transform: translateY(-50%);
border-radius: 50%;
background-color: white;
display: flex;
color: rgb(71, 127, 75);
align-items: center;
justify-content: center;
padding: 0;
width: 32px;
height: 32px;
border: none;
outline: none;
cursor: pointer;
}
.save-button {
display: flex;
justify-content: flex-end;
margin-bottom: 5px;
}
.input-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 5px;
}
<div class="contenedor-dos">
<form class="formulario" [formGroup]="myForm" (ngSubmit)="onSubmit()">
<!-- Información de la institución -->
<div class="columna-unico">
<!-- Control de fechas inicio -->
<div class="save-button">
<button mat-raised-button class="botones" color="primary" *ngIf="!cambio" (click)="cambiar()">Agregar</button>
<button mat-raised-button class="botones" color="primary" *ngIf="cambio"
[disabled]="myForm.invalid">Guardar</button>
<span class="separator"></span>
<button mat-raised-button class="botones" color="warn" *ngIf="cambio" (click)="cancelado()">Cancelar</button>
</div>
<div class="input-container">
<mat-form-field class="contenedor-dos">
<mat-label>Nombres</mat-label>
<input matInput [formControl]="myControl" [matAutocomplete]="autocomplete" formControlName="nombres"
placeholder="Realizar búsqueda" />
</mat-form-field>
<mat-autocomplete *ngIf="usuarios" autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let usuario of filteredOptions | async" [value]="usuario"
(click)="onUsuarioSelected(usuario)">
{{ usuario.uzytusuario_nombres }} {{ usuario.uzytusuario_apellidos }}
</mat-option>
</mat-autocomplete>
</div>
<div class="input-container">
<mat-form-field class="contenedor-dos">
<mat-label>Seleccionar Funcion</mat-label>
<mat-select formControlName="funcion">
<mat-option *ngFor="let option of tipres" [value]="option.uzytavtipres_id">
{{ option.uzytavtipres_descrip }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="input-container">
<mat-form-field class="contenedor-dos">
<mat-label>Número de horas planificadas:</mat-label>
<input matInput formControlName="numero" required pattern="[0-9]+">
<mat-error *ngIf="myForm.get('numero').invalid && (myForm.get('numero').dirty ||
myForm.get('numero').touched)">
Por favor, ingrese un Número de horas planificadas.
</mat-error>
</mat-form-field>
</div>
</div>
</form>
</div>
\ No newline at end of file
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { AsignacionDocentesComponent } from './asignacion-docentes.component';
describe('AsignacionDocentesComponent', () => {
let component: AsignacionDocentesComponent;
let fixture: ComponentFixture<AsignacionDocentesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AsignacionDocentesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AsignacionDocentesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
<div class="container">
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- Nro Column -->
<ng-container matColumnDef="Nro" class="Column1">
<th class="Column1 negrita" mat-header-cell *matHeaderCellDef mat-sort-header> Nro </th>
<td class="Column1" mat-cell *matCellDef="let i = index"> {{ i+1 }}
</td>
</ng-container>
<!-- Dirección Column -->
<ng-container matColumnDef="Campus" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header>Campus</th>
<td class="Column" mat-cell *matCellDef="let dato">
{{dato.campus$ | async }} </td>
</ng-container>
<ng-container matColumnDef="Departamento" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header>Departamento</th>
<td class="Column" mat-cell *matCellDef="let dato">
{{ dato.departamento$ | async }}
</td>
</ng-container>
<ng-container matColumnDef="Docentes Participantes" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header>Docentes Participantes</th>
<td class="Column" mat-cell *matCellDef="let dato"> {{dato.uzytavdocparti_numero}} </td>
</ng-container>
<ng-container matColumnDef="Acciones" class="Column">
<th class="Column" mat-header-cell *matHeaderCellDef mat-sort-header>Acciones</th>
<td class="Column" mat-cell *matCellDef="let dato">
<!--eliminar-->
<button>
<mat-icon color="warn" (click)="eliminarParametro(dato.uzytavdocparti_id)">delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<table> <!-- Nueva tabla para la fila de total -->
<tr>
<td class="Column1 negrita " colspan="1">Total</td>
<td class="Column ">{{ totalDocentesParticipantes }}</td>
<td class="Column "></td>
<td class="Column "></td>
</tr>
</table>
</div>
</div>
\ No newline at end of file
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ListarDocentesAsignadosComponent } from './listar-docentes-asignados.component';
describe('ListarDocentesAsignadosComponent', () => {
let component: ListarDocentesAsignadosComponent;
let fixture: ComponentFixture<ListarDocentesAsignadosComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ListarDocentesAsignadosComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListarDocentesAsignadosComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
<div class="modal">
<div class="modal-content">
<p>
La información excede el maximo de caracteres</p>
{{mensaje}}</p>
<button mat-button (click)="closeModal()">Cerrar</button>
</div>
</div>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment