diff --git a/src/app/demandes-formation/demandes-formation.component.html b/src/app/demandes-formation/demandes-formation.component.html index 59510c3..ed2dec7 100644 --- a/src/app/demandes-formation/demandes-formation.component.html +++ b/src/app/demandes-formation/demandes-formation.component.html @@ -1,2 +1,3 @@

Liste des demandes de formation

+ diff --git a/src/app/demandes-formation/demandes-formation.component.ts b/src/app/demandes-formation/demandes-formation.component.ts index 336d248..9dea266 100644 --- a/src/app/demandes-formation/demandes-formation.component.ts +++ b/src/app/demandes-formation/demandes-formation.component.ts @@ -1,4 +1,7 @@ import { Component, OnInit } from '@angular/core'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { DemandeFormationDTO } from '@shared/api-swagger'; +import { DialogDemandeFormationComponent } from './mat-dialog/dialog-demande-formation.component'; /** * Composant pour faire afficher la liste des demandes de formations @@ -10,8 +13,16 @@ import { Component, OnInit } from '@angular/core'; }) export class DemandesFormationComponent implements OnInit { - constructor() {} + displayedColumns : string[] = ["businessunit", "collaborateur", "datedemande", "demanderh", "ep", "etat", "datereponse"]; + + constructor(private dialog: MatDialog) {} + ngOnInit() { } + + afficherDetailDemandeFormation(demandeFormation: DemandeFormationDTO) { + const datas = { data: demandeFormation, width: "80%", height: '80%'}; + this.dialog.open(DialogDemandeFormationComponent, datas); + } } diff --git a/src/app/demandes-formation/demandes-formation.module.ts b/src/app/demandes-formation/demandes-formation.module.ts index 838506f..031f2a4 100644 --- a/src/app/demandes-formation/demandes-formation.module.ts +++ b/src/app/demandes-formation/demandes-formation.module.ts @@ -1,35 +1,40 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { NgModule } from "@angular/core"; import { CommonModule } from "@angular/common"; - import { MaterialModule } from "@shared/angular-material/angular-material.module"; import {NavMenuModule} from '@shared/nav-menu/nav-menu.module'; import { DemandesFormationComponent } from './demandes-formation.component'; +import { DialogDemandeFormationComponent } from './mat-dialog/dialog-demande-formation.component'; import { DemandeFormationComponent } from './details-demande-formation/demande-formation.component' import { NewDemandeFormationComponent } from './new-demande-formation/new-demande-formation.component' import { DemandesFormationsRoutingModule } from './demandes-formation.routing.module'; +import { MatTablesModule } from "@shared/mat-tables/mat-tables.module"; /** * Module demandes formation */ @NgModule({ - declarations: [ DemandesFormationComponent, DemandeFormationComponent, + declarations: [ DemandesFormationComponent, DialogDemandeFormationComponent, DemandeFormationComponent, NewDemandeFormationComponent ], exports: [ DemandesFormationComponent ], imports: [ + CommonModule, MaterialModule, NavMenuModule, DemandesFormationsRoutingModule, - RouterModule + MatTablesModule, + RouterModule, + FormsModule, + ReactiveFormsModule ], }) export class DemandesFormationModule {} diff --git a/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.html b/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.html new file mode 100644 index 0000000..38e722a --- /dev/null +++ b/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.html @@ -0,0 +1,31 @@ +

Détails de la demande

+

+

+

+

Libellé : {{ data.libelle}}

+

Description: {{ data.description }}

+

Demande RH: {{ afficherDemandeRH(data.demandeRH) }}

+

Date demande: {{ data.dateDemande | date: 'dd/MM/yyyy' }}

+

Etat : {{ afficherEtat(data.etatDemande) }}

+

Raison du refus : {{data.commentaireRefus}}

+ + + + + Demande validée + + +
+ + Raison du refus + + + +
+ +
+ +
+ + + diff --git a/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.ts b/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.ts new file mode 100644 index 0000000..e33e012 --- /dev/null +++ b/src/app/demandes-formation/mat-dialog/dialog-demande-formation.component.ts @@ -0,0 +1,79 @@ +import { Component, Inject } from "@angular/core"; +import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; +import { MatSnackBar } from "@angular/material/snack-bar"; +import { CollaborateurDTO, EpInformationDTO, DemandesFormationService, DemandeFormationDTO, EtatDemande, afficherEtatDemande } from "@shared/api-swagger"; +import { Subscription } from "rxjs"; + + +@Component( { + selector: "dialog-demande-formation", + templateUrl: "dialog-demande-formation.component.html" +}) +export class DialogDemandeFormationComponent { + ep: EpInformationDTO; + collaborateur: CollaborateurDTO; + referent: CollaborateurDTO; + etatDemande: any = EtatDemande; + engagementsSubscription: Subscription; + + donnerReponse: boolean = false; + commentaireRefus : string = ""; + demandeValidee: boolean = true; + + + constructor(private dialogRef : MatDialogRef, @Inject(MAT_DIALOG_DATA) public data : DemandeFormationDTO, private demandesFormationService: DemandesFormationService, + private snackBar: MatSnackBar){ + this.ep = data.ep; + this.collaborateur = data.ep.collaborateur; + this.referent = data.ep.referent; + } + + updateDemandeFormation() { + let demandeFormation : DemandeFormationDTO = this.data; + if(this.demandeValidee) { + demandeFormation.etatDemande = EtatDemande.Validee; + } + else { + if(this.commentaireRefus.length == 0) { + this.snackBar.open("Vous devez justifier le refus de la demande de formation.", "Attention", { + duration: 5000, + horizontalPosition: "center", + verticalPosition: "top", + }); + return; + } + + demandeFormation.commentaireRefus = this.commentaireRefus; + demandeFormation.etatDemande = EtatDemande.Rejetee; + } + this.engagementsSubscription = this.demandesFormationService.updateDemandeFormation(demandeFormation, demandeFormation.id).subscribe( + () => location.reload(), + err => console.log(err) + ); + } + + afficherDemandeRH(demandeRH: boolean) { + if (demandeRH) + return 'Oui'; + else + return 'Non' + } + + afficherEtat(etat: EtatDemande) { + return afficherEtatDemande(etat); + } + + fermer() { + this.dialogRef.close(); + } + + repondre() { + this.donnerReponse = true; + } + + ngOnDestroy() { + if(this.engagementsSubscription != null) { + this.engagementsSubscription.unsubscribe(); + } + } +} \ No newline at end of file diff --git a/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.css b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.css new file mode 100644 index 0000000..d42a102 --- /dev/null +++ b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.css @@ -0,0 +1,16 @@ +div { + margin-left: 5%; + margin-bottom: 1%; +} + +.input{ + width: 30%; +} + +.input2 { + width: 14%; +} + +.moveright { + margin-left: 2%; +} diff --git a/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.html b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.html index 84467ba..6185302 100644 --- a/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.html +++ b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.html @@ -1,2 +1,35 @@

Nouvelle demande de formation

+ + + +
+
+ + + + +
+ +
+ + + + +
+ +
+ + + Origine de la demande + + {{o.libelle}} + + +
+ + +
+ +
+
\ No newline at end of file diff --git a/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.ts b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.ts index ad4488c..4cc4292 100644 --- a/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.ts +++ b/src/app/demandes-formation/new-demande-formation/new-demande-formation.component.ts @@ -1,16 +1,80 @@ import { Component, OnInit } from '@angular/core'; +import { Observable, Subscription } from 'rxjs'; +import { Router } from '@angular/router'; +import { FormBuilder, FormGroup, FormControl, } from '@angular/forms'; + +import { OrigineDemandeFormationDTO, EtatDemande } from "@shared/api-swagger/model/models"; + +import { DemandesFormationService } from "@shared/api-swagger/api/api"; /** * Composant qui sert à créer une demande de formation pour un collaborateur. */ @Component({ selector: 'app-new-demande-formation', - templateUrl: './new-demande-formation.component.html' + templateUrl: './new-demande-formation.component.html', + styleUrls: ['./new-demande-formation.component.css'] }) export class NewDemandeFormationComponent implements OnInit { - constructor() {} + /** + * Observable pour enregistrer la nouvelle formation + */ + demandeFormationSubscription: Subscription; + /** + * Observable pour récupérer la liste des origines formation + */ + origineDemandeSubscription: Subscription; + + + /** + * Liste des origines de demande de formation à faire afficher dans une liste déroulante. + */ + originesDemandeFormation: OrigineDemandeFormationDTO[]; + + /** + * FormBuilder qui sera lié au formulaire du template avec les attributs d'une formation + * C'est dans cet objet qu'est stockée la nouvelle formation + */ + demandeFormationForm = this.fb.group( + { + id:[0], + libelle: [""], + description: [], + demandeRH: [true], + dateDemande: [new Date()], + etatDemande: [EtatDemande.EnAttente], + origine: [""], + collaborateur: [""], + } + ); + + constructor(private fb: FormBuilder, private demandesFormationService: DemandesFormationService, private router: Router) { } + + ngOnInit() { + + this.origineDemandeSubscription = this.demandesFormationService.getOriginesDemandeFormation().subscribe( + originesDemandeFormation => this.originesDemandeFormation = originesDemandeFormation, + err => console.log(err) + ); + } + + ajouterDemandeFormation() { + this.demandeFormationSubscription = this.demandesFormationService.addDemandeFormation(this.demandeFormationForm.getRawValue()).subscribe( + response => { + console.log(response); + this.router.navigate(['/demandesformation',response["id"]]); + } + ); + } + + ngOnDestroy() { + if(this.demandeFormationSubscription != undefined) { + this.demandeFormationSubscription.unsubscribe(); + } - ngOnInit() { - } + if(this.origineDemandeSubscription != undefined) { + this.origineDemandeSubscription.unsubscribe(); + } + } } diff --git a/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.css b/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.html b/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.html new file mode 100644 index 0000000..690a6a6 --- /dev/null +++ b/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.html @@ -0,0 +1,133 @@ + + + + + + + + + Rechercher un collaborateur + + + + + + + + + + + + + + + + + + + + + + + + Date de début + + clear + + + + + + + Date de fin + + clear + + + + + + + +

Aucune demande de formation à afficher

+
+ + + + + Agence + {{row.ep.collaborateur.businessUnit.nom}} + + + + Collabotareur + + + {{row.collaborateur.nom}} {{row.collaborateur.prenom}} + + + + + Date demande + {{row.dateDemande | date :'dd/MM/yyyy'}} + + + + Demande RH + {{afficherDemandeRH(row.demandeRH)}} + + + + EP + + + +

Consulter EP

+
+
+
+ + + Réponse + {{afficherEtat(row.etatDemande)}} + + + + Date réponse + + {{row.dateDerniereReponse | date :'dd/MM/yyyy'}} + {{row.dateDerniereReponse}} + + + + + +
+ + +
+ +
\ No newline at end of file diff --git a/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.ts b/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.ts new file mode 100644 index 0000000..11d9a94 --- /dev/null +++ b/src/app/shared/mat-tables/demandes-formation-table/demandes-formation.table.ts @@ -0,0 +1,372 @@ +import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { MatTableDataSource } from "@angular/material/table"; +import { BusinessUnitDTO, CollaborateurDTO, DemandesFormationService, EtatDemande, afficherEtatDemande, DemandeFormationDTO, StatutEp, estEPEnCours } from "@shared/api-swagger"; +import { cles } from "@shared/utils/cles"; +import { DemandesFormationsRoutingModule } from "app/demandes-formation/demandes-formation.routing.module"; + +import { Subscription } from "rxjs"; + + +@Component({ + selector: "demandes-formation-table", + templateUrl: "./demandes-formation.table.html" +}) +export class DemandesFormationTableComponent implements OnInit { + + + chargement : boolean = true; + + /** + * * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà). + */ + asc : boolean = true; + + /** + * Numéro de la page à afficher dans le tableau. + */ + numPage: number = 1; + + /** + * Nombre d'élément du tableau à affiche en une page. + */ + parPage: number = 15; + + /** + * Nombre total d'élément du tableau + */ + taille: number = 0; + + /** + * Liste des business units du collaborateur connecté + */ + bus: Array = []; + + /** + * contenu de la recherche pour trouver un collaborateur. + */ + search: string = ""; + + /** + * Options pour choisir le nombre de page à affiche + */ + pageOption = [ 5, 15, 20, 30, 50]; + + /** + * Permet de savoir sur quelle attribut d'un CollaborateurDTO doit être trié le tableau. + */ + tri: string = "collaborateur"; + + /** + * Liste des id des business units des collaborateurs à afficher + */ + private busIds: Array = []; + + /** + * Liste des tous les états demandes + */ + etatsDemandes: Array = [ + EtatDemande.EnAttente, EtatDemande.Validee, + EtatDemande.Rejetee + ]; + etatsDemandesAffiches: Array = [ + EtatDemande.EnAttente, EtatDemande.Validee, + EtatDemande.Rejetee + ]; + + /** + * Liste des tous les statuts d'EP + */ + allStatutsEp: Array = [ + StatutEp.Cree, StatutEp.Disponible, + StatutEp.Saisi, StatutEp.DatesProposees, + StatutEp.AttenteEntretien, StatutEp.Effectue, + StatutEp.SignatureReferent, StatutEp.Signe, + StatutEp.Rejete, StatutEp.Annule + ]; + + statutsEp: Array = [ + StatutEp.Cree, StatutEp.Disponible, + StatutEp.Saisi, StatutEp.DatesProposees, + StatutEp.AttenteEntretien, StatutEp.Effectue, + StatutEp.SignatureReferent, StatutEp.Signe, + StatutEp.Rejete, StatutEp.Annule + ]; + + statutsEpAffiches: Array = [ + 'Annulé','En cours', 'Rejeté', 'Signé' + ]; + + /** + * Date à partir de laquelle les demandes de formation doivent être récupérées en fonction de leur date de demande + */ + dateDebut: Date = undefined; + + /** + * Date jusqu'à laquelle les demandes de formation doivent être récupérées en fonction de leur date de demande + */ + dateFin: Date = undefined; + + + /** + * Liste des colonnes du tableau à afficher. + */ + @Input() displayedColumns : string[] = []; + @Input() estAffichageEP: boolean = false; + @Input() demandesFormation: DemandeFormationDTO[] = []; + + @Output() eventEmitter: EventEmitter = new EventEmitter(); + + dataSource: MatTableDataSource; + demandesFormationSubscription: Subscription; + demandesFormationCountSubscription: Subscription; + etatsDemandesSubscription: Subscription; + + constructor(private demandeFormationService: DemandesFormationService) {} + + ngOnInit() { + if(this.estAffichageEP) { + this.taille = this.demandesFormation.length; + this.dataSource = new MatTableDataSource(this.demandesFormation); + } + else + this.setBUsId(); + } + + emitEvent(demande: DemandesFormationsRoutingModule) { + if(this.eventEmitter != null) + this.eventEmitter.emit(demande); + } + + updateDataSource() { + if(this.busIds.length == 0 || this.etatsDemandes.length == 0 || this.statutsEp.length == 0) { + this.taille = 0; + this.dataSource = new MatTableDataSource(undefined); + return; + } + this.demandesFormationSubscription = this.demandeFormationService.getDemandesFormation(this.etatsDemandes, this.busIds, this.statutsEp, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe( + demandesFormation => this.dataSource = new MatTableDataSource(demandesFormation), + err => console.log(err) + ); + + this.demandesFormationCountSubscription = this.demandeFormationService.getDemandesFormationCount(this.etatsDemandes, this.busIds, this.statutsEp, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe( + count => this.taille = count, + err => console.log(err) + ); + } + + afficherDemandeRH(demandeRH: boolean) { + if (demandeRH) + return 'Oui'; + else + return 'Non' + } + + afficherEtat(etat: EtatDemande) { + return afficherEtatDemande(etat); + } + + /** + * création de la liste des business unit du collaborateur connecté pour afficher les checkboxes + */ + setBUsId() { + if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){ + setTimeout( () => this.setBUsId(), 1000); + } + else { + const collaborateurConnecte : CollaborateurDTO = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee)); + this.bus = collaborateurConnecte.businessUnit.agence.bu; + for(let bu of this.bus) { + this.busIds.push(bu.id); + } + this.updateDataSource(); + this.chargement = false; + } + } + + setSearch() { + this.numPage = 1; + this.updateDataSource(); + } + + resetSearch() { + this.search = ""; + this.setSearch(); + } + + /** + * Trier le tableau en fonction de l'évènement de la colonne + * @param e évènement du tri + */ + triTableau(e) { + this.tri = e.active; + switch(e.direction) { + case "asc": + this.asc = true; + break; + case "desc": + this.asc = false; + break; + } + this.updateDataSource(); + } + + /** + * Mettre à jour le nombre d'élément à afficher par page et le numéro de la page + * @param event évènement de la pagination + */ + updatePageInfo(event){ + this.parPage = event.pageSize; + this.numPage = event.pageIndex+1; + this.updateDataSource(); + } + + /** + * Mettre à jour toutes les checkbox des états d'engagement + * @param event case cochée ou décochée + */ + updateAllEtatsDemande(event) { + this.etatsDemandes = []; + // si la checkbox a été cochée + if(event) + this.etatsDemandes = this.etatsDemandesAffiches.map(e => e); + else + this.etatsDemandes = []; + + this.setSearch(); + } + + /** + * Mettre à jour la liste des etats de demande + * @param event + * @param etat + */ + updateEtatsDemande(event:boolean, etat:EtatDemande) { + if(event) { + this.etatsDemandes.push(etat); + } + else + this.etatsDemandes = this.etatsDemandes.filter( e => etat != e); + this.setSearch(); + } + + getStatutsEpEnCours() { + return [ StatutEp.AttenteEntretien, StatutEp.DatesProposees, + StatutEp.Disponible, StatutEp.Effectue, + StatutEp.Saisi, StatutEp.SignatureReferent ]; + } + + /** + * Mettre à jour toutes les checkbox des statuts d'EP + * @param event case cochée ou décochée + */ + updateAllStatutsEp(event) { + this.statutsEp = []; + // si la checkbox a été cochée + if(event) + this.statutsEp = this.allStatutsEp; + else + this.statutsEp = []; + + this.setSearch(); + } + + /** + * Mettre à jour la liste des statuts d'EP + * @param event + * @param statutEpAffiche + */ + updateEt + updateStatutsEp(event:boolean, statutEpAffiche:string) { + if(event) { + this.addStatutsEp(statutEpAffiche); + } + else { + this.removeStatutsEp(statutEpAffiche); + } + this.setSearch(); + } + + addStatutsEp(statutEpAffiche:string) { + switch(statutEpAffiche) { + case "Annulé": + this.statutsEp.push(StatutEp.Annule); + break; + case "En cours": + const statutsEpEnCoursOuCree = this.allStatutsEp.filter(s => estEPEnCours(s) || s == StatutEp.Cree); + this.statutsEp = this.statutsEp.concat(statutsEpEnCoursOuCree); + break; + case "Rejeté": + this.statutsEp.push(StatutEp.Rejete); + break; + case "Signé": + this.statutsEp.push(StatutEp.Signe); + break; + } + } + + removeStatutsEp(statutEpAffiche:string) { + switch(statutEpAffiche) { + case "Annulé": + this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Annule) + break; + case "En cours": + this.statutsEp = this.statutsEp.filter(s => !estEPEnCours(s) && s != StatutEp.Cree) + break; + case "Rejeté": + this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Rejete) + break; + case "Signé": + this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Signe) + break; + } + } + + + /** + * Mettre à jour toutes les checkbox des BU + * @param event case cochée ou décochée + */ + updateAllBUs(event) { + this.busIds = []; + // si la checkbox a été cochée + if(event) + this.bus.map(bu => this.busIds.push(bu.id)); + else + this.busIds = []; + + this.setSearch(); + } + + updateBUs(event, bu) { + // si la checkbox a été cochée + if(event) { + this.busIds.push(bu.id) + } + else{ + this.busIds = this.busIds.filter( (id) => id != bu.id); + } + this.setSearch(); + } + + /** + * Mettre à undefined la date de début ou la date de fin + * @param val Valeur pour indiquer quel variable doit être mis à undefined + */ + updateDateToUndefined(val : number) { + if(val == 1) + this.dateDebut = undefined; + if(val == 2) + this.dateFin = undefined; + this.updateDataSource(); + } + + + ngOnDestroy() { + if(this.demandesFormationSubscription != undefined) { + this.demandesFormationSubscription.unsubscribe(); + } + if(this.demandesFormationCountSubscription != undefined) { + this.demandesFormationCountSubscription.unsubscribe(); + } + } +} diff --git a/src/app/shared/mat-tables/mat-tables.module.ts b/src/app/shared/mat-tables/mat-tables.module.ts index 7a204d8..bed0477 100644 --- a/src/app/shared/mat-tables/mat-tables.module.ts +++ b/src/app/shared/mat-tables/mat-tables.module.ts @@ -10,6 +10,7 @@ import { FormationsTableComponent } from "@shared/mat-tables/formations-table/fo import { ParticipationsFormationTableComponent } from "@shared/mat-tables/participations-formation-table/participations-formation.table"; import { FilterModule } from "@shared/filter/filter.module"; import { EpTableComponent } from "./ep-table/ep-table"; +import { DemandesFormationTableComponent } from "@shared/mat-tables/demandes-formation-table/demandes-formation.table"; @NgModule({ @@ -18,7 +19,8 @@ import { EpTableComponent } from "./ep-table/ep-table"; EngagementTableComponent, FormationsTableComponent , EpTableComponent, - ParticipationsFormationTableComponent + ParticipationsFormationTableComponent, + DemandesFormationTableComponent ], imports: [ MaterialModule, @@ -32,7 +34,8 @@ import { EpTableComponent } from "./ep-table/ep-table"; EngagementTableComponent, FormationsTableComponent, EpTableComponent, - ParticipationsFormationTableComponent + ParticipationsFormationTableComponent, + DemandesFormationTableComponent ] }) export class MatTablesModule {}