diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0475665..8118234 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -27,6 +27,7 @@ import { AuthModule } from '@shared/auth/auth.module'; import { MatTablesModule } from "@shared/mat-tables/mat-tables.module"; import { EngagementsModule } from './engagements'; import { NotesModule } from './notes'; +import { FilterModule } from "@shared/filter/filter.module"; @NgModule({ declarations: [ @@ -39,10 +40,9 @@ import { NotesModule } from './notes'; HomeModule, CollaborateursModule, ReferentsModule, FormationsModule, DemandesFormationModule, DemandesDelegationModule, - EpSaisieModule, EpModule, MatTablesModule, - AffichageDetailsCollaborateurModule, EngagementsModule, - NotesModule - + EpSaisieModule, NotesModule, EpModule, + MatTablesModule, FilterModule, + AffichageDetailsCollaborateurModule, EngagementsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/formations/formations.component.html b/src/app/formations/formations.component.html index a70b540..53d3f5b 100644 --- a/src/app/formations/formations.component.html +++ b/src/app/formations/formations.component.html @@ -1,42 +1,4 @@

Liste des formations

- - - - Intitulé - {{ row.intitule }} - - - - Nb participants - {{ row.nbParticipants }} - - - - Date prévisionnelle - {{ row.dateDebut | date:'dd/MM/yy à hh:mm' }} - - - - Origine - {{ row.origine.libelle}} - - - - Statut - {{row.statut.libelle}} - - - - - - - - + \ No newline at end of file diff --git a/src/app/formations/formations.component.ts b/src/app/formations/formations.component.ts index 6635e80..bf31dcd 100644 --- a/src/app/formations/formations.component.ts +++ b/src/app/formations/formations.component.ts @@ -1,13 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; - -import { Observable, Subscription } from 'rxjs'; - -import {MatTableDataSource} from '@angular/material/table'; -import {MatPaginator, PageEvent} from '@angular/material/paginator'; -import {MatSort} from '@angular/material/sort'; - -import { FormationDetailsDTO } from "@shared/api-swagger/model/models"; -import { FormationsService } from "@shared/api-swagger/api/api"; +import { Component } from '@angular/core'; /** */ @@ -15,96 +6,16 @@ import { FormationsService } from "@shared/api-swagger/api/api"; selector: 'app-formations', templateUrl: './formations.component.html' }) -export class FormationsComponent implements OnInit { - +export class FormationsComponent { /** - * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà). + * Liste des colonnes du tableau à afficher. */ - asc = true; - /** - * Numéro de la page à afficher dans le tableau. - */ - numPage = 1; - /** - * Nombre d'élément du tableau à affiche en une page. - */ - parPage = 5; - - etat = 0; - - - /** - * Observable permettant de faire des requêtes sur le service formation. - */ - private formationsDisponiblesSubscription : Subscription; - - //displayedColumns: string[] = ["intitule", "participants", "date", "origine", "statut"] - /** - * Les colonnes à afficher dans le Mat Table - */ - displayedColumns: string[] = ["intitule", "origine", "participants", "date", "statut"] - - /** - * source pour l'affichage des formations dans le tableau qui est affichée. - */ - dataSource : MatTableDataSource; + displayedColumns: string[] = ["intitule", "origine", "participants", "date", "statut","certification"]; /** - * contenu de la recherche. - */ - search = ""; - tri = ""; - - - taille = 100; - - pageOption = [ 5, 15, 20, 30, 50]; - - pageEvent: PageEvent; - /** - * Pagination du tableau. - */ - @ViewChild(MatPaginator) paginator: MatPaginator; - - /** - * Tri par les éléments du tableau selon la colonne choisie. - */ - @ViewChild(MatSort) sort: MatSort; - - /** - * Spécifie si la liste des EP est en cours de chargement et d'écriture dans le tableau. - */ - chargement = true; - - constructor(private service:FormationsService) { - } - - ngOnInit() { - this.updateDataSource(); - } - - updateDataSource() { - this.formationsDisponiblesSubscription = this.service.getFormations(1,[1,2,3,4], this.asc,this.numPage, this.parPage, this.search, this.tri).subscribe( - formations => this.dataSource = new MatTableDataSource(formations), - err => console.log(err) - ); - //this.dataSource.paginator = this.paginator; - //this.dataSource.sort = this.sort; - } - - updatePageInfo(event) : PageEvent{ - console.log("update") - console.log(event); - this.parPage = event.pageSize; - this.numPage = event.pageIndex+1; - this.updateDataSource(); - return event; - } - - ngOnDestroy() { - if(this.formationsDisponiblesSubscription != undefined) { - this.formationsDisponiblesSubscription.unsubscribe(); - } - } + * Indique si la recherche par statut de formation est activée ou non + */ + rechercherParStatutFormation: boolean = true; + } diff --git a/src/app/formations/formations.module.ts b/src/app/formations/formations.module.ts index 427d569..c6ac76e 100644 --- a/src/app/formations/formations.module.ts +++ b/src/app/formations/formations.module.ts @@ -5,6 +5,7 @@ import { RouterModule } from '@angular/router'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MaterialModule } from "@shared/angular-material/angular-material.module"; +import { MatTablesModule } from "@shared/mat-tables/mat-tables.module"; import {NavMenuModule} from '@shared/nav-menu/nav-menu.module'; @@ -29,6 +30,7 @@ import { FormationsRoutingModule } from './formations.routing.module'; CommonModule, MaterialModule, NavMenuModule, + MatTablesModule, RouterModule, FormationsRoutingModule, ReactiveFormsModule diff --git a/src/app/home/home-rh/home-rh.component.html b/src/app/home/home-rh/home-rh.component.html index 725b7ef..c673d9a 100644 --- a/src/app/home/home-rh/home-rh.component.html +++ b/src/app/home/home-rh/home-rh.component.html @@ -1,47 +1,3 @@

Page RH

- - - - Intitulé - {{ row.intitule }} - - - - Nb participants - {{ row.nbParticipants }} - - - - Date prévisionnelle - {{ row.dateDebut | date:'dd/MM/yyyy à hh:mm' }} - - - - Origine - {{row.origine.libelle}} - - - - Statut - {{row.statut.libelle}} - - - - Certifiée - {{estCertifiee(row.estCertifiee)}} - - - - - - - - - + \ No newline at end of file diff --git a/src/app/home/home-rh/home-rh.component.ts b/src/app/home/home-rh/home-rh.component.ts index 6cf56ec..1ad0e48 100644 --- a/src/app/home/home-rh/home-rh.component.ts +++ b/src/app/home/home-rh/home-rh.component.ts @@ -1,12 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; - -import { Observable, Subscription } from 'rxjs'; - -import {MatTableDataSource} from '@angular/material/table'; -import {MatPaginator, PageEvent} from '@angular/material/paginator'; -import {MatSort} from '@angular/material/sort'; -import { FormationDetailsDTO } from "@shared/api-swagger/model/models"; -import { FormationsService } from "@shared/api-swagger/api/api"; +import { Component } from '@angular/core'; /** @@ -19,107 +11,19 @@ import { FormationsService } from "@shared/api-swagger/api/api"; selector : 'home-rh', templateUrl : 'home-rh.component.html' }) -export class HomeRHComponent implements OnInit { +export class HomeRHComponent { + /** - * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà). - */ - asc = true; - /** - * Numéro de la page à afficher dans le tableau. - */ - numPage = 1; - /** - * Nombre d'élément du tableau à affiche en une page. - */ - parPage = 15; - /** - * Permet d'indiquer au serveur sur quel attribut de l'objet CollaborateurDTO on souhaite faire le tri + * Liste des colonnes du tableau à afficher. */ - tri = ""; - - taille = 100; - - pageOption = [ 5, 15, 20, 30, 50]; + displayedColumns: string[] = ["intitule", "origine", "participants", "date", "statut","certification"]; - pageEvent: PageEvent; - - /** - * Observable pour faire des requêtes sur le service formation. - */ - private formationsDisponiblesSubscription : Subscription; /** - * Colonnes du tableau à afficher - */ - displayedColumns: string[] = ["intitule", "origine", "participants", "date", "statut","certification"]; - //displayedColumns: string[] = ["intitule", "participants", "date", "origine", "statut"] - //displayedColumns: string[] = ["intitule", "participants", "date", "statut","certification"]; + * Indique si la recherche par statut de formation est activée ou non + */ + rechercherParStatutFormation: boolean = true; + + constructor() {} - /** - * source pour l'affichage des formations dans le tableau Mat Table. - */ - dataSource : MatTableDataSource; - - /** - * contenu de la recherche. - */ - search = ""; - - /** - * Pagination du tableau. - */ - @ViewChild(MatPaginator) paginator: MatPaginator; - - /** - * Tri par les éléments du tableau selon la colonne choisie. - */ - @ViewChild(MatSort) sort: MatSort; - - /** - * Spécifie si la liste des EP est en cours de chargement et d'écriture dans le tableau. - */ - chargement = true; - constructor(private service:FormationsService) { - } - - ngOnInit() { - this.updateFormations(); - } - - /** - * Mettre à jour les informations à afficher dans la tableau. - * Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche. - */ - updateFormations() { - console.log(this.numPage); - console.log(this.parPage); - this.formationsDisponiblesSubscription = this.service.getFormations(1,[1,2],this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe( - formations => this.dataSource = new MatTableDataSource(formations), - err => console.log(err) - ) - } - - estCertifiee(certifiee: boolean) { - if(certifiee) - return "Oui"; - return "Non"; - } - - updatePageInfo(event) : PageEvent{ - console.log("update") - console.log(event); - this.parPage = event.pageSize; - this.numPage = event.pageIndex+1; - this.updateFormations(); - return event; - } - - /** - * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires. - */ - ngOnDestroy() { - if(this.formationsDisponiblesSubscription != undefined) { - this.formationsDisponiblesSubscription.unsubscribe(); - } - } } diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts index c43375e..8be69f1 100644 --- a/src/app/home/home.module.ts +++ b/src/app/home/home.module.ts @@ -4,6 +4,7 @@ import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; import { MaterialModule } from "@shared/angular-material/angular-material.module"; +import { MatTablesModule } from "@shared/mat-tables/mat-tables.module"; import {HomeAssistanteComponent} from './home-assistante/home-assistante.component'; import {HomeRHComponent} from './home-rh/home-rh.component'; @@ -30,6 +31,7 @@ import {NavMenuModule} from '@shared/nav-menu/nav-menu.module'; FormsModule, MaterialModule, NavMenuModule, + MatTablesModule, RouterModule ], }) diff --git a/src/app/shared/angular-material/angular-material.module.ts b/src/app/shared/angular-material/angular-material.module.ts index 195bc88..94f722f 100644 --- a/src/app/shared/angular-material/angular-material.module.ts +++ b/src/app/shared/angular-material/angular-material.module.ts @@ -9,6 +9,7 @@ import {MatMenuModule} from '@angular/material/menu'; import {MatPaginatorModule} from '@angular/material/paginator'; import {MatTableModule} from '@angular/material/table'; import {MatSortModule} from '@angular/material/sort'; +import {MatListModule} from '@angular/material/list'; import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; import {MatTabsModule} from '@angular/material/tabs'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -36,7 +37,7 @@ import { NgxMatDatetimePickerModule, NgxMatTimepickerModule, NgxMatNativeDateMod MatInputModule, MatProgressSpinnerModule, MatTabsModule, MatFormFieldModule, NgxMatDatetimePickerModule, MatDatepickerModule, - NgxMatNativeDateModule, MatNativeDateModule, + NgxMatNativeDateModule, MatNativeDateModule, MatListModule, MatCheckboxModule, MatSelectModule, MatStepperModule, MatChipsModule, MatSnackBarModule, MatSlideToggleModule ], @@ -47,7 +48,7 @@ import { NgxMatDatetimePickerModule, NgxMatTimepickerModule, NgxMatNativeDateMod MatInputModule, MatProgressSpinnerModule, MatTabsModule, MatFormFieldModule, NgxMatDatetimePickerModule, MatDatepickerModule, - NgxMatNativeDateModule, MatNativeDateModule, + NgxMatNativeDateModule, MatNativeDateModule, MatListModule, MatCheckboxModule, MatSelectModule, MatStepperModule, MatChipsModule, MatSnackBarModule, MatSlideToggleModule ] diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.css b/src/app/shared/filter/checkbox-filter/checkbox-filter.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.html b/src/app/shared/filter/checkbox-filter/checkbox-filter.html new file mode 100644 index 0000000..b6d06dc --- /dev/null +++ b/src/app/shared/filter/checkbox-filter/checkbox-filter.html @@ -0,0 +1,14 @@ + + + + + Tout sélectionner + + + {{data[propertyValueName]}} + {{data}} + + + \ No newline at end of file diff --git a/src/app/shared/filter/checkbox-filter/checkbox-filter.ts b/src/app/shared/filter/checkbox-filter/checkbox-filter.ts new file mode 100644 index 0000000..e6ff222 --- /dev/null +++ b/src/app/shared/filter/checkbox-filter/checkbox-filter.ts @@ -0,0 +1,120 @@ +import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core"; + +import { SelectedElement } from "@shared/filter/selected-element"; + + + + +@Component({ + selector: "checkbox-filter", + templateUrl: "./checkbox-filter.html", + styleUrls: ["./checkbox-filter.css"] +}) +export class CheckboxFilterComponent implements OnInit, OnChanges { + + /** + * Liste des éléments sélectionnés + */ + elementsSelected: Array = []; + + /** + * Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non + */ + isPropertyValueName: boolean; + + /** + * Coche toutes les cases à cocher + */ + @Input() checkedAll: boolean; + + /** + * Source de données + */ + @Input() dataSource : Array; + + /** + * Nom de la propriété contenant la valeur à afficher + */ + @Input() propertyValueName: string; + + /** + * Booléen permettant de savoir si toutes les cases sont cochées ou non + */ + @Output() isSelectedAllEvent = new EventEmitter(); + + /** + * Elément sélectionné + */ + @Output() isSelectedEvent = new EventEmitter>(); + + + constructor() {} + + ngOnInit() { + this.isPropertyValueName = !this.propertyValueName ? false : true; + } + + ngOnChanges() { + if (this.dataSource.length > 0) { + this.checkElementhasProperty(); + this.selectedAllChecked(this.checkedAll); + } + } + + + /** + * Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière + * contient une valeur. + */ + checkElementhasProperty() { + if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName))) + throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'."); + } + + + /** + * Détermine si l'élément est présent dans la liste des éléments sélectionnés + * @param element + */ + exists(element) { + return this.elementsSelected.indexOf(element) > -1; + }; + + /** + * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent" + * @param event case "Tout Sélectionner" cochée ou décochée + */ + selectedAllChecked(event) { + this.isSelectedAllEvent.emit(event); + this.checkedAll = event; + this.elementsSelected = []; + + if(event) + this.dataSource.map(data => this.elementsSelected.push(data)); + } + + /** + * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent" + * @param event case cochée ou décochée par l'utilisateur + * @param data Valeur de la case cochée ou décochée + */ + selectedChecked = (event: any, data: T) => { + this.isSelectedEvent.emit({isSelected: event, selectedElement: data}); + + // si la checkbox a été cochée + if(event) + this.elementsSelected.push(data); + else + this.elementsSelected = this.elementsSelected.filter(element => element != data); + + // coche la case "Tout sélectionner" si tous les éléments sont cochés + this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false; + } + + /** + * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires. + */ + ngOnDestroy() { + } + } + \ No newline at end of file diff --git a/src/app/shared/filter/filter.module.ts b/src/app/shared/filter/filter.module.ts new file mode 100644 index 0000000..9d30ceb --- /dev/null +++ b/src/app/shared/filter/filter.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule} from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { MaterialModule } from "../angular-material/angular-material.module"; +import { CheckboxFilterComponent } from "@shared/filter/checkbox-filter/checkbox-filter"; +import { SelectFilterComponent } from "@shared/filter/select-filter/select-filter"; + + +@NgModule({ + declarations: [ + CheckboxFilterComponent, + SelectFilterComponent + ], + imports: [ + MaterialModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + RouterModule + ], + exports: [ + CheckboxFilterComponent, + SelectFilterComponent + ] +}) +export class FilterModule {} diff --git a/src/app/shared/filter/select-filter/select-filter.css b/src/app/shared/filter/select-filter/select-filter.css new file mode 100644 index 0000000..8eea0ab --- /dev/null +++ b/src/app/shared/filter/select-filter/select-filter.css @@ -0,0 +1,4 @@ +mat-select .mat-checkbox-layout, +mat-select .mat-checkbox-label { + width:100% !important; +} \ No newline at end of file diff --git a/src/app/shared/filter/select-filter/select-filter.html b/src/app/shared/filter/select-filter/select-filter.html new file mode 100644 index 0000000..d3bb6c6 --- /dev/null +++ b/src/app/shared/filter/select-filter/select-filter.html @@ -0,0 +1,11 @@ + + {{label}} + + Tout sélectionner + + {{data[propertyValueName]}} + {{data}} + + + + diff --git a/src/app/shared/filter/select-filter/select-filter.ts b/src/app/shared/filter/select-filter/select-filter.ts new file mode 100644 index 0000000..6b1d985 --- /dev/null +++ b/src/app/shared/filter/select-filter/select-filter.ts @@ -0,0 +1,116 @@ +import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core"; +import { SelectedElement } from "@shared/filter/selected-element"; + +@Component({ + selector: "select-filter", + templateUrl: "./select-filter.html", + styleUrls: ["./select-filter.css"] +}) +export class SelectFilterComponent implements OnInit, OnChanges { + + /** + * Liste des éléments sélectionnés + */ + elementsSelected: Array = []; + + /** + * Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non + */ + isPropertyValueName: boolean; + + /** + * Libellé qui est affiché dans la liste déroulante lorsqu'aucune valeur n'est sélectionnée + */ + @Input() label: string; + + /** + * Cocher toutes les cases à cocher + */ + @Input() checkedAll: boolean; + + /** + * Source de données + */ + @Input() dataSource : Array; + + /** + * Nom de la propriété contenant la valeur à afficher + */ + @Input() propertyValueName: string; + + /** + * Booléen permettant de savoir si toutes les cases sont cochées ou non + */ + @Output() isSelectedAllEvent = new EventEmitter(); + + /** + * Elément sélectionné + */ + @Output() isSelectedEvent = new EventEmitter>(); + + + constructor() {} + + ngOnInit() { + this.isPropertyValueName = !this.propertyValueName ? false : true; + } + + ngOnChanges() { + if (this.dataSource.length > 0) { + this.checkElementhasProperty(); + this.selectedAllChecked(this.checkedAll); + } + } + + + /** + * Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière + * contient une valeur. + */ + checkElementhasProperty() { + if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName))) + throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'."); + } + + /** + * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent" + * @param event case "Tout Sélectionner" cochée ou décochée + */ + selectedAllChecked(event) { + this.isSelectedAllEvent.emit(event); + this.checkedAll = event; + this.elementsSelected = []; + + if(event) + this.dataSource.map(data => this.elementsSelected.push(data)); + } + + /** + * Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent" + * @param isChecked case cochée ou décochée par l'utilisateur + * @param data Valeur de la case cochée ou décochée + */ + selectedChecked = (isChecked: boolean, data: T) => { + this.isSelectedEvent.emit({isSelected: isChecked, selectedElement: data}); + + if(isChecked) { + var index = this.elementsSelected.findIndex(element => element == data); + + if (index === -1) + this.elementsSelected.push(data); + } + else { + this.elementsSelected = this.elementsSelected.filter(element => element != data); + } + + // coche la case "Tout sélectionner" si tous les éléments sont cochés + this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false; + } + + /** + * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires. + */ + ngOnDestroy() { + } + } + \ No newline at end of file diff --git a/src/app/shared/filter/selected-element.ts b/src/app/shared/filter/selected-element.ts new file mode 100644 index 0000000..fd68bbe --- /dev/null +++ b/src/app/shared/filter/selected-element.ts @@ -0,0 +1,11 @@ +export interface SelectedElement { + /** + * Détermine si l'élément est sélectionné ou non + */ + isSelected: boolean; + + /** + * Element sélectionné + */ + selectedElement: T; +} \ No newline at end of file diff --git a/src/app/shared/mat-tables/formations-table/formations.table.css b/src/app/shared/mat-tables/formations-table/formations.table.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/shared/mat-tables/formations-table/formations.table.html b/src/app/shared/mat-tables/formations-table/formations.table.html new file mode 100644 index 0000000..ce58390 --- /dev/null +++ b/src/app/shared/mat-tables/formations-table/formations.table.html @@ -0,0 +1,84 @@ + + + + + + + + + + Rechercher une formation + + + + + + + + + + + + + Intitulé + {{ row.intitule }} + + + + Nb participants + {{ row.nbParticipations }} + + + + Date prévisionnelle + {{ row.dateDebut | date:'dd/MM/yyyy à hh:mm' }} + + + + Origine + {{row.origine.libelle}} + + + + + Statut + + + + {{row.statut.libelle}} + + + + Certifiée + {{estCertifiee(row.estCertifiee)}} + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/shared/mat-tables/formations-table/formations.table.ts b/src/app/shared/mat-tables/formations-table/formations.table.ts new file mode 100644 index 0000000..17ddf19 --- /dev/null +++ b/src/app/shared/mat-tables/formations-table/formations.table.ts @@ -0,0 +1,256 @@ +import { Component, Input, OnInit } from "@angular/core"; + +import { Subscription } from 'rxjs'; + +import {MatTableDataSource} from '@angular/material/table'; + +import { CollaborateurDTO, FormationDetailsDTO, StatutFormationDTO } from '@shared/api-swagger/model/models' +import { FormationsService } from "@shared/api-swagger/api/api"; +import { cles } from "@shared/utils/cles"; + + +@Component({ + selector: "formations-table", + templateUrl: "./formations.table.html", + styleUrls: ["./formations.table.css"] +}) +export class FormationsTableComponent implements OnInit { + + /** + * 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; + /** + * Observable pour faire des requêtes sur le service formation. + */ + private formationsDisponiblesSubscription : Subscription; + + /** + * Observable pour faire des requêtes sur le service formation. + */ + private formationsDisponiblesCountSubscription : Subscription; + + /** + * C'est dans cet objet que seront stockés les formations à afficher dans le Mat Table côté template. + */ + dataSource : MatTableDataSource; + + /** + * contenu de la recherche pour trouver une formation. + */ + search: string = ""; + /** + * Permet de savoir sur quelle attribut d'un FormationDetailsDTO doit être trié le tableau. + */ + tri: string = "intitule"; + + /** + * Id agence collaborateur connecté + */ + idAgence: number; + + /** + * Liste des statuts de formation + */ + statutsFormation: Array = []; + + /** + * Liste des id statuts à afficher + */ + private idStatuts: Array = []; + + /** + * Spécifie si les checkbox des statuts de formation sont toutes cochées ou non. + */ + isStatutsSelectedAll: boolean = false; + + /** + * Nombre total d'élément du tableau + */ + taille: number = 0; + + /** + * Options pour choisir le nombre de page à affiche + */ + pageOption = [ 5, 15, 20, 30, 50]; + + /** + * Spécifie si la liste des formations est en cours de chargement dans le tableau. + */ + chargement: boolean = true; + + /** + * Indique si la recherche par statut de formation est activée ou non + */ + @Input() rechercherParStatutFormation: boolean = false; + + /** + * Liste des colonnes du tableau à afficher. + */ + @Input() displayedColumns : string[]; + + private collaborateurConnecte : CollaborateurDTO; + + constructor(private formationsService: FormationsService) {} + + ngOnInit() { + this.getStatutsFormation(); + this.setCollaborateurConnecte(); + } + + /** + * Mettre à jour les informations à afficher dans la tableau. + * Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche. + */ + updateDataSource() { + this.updateFormations(); + } + + /** + * Récupère les statuts de formation + */ + getStatutsFormation() + { + this.formationsService.getStatutsFormation().subscribe( + statuts => this.statutsFormation = statuts, + err => console.log(err) + ); + } + + /** + * Mettre à jour les informations à afficher dans la tableau. + * Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche. + */ + updateFormations() { + this.formationsDisponiblesSubscription = this.formationsService.getFormations(this.idAgence,this.idStatuts,this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe( + formations => this.dataSource = new MatTableDataSource(formations), + err => console.log(err) + ) + + this.formationsDisponiblesCountSubscription = this.formationsService.getFormationsCount(this.idAgence,this.idStatuts,this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe( + count => this.taille=count, + err => console.log(err) + ); + } + + estCertifiee(certifiee: boolean) { + if(certifiee) + return "Oui"; + return "Non"; + } + + setCollaborateurConnecte() + { + if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){ + setTimeout( () => this.setCollaborateurConnecte(), 1000); + } + else { + this.collaborateurConnecte = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee)); + this.idAgence = this.collaborateurConnecte.businessUnit.agence.id; + this.updateDataSource(); + this.chargement = false; + } + } + + /** + * Mettre à jour le nomre 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(); + } + + + /** + * Remettre au début la liste lors d'une recherche via la barre de recherche + */ + setSearch() { + this.numPage = 1; + this.updateDataSource(); + } + + + /** + * Vider la barre de recherche et remettre le tableau à la première page + */ + 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 toutes les checkox + * @param event case cochée ou décochée + */ + updateAllCheckbox(event) { + this.idStatuts = []; + // si la checkbox a été cochée + if(event) + this.statutsFormation.map(statut => this.idStatuts.push(statut.id)); + else + this.idStatuts = []; + + this.numPage = 1; + this.updateDataSource(); + } + + + /** + * Mettre à jour la liste des checkox + * @param event case cochée ou décochée + * @param statut statut concerné par la checkbox cochée ou décochée + */ + updateCheckbox(event, statut) { + // si la checkbox a été cochée + if(event) { + this.idStatuts.push(statut.id) + } + else{ + this.idStatuts = this.idStatuts.filter(id => id != statut.id); + } + this.numPage = 1; + this.updateDataSource(); + } + + /** + * Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires. + */ + ngOnDestroy() { + if(this.formationsDisponiblesSubscription != undefined) { + this.formationsDisponiblesSubscription.unsubscribe(); + } + if(this.formationsDisponiblesCountSubscription != undefined) { + this.formationsDisponiblesCountSubscription.unsubscribe(); + } + } + } + \ No newline at end of file diff --git a/src/app/shared/mat-tables/mat-tables.module.ts b/src/app/shared/mat-tables/mat-tables.module.ts index d93ea50..94e3941 100644 --- a/src/app/shared/mat-tables/mat-tables.module.ts +++ b/src/app/shared/mat-tables/mat-tables.module.ts @@ -1,20 +1,32 @@ import { NgModule } from "@angular/core"; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; import { MaterialModule } from "../angular-material/angular-material.module"; import { CollaborateursTableComponent } from "@shared/mat-tables/collaborateurs-table/collaborateurs.table"; import { EngagementTableComponent } from "@shared/mat-tables/engagements-table/engagements-table" +import { FormationsTableComponent } from "@shared/mat-tables/formations-table/formations.table"; +import { FilterModule } from "@shared/filter/filter.module"; + @NgModule({ declarations: [ - CollaborateursTableComponent, EngagementTableComponent + CollaborateursTableComponent, + EngagementTableComponent, + FormationsTableComponent ], imports: [ MaterialModule, + FilterModule, CommonModule, - FormsModule + FormsModule, + RouterModule ], - exports: [CollaborateursTableComponent, EngagementTableComponent] + exports: [ + CollaborateursTableComponent, + EngagementTableComponent, + FormationsTableComponent + ] }) export class MatTablesModule {} diff --git a/src/environments/environment.ts b/src/environments/environment.ts index f325ab0..cfc67ff 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -18,7 +18,7 @@ const keycloakConfig: AuthConfig = { // is a sign that the auth server is not configured with SPAs in mind // and it might not enforce further best practices vital for security // such applications. - //dummyClientSecret: 'f27746f4-e603-441e-a256-3ddd5b19ba54', + //dummyClientSecret: 'b261c083-d8ba-4a7c-918e-9d13393f33bd', dummyClientSecret: '201a3d53-7cd5-4613-bcb6-f2e98c1ba2ec', // To configure your solution for code flow + PKCE you have to set the responseType to code