Bladeren bron

dev en cours

rajah 8 maanden geleden
bovenliggende
commit
15c37fae72

+ 18 - 3
src/app/app.config.ts

@@ -1,9 +1,24 @@
 import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
 import { provideRouter } from '@angular/router';
 import { routes } from './app.routes';
-import { provideHttpClient } from '@angular/common/http';
+import { provideClientHydration } from '@angular/platform-browser';
+import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
+import { provideHttpClient, withInterceptorsFromDi, HTTP_INTERCEPTORS } from '@angular/common/http';
 
-export const appConfig: ApplicationConfig = 
+import { AuthInterceptor } from './services/auth.interceptor';
+
+export const appConfig: ApplicationConfig =
 {
-  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient()]
+  providers: [
+    provideZoneChangeDetection({ eventCoalescing: true }),
+    provideRouter(routes),
+    provideClientHydration(),
+    provideAnimationsAsync(),
+    provideHttpClient(withInterceptorsFromDi()),
+    {
+      provide: HTTP_INTERCEPTORS,
+      useClass: AuthInterceptor,
+      multi: true
+    }
+  ]
 };

+ 28 - 27
src/app/app.routes.ts

@@ -4,12 +4,13 @@ import { NgModule } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import { Routes, RouterModule } from '@angular/router';
 
-//import { MenuComponent } from './composants/menu/menu.component';    
-import { HomeComponent } from './composants/home/home.component';    
-import { LoginComponent } from './composants/login/login.component';    
+import { HomeComponent } from './composants/home/home.component';
+import { LoginComponent } from './composants/login/login.component';
 import { AccountDetailsComponent } from './composants/account-details/account-details.component';
 import { AccountUpdateComponent } from './composants/account-update/account-update.component';
-//import { LoggedGuard } from './guards/logged.guard';    
+import { AdminGuard } from './guards/admin.guard';
+import { OrgaGuard } from './guards/orga.guard';
+import { UserGuard } from './guards/user.guard';
 import { VariableListComponent } from './composants/variable-list/variable-list.component';
 import { VariableCreateComponent } from './composants/variable-create/variable-create.component';
 import { VariableDetailsComponent } from './composants/variable-details/variable-details.component';
@@ -28,34 +29,34 @@ import { ProductionDetailsComponent } from './composants/production-details/prod
 import { ProductionUpdateComponent } from './composants/production-update/production-update.component';
 import { ProductionUploadComponent } from './composants/production-upload/production-upload.component';
 
-export const routes: Routes = [  
+export const routes: Routes = [
   {path: '', redirectTo: 'home', pathMatch: 'full'},
   {path: 'home', component: HomeComponent, runGuardsAndResolvers: 'always' },
   {path: 'login', component: LoginComponent, runGuardsAndResolvers: 'always' },
-  {path: 'account-details', component: AccountDetailsComponent, runGuardsAndResolvers: 'always' },
-  {path: 'account-update', component: AccountUpdateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'variable-list', component: VariableListComponent /*, canActivate: [LoggedGuard]*/, runGuardsAndResolvers: 'always'},
-  {path: 'variable-create', component: VariableCreateComponent /*, canActivate: [LoggedGuard]*/, runGuardsAndResolvers: 'always'},
-  {path: 'variable-details/:numeroVariable', component: VariableDetailsComponent /*, canActivate: [LoggedGuard]*/, runGuardsAndResolvers: 'always'},
-  {path: 'variable-update/:numeroVariable', component: VariableUpdateComponent /*, canActivate: [LoggedGuard]*/, runGuardsAndResolvers: 'always'},
-  {path: 'categorie-list', component: CategorieListComponent, runGuardsAndResolvers: 'always' },
-  {path: 'categorie-create', component: CategorieCreateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'categorie-details/:numeroCategorie', component: CategorieDetailsComponent, runGuardsAndResolvers: 'always' },
-  {path: 'categorie-update/:numeroCategorie', component: CategorieUpdateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'participant-list', component: ParticipantListComponent, runGuardsAndResolvers: 'always' },
-  {path: 'participant-create', component: ParticipantCreateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'participant-details/:numeroParticipant', component: ParticipantDetailsComponent, runGuardsAndResolvers: 'always' },
-  {path: 'participant-update/:numeroParticipant', component: ParticipantUpdateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'production-list', component: ProductionListComponent, runGuardsAndResolvers: 'always' },
-  {path: 'production-create', component: ProductionCreateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'production-details/:numeroProduction', component: ProductionDetailsComponent, runGuardsAndResolvers: 'always' },
-  {path: 'production-update/:numeroProduction', component: ProductionUpdateComponent, runGuardsAndResolvers: 'always' },
-  {path: 'production-upload/:numeroProduction', component: ProductionUploadComponent, runGuardsAndResolvers: 'always' },
+  {path: 'account-details', component: AccountDetailsComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'account-update', component: AccountUpdateComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'variable-list', component: VariableListComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always'},
+  {path: 'variable-create', component: VariableCreateComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always'},
+  {path: 'variable-details/:numeroVariable', component: VariableDetailsComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always'},
+  {path: 'variable-update/:numeroVariable', component: VariableUpdateComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always'},
+  {path: 'categorie-list', component: CategorieListComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always' },
+  {path: 'categorie-create', component: CategorieCreateComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always' },
+  {path: 'categorie-details/:numeroCategorie', component: CategorieDetailsComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always' },
+  {path: 'categorie-update/:numeroCategorie', component: CategorieUpdateComponent, canActivate: [AdminGuard], runGuardsAndResolvers: 'always' },
+  {path: 'participant-list', component: ParticipantListComponent, canActivate: [OrgaGuard], runGuardsAndResolvers: 'always' },
+  {path: 'participant-create', component: ParticipantCreateComponent, canActivate: [OrgaGuard], runGuardsAndResolvers: 'always' },
+  {path: 'participant-details/:numeroParticipant', component: ParticipantDetailsComponent, canActivate: [OrgaGuard], runGuardsAndResolvers: 'always' },
+  {path: 'participant-update/:numeroParticipant', component: ParticipantUpdateComponent, canActivate: [OrgaGuard], runGuardsAndResolvers: 'always' },
+  {path: 'production-list', component: ProductionListComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'production-create', component: ProductionCreateComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'production-details/:numeroProduction', component: ProductionDetailsComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'production-update/:numeroProduction', component: ProductionUpdateComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
+  {path: 'production-upload/:numeroProduction', component: ProductionUploadComponent, canActivate: [UserGuard], runGuardsAndResolvers: 'always' },
 ];
 
 @NgModule({
-  imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' }), BrowserModule, FormsModule],                                                                                                                                                                                                                                                                                                          
-  exports: [RouterModule]
+  imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' }), BrowserModule, FormsModule],
+  exports: [RouterModule],
 })
 
-export class AppRoutingModule { }
+export class AppRoutingModule { }

+ 4 - 4
src/app/composants/account-update/account-update.component.html

@@ -37,9 +37,9 @@
 		</div>
 
 		<div class="form-group row">
-			<label class="col-sm-4 col-form-label col-form-label-sm label-nobr">Pseudonyme&nbsp;<sup><span class="text-danger">*</span></sup></label>
+			<label class="col-sm-4 col-form-label col-form-label-sm label-nobr">Pseudonyme</label>
 			<div class="col-sm-8">
-				<input type="text" class="form-control form-control-sm field-separate" id="pseudonyme" name="pseudonyme" [(ngModel)]="participant.pseudonyme" #pseudonymeRef="ngModel" required [class.is-invalid]="pseudonymeRef.invalid && pseudonymeRef.touched">
+				<input type="text" class="form-control form-control-sm field-separate" id="pseudonyme" name="pseudonyme" [(ngModel)]="participant.pseudonyme" disabled>
 			</div>
 		</div>
 
@@ -155,7 +155,7 @@
 				<div class="col-sm-4"></div>
 				<div class="col-sm-8">
 					<div class="form-check form-switch">
-						<input class="form-check-input field-separate" type="checkbox" id="useAmigabus" name="useAmigabus" [(ngModel)]="participant.useAmigabus" disabled> 
+						<input class="form-check-input field-separate" type="checkbox" id="useAmigabus" name="useAmigabus" [(ngModel)]="participant.useAmigabus" disabled>
 						<label class="form-check-label" for="useAmigabus">Vient en Amigabus</label>
 					</div>
 				</div>
@@ -198,4 +198,4 @@
 		</div>
 	</div>
 </div>
-</div>
+</div>

+ 3 - 3
src/app/composants/categorie-list/categorie-list.component.ts

@@ -6,7 +6,7 @@ import { CategorieService } from '../../services/categorie.service';
 
 @Component({ selector: 'app-categorie-list', imports: [MenuComponent], templateUrl: './categorie-list.component.html', styleUrl: './categorie-list.component.css'})
 
-export class CategorieListComponent implements OnInit, AfterViewInit 
+export class CategorieListComponent implements OnInit, AfterViewInit
 {
 
   categories: Categorie[] = [];
@@ -19,8 +19,8 @@ export class CategorieListComponent implements OnInit, AfterViewInit
 
   private retreiveDatas() { this.categorieService.getListCategorie().subscribe(data => { this.categories = data; }); }
 
-  goToRefreshListCategorie(){ window.location.reload(); }
-  
+  goToRefreshListCategorie(){ this.retreiveDatas(); }
+
   goToNewCategorie(){ this.router.navigate(['/categorie-create']); }
 
   formCategorie(id: number) { this.router.navigate(['/categorie-details', id]); }

+ 10 - 1
src/app/composants/login/login.component.html

@@ -5,6 +5,14 @@
 		<div class="card-header">S'identifier</div>
 		<div class="card-body">
 
+			@if (this.identifiants.erreur !== "") {
+			<div class="form-group row">
+				<div class="col-sm-12 col-form-label col-form-label-sm">
+					<div class="alert alert-warning" role="alert">{{ this.identifiants.erreur }}</div>
+				</div>
+			</div>
+			}
+
 			<div class="form-group row">
 				<label class="col-sm-4 col-form-label col-form-label-sm label-nobr">Pseudonyme&nbsp;<sup><span class="text-danger">*</span></sup></label>
 				<div class="col-sm-8">
@@ -16,6 +24,7 @@
 				<label class="col-sm-4 col-form-label col-form-label-sm label-nobr">Mot de passe&nbsp;<sup><span class="text-danger">*</span></sup></label>
 				<div class="col-sm-8">
 					<input type="password" class="form-control form-control-sm field-separate" id="userpwd" name="userpwd" [(ngModel)]="identifiants.password" #passRef="ngModel" required [class.is-invalid]="passRef.invalid && passRef.touched">
+					<div class="form-text field-separate">Merci de contacter l'administrateur si vous l'avez oublié ou ne le connaissez pas.</div>
 				</div>
 			</div>
 
@@ -25,4 +34,4 @@
 		</div>
 	</div>
 </form>
-</div>
+</div>

+ 13 - 13
src/app/composants/menu/menu.component.html

@@ -9,7 +9,7 @@
 	</ul>
 </div>
 
-} @else if (this.logged && (this.role === "USER")) {		
+} @else if (this.logged && (this.role === "USER")) {
 
 <div class="d-flex flex-column flex-shrink-0 bg-body-tertiary" id="sidenav">
   <ul class="nav nav-pills nav-flush flex-column text-center">
@@ -18,9 +18,9 @@
 		<li><a routerLinkActive="active" data-bs-toggle="modal" data-bs-target="#modalDeconnecter" class="nav-link rounded-0 bg-gradient" tooltip="Logout" placement="right" container="body"><i class="fa-solid fa-right-from-bracket"></i></a></li>
 		<li><a routerLink="/event-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Planning" placement="right" container="body"><i class="fa-solid fa-clock"></i></a></li>
 		<li><a routerLink="/webcam-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Caméras" placement="right" container="body"><i class="fa-solid fa-eye"></i></a></li>
-		
+
 		<li><a routerLink="/chat" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Messagerie" placement="right" container="body"><i class="fa-solid fa-comments"></i></a></li>
-		
+
 		<li><a routerLink="/production-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Productions" placement="right" container="body"><i class="fa-solid fa-save"></i></a></li>
 
 		<li><a routerLink="/vote-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Voter" placement="right" container="body"><i class="fa-solid fa-vote-yea"></i></a></li>
@@ -29,7 +29,7 @@
 	</ul>
 </div>
 
-} @else if (this.logged && (this.role === "ORGA")) {		
+} @else if (this.logged && (this.role === "ORGA")) {
 
 <div class="d-flex flex-column flex-shrink-0 bg-body-tertiary" id="sidenav">
   <ul class="nav nav-pills nav-flush flex-column text-center">
@@ -38,18 +38,18 @@
 		<li><a routerLinkActive="active" data-bs-toggle="modal" data-bs-target="#modalDeconnecter" class="nav-link rounded-0 bg-gradient" tooltip="Logout" placement="right" container="body"><i class="fa-solid fa-right-from-bracket"></i></a></li>
 		<li><a routerLink="/event-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Planning" placement="right" container="body"><i class="fa-solid fa-clock"></i></a></li>
 		<li><a routerLink="/webcam-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Caméras" placement="right" container="body"><i class="fa-solid fa-eye"></i></a></li>
-		
+
 		<li><a routerLink="/chat" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Messagerie" placement="right" container="body"><i class="fa-solid fa-comments"></i></a></li>
-		
+
 		<li><a routerLink="/participant-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Participants" placement="right" container="body"><i class="fa-solid fa-users"></i></a></li>
-		
+
 		<li><a routerLink="/production-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Productions" placement="right" container="body"><i class="fa-solid fa-save"></i></a></li>
 		<li><a routerLink="/vote-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Voter" placement="right" container="body"><i class="fa-solid fa-vote-yea"></i></a></li>
 		<li><a routerLink="/result-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Résultats" placement="right" container="body"><i class="fa-solid fa-trophy"></i></a></li>
 	</ul>
 </div>
 
-} @else if (this.logged && (this.role === "ADMIN")) {		
+} @else if (this.logged && (this.role === "ADMIN")) {
 
 <div class="d-flex flex-column flex-shrink-0 bg-body-tertiary" id="sidenav">
   <ul class="nav nav-pills nav-flush flex-column text-center">
@@ -58,17 +58,17 @@
 		<li><a routerLinkActive="active" data-bs-toggle="modal" data-bs-target="#modalDeconnecter" class="nav-link rounded-0 bg-gradient" tooltip="Logout" placement="right" container="body"><i class="fa-solid fa-right-from-bracket"></i></a></li>
 		<li><a routerLink="/event-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Planning" placement="right" container="body"><i class="fa-solid fa-clock"></i></a></li>
 		<li><a routerLink="/webcam-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Caméras" placement="right" container="body"><i class="fa-solid fa-eye"></i></a></li>
-		
+
 		<li><a routerLink="/chat" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Messagerie" placement="right" container="body"><i class="fa-solid fa-comments"></i></a></li>
-		
+
 		<li><a routerLink="/participant-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Participants" placement="right" container="body"><i class="fa-solid fa-users"></i></a></li>
-		
+
 		<li><a routerLink="/categorie-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Catégories" placement="right" container="body"><i class="fa-solid fa-layer-group"></i></a></li>
 		<li><a routerLink="/production-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Productions" placement="right" container="body"><i class="fa-solid fa-save"></i></a></li>
 		<li><a routerLink="/show-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Présentations" placement="right" container="body"><i class="fa-solid fa-display"></i></a></li>
 		<li><a routerLink="/poll-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Voter" placement="right" container="body"><i class="fa-solid fa-vote-yea"></i></a></li>
 		<li><a routerLink="/result-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Résultats" placement="right" container="body"><i class="fa-solid fa-trophy"></i></a></li>
-		
+
 		<li><a routerLink="/variable-list" routerLinkActive="active" class="nav-link rounded-0 bg-gradient" tooltip="Paramétrages" placement="right" container="body"><i class="fa-solid fa-sliders-h"></i></a></li>
 	</ul>
 </div>
@@ -87,4 +87,4 @@
 		</div>
 	</div>
 </div>
-}
+}

+ 17 - 15
src/app/composants/menu/menu.component.ts

@@ -1,29 +1,31 @@
-import { Injectable, Component, OnInit } from '@angular/core';
+import { Injectable, Component, OnInit, AfterViewInit } from '@angular/core';
 import { Router, RouterLink, RouterLinkActive } from '@angular/router';
-import { AccountService } from '../../services/account.service';  
-import { TooltipModule } from 'ngx-bootstrap/tooltip'; 
+import { AccountService } from '../../services/account.service';
+import { TooltipModule } from 'ngx-bootstrap/tooltip';
 
 @Component({ selector: 'app-menu', imports: [TooltipModule, RouterLink, RouterLinkActive], templateUrl: './menu.component.html', styleUrl: './menu.component.css' })
 
 @Injectable({ providedIn: 'root' })
 
-export class MenuComponent implements OnInit 
+export class MenuComponent implements OnInit, AfterViewInit
 {
 
   logged: boolean = false;
-  
-  role: String = "";
-
-  constructor(private router: Router, private accountService: AccountService) {  }  
-  
-  ngOnInit() 
-  { 
-    this.logged = this.accountService.isLogged(); 
+
+  role: string = "";
+
+  constructor(private router: Router, private accountService: AccountService) {  }
+
+  ngOnInit()
+  {
+    this.logged = this.accountService.isLogged();
     this.role = this.accountService.getRole();
   }
-  
-  deconnexion() { this.accountService.signOut(); window.location.reload(); } 
-  
+
+  ngAfterViewInit() { }
+
+  deconnexion() { this.accountService.signOut(); if ((this.router.url === '/') || (this.router.url === '/home')) { window.location.reload(); } else { this.router.navigate(['/']); }  }
+
   getRandomInteger(min: number, max: number) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; }
 
 }

+ 34 - 12
src/app/composants/participant-list/participant-list.component.html

@@ -3,12 +3,34 @@
 <div class="card shadow">
 	<div class="card-header">Table des participants</div>
 	<div class="card-header shadow-sm">
-		<div class="row">
+		<div class="row justify-content-between">
 			<div class="form-group col-sm-4 label-nobr">
-				<button type="button" (click)="goToRefreshListParticipant()" class="btn bg-gradient btn-primary btn-sm" style="margin-right: 5px;"><i class="fa-solid fa-rotate"></i>&nbsp;Actualiser</button>
-				<button type="button" (click)="goToNewParticipant()" class="btn bg-gradient btn-primary btn-sm" style="margin-right: 5px;"><i class="fa-solid fa-plus"></i>&nbsp;Créer</button>
+				<button type="button" (click)="goToRefreshListParticipant()" class="btn bg-gradient btn-primary btn-sm field-separate" style="margin-right: 5px;"><i class="fa-solid fa-rotate"></i>&nbsp;Actualiser</button>
+				<button type="button" (click)="goToNewParticipant()" class="btn bg-gradient btn-primary btn-sm field-separate" style="margin-right: 5px;"><i class="fa-solid fa-plus"></i>&nbsp;Créer</button>
 			</div>
-		</div>
+			<div class="form-group col-sm-2">
+				<div class="input-group input-group-sn">
+					<button type="button" (click)="filtrageParNom()" class="btn bg-gradient btn-primary btn-sm field-separate"><i class="fa-solid fa-filter"></i>&nbsp;Filtrer</button>
+					<input type="text" (keydown.enter)="filtrageParNom()" class="form-control form-control-sm field-separate" id="input_nom" [(ngModel)]="nomFiltre" tooltip="Filtrer par nom, prenom ou pseudonyme" placement="bottom">
+			  </div>
+			</div>
+			<div class="form-group col-sm-2">
+				<select class="form-select form-select-sm field-separate" id="select_statut" [(ngModel)]="statutFiltre" (change)="filtrageParStatut($event)" tooltip="Filtrer selon le status" placement="bottom">
+					<option value="0">Tout statut</option>
+					<option value="1">Non réglé(s)</option>
+				</select>
+			</div>
+			<div class="form-group col-sm-2">
+				<select class="form-select form-select-sm field-separate" id="select_arrive" [(ngModel)]="arriveFiltre" (change)="filtrageParArrive($event)" tooltip="Filtrer selon l'arrivage" placement="bottom">
+					<option value="0">Tous</option>
+					<option value="1">Non arrivé(s)</option>
+					<option value="2">Arrivé(s)</option>
+				</select>
+			</div>
+			<div class="form-group col-sm-2">
+				<button type="button" (click)="filtrageReset()" class="btn bg-gradient btn-secondary btn-sm field-separate"><i class="fa-solid fa-filter-circle-xmark"></i>&nbsp;Retirer les filtres</button>
+			</div>
+   	</div>
 	</div>
 	<div class="card-body">
 		<table class="table table-sm">
@@ -29,15 +51,15 @@
 					<td class="label-nobr text-truncate" style="max-width:200px;"><a (click)="formParticipant(participant.numeroParticipant)" class="link-primary pointeur-souris text-decoration-none">{{ participant.pseudonyme }}</a>@if (participant.groupe) { / {{ participant.groupe }} }&nbsp;&nbsp;</td>
 					<td>
 					  @if (participant.statut === PS[0].key) { <i class="fa-solid fa-circle-xmark text-danger" title="{{ PS[0].value }}"></i> }
-					  @else if (participant.statut === PS[1].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[1].value }}"></i> }  
-					  @else if (participant.statut === PS[2].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[2].value }}"></i> }  
-					  @else if (participant.statut === PS[3].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[3].value }}"></i> }  
-					  @else if (participant.statut === PS[4].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[4].value }}"></i> }  
-					  @else if (participant.statut === PS[5].key) { <i class="fa-solid fa-circle-check text-primary" title="{{ PS[5].value }}"></i> }  
-					  @else if (participant.statut === PS[6].key) { <i class="fa-solid fa-circle-check text-primary" title="{{ PS[6].value }}"></i> } 
+					  @else if (participant.statut === PS[1].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[1].value }}"></i> }
+					  @else if (participant.statut === PS[2].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[2].value }}"></i> }
+					  @else if (participant.statut === PS[3].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[3].value }}"></i> }
+					  @else if (participant.statut === PS[4].key) { <i class="fa-solid fa-circle-check text-success" title="{{ PS[4].value }}"></i> }
+					  @else if (participant.statut === PS[5].key) { <i class="fa-solid fa-circle-check text-primary" title="{{ PS[5].value }}"></i> }
+					  @else if (participant.statut === PS[6].key) { <i class="fa-solid fa-circle-check text-primary" title="{{ PS[6].value }}"></i> }
 					</td>
 					<td>
-					  @if (participant.arrived) { <i class="fa-solid fa-circle-check text-success"></i> } 
+					  @if (participant.arrived) { <i class="fa-solid fa-circle-check text-success"></i> }
 					  @else { <i class="fa-solid fa-circle-xmark text-danger"></i> }&nbsp;&nbsp;
 					</td>
 					<td>{{ getNombreJours(participant.hereDay1, participant.hereDay2, participant.hereDay3) }} @if(participant.sleepingOnSite) { + <i class="fa-solid fa-bed"></i> }</td>
@@ -48,4 +70,4 @@
 		</table>
 	</div>
 </div>
-</div>
+</div>

+ 26 - 13
src/app/composants/participant-list/participant-list.component.ts

@@ -3,12 +3,18 @@ import { Router } from '@angular/router';
 import { MenuComponent } from '../menu/menu.component';
 import { ParticipantList, ParticipantEnum, ParticipantStatutList } from '../../interfaces/participant';
 import { ParticipantService } from '../../services/participant.service';
+import { FormsModule, NgForm } from '@angular/forms';
+import { TooltipModule } from 'ngx-bootstrap/tooltip';
 
-@Component({ selector: 'app-participant-list', imports: [MenuComponent], templateUrl: './participant-list.component.html', styleUrl: './participant-list.component.css' })
+@Component({ selector: 'app-participant-list', imports: [TooltipModule, FormsModule, MenuComponent], templateUrl: './participant-list.component.html', styleUrl: './participant-list.component.css' })
 
 export class ParticipantListComponent implements OnInit, AfterViewInit
 {
-    
+
+  nomFiltre: string = "";
+  statutFiltre: number = 0;
+  arriveFiltre: number = 0;
+
   PS: ParticipantEnum[] = ParticipantStatutList;
 
   participants: ParticipantList[] = [];
@@ -16,23 +22,30 @@ export class ParticipantListComponent implements OnInit, AfterViewInit
   constructor(private participantService: ParticipantService, private router: Router) { }
 
   ngOnInit(): void { this.retreiveDatas(); }
-  
+
   ngAfterViewInit() { }
 
-  private retreiveDatas() { this.participantService.getListParticipant().subscribe(data => { this.participants = data; }); }
+  private retreiveDatas() { this.participantService.getListParticipant(this.nomFiltre, this.statutFiltre, this.arriveFiltre).subscribe(data => { this.participants = data; }); }
 
-  getNombreJours(j1: boolean, j2: boolean, j3: boolean) 
-  { 
-    var nbjours: number = 0; 
-    if (j1) { nbjours++; } 
-    if (j2) { nbjours++; } 
-    if (j3) { nbjours++; } 
+  getNombreJours(j1: boolean, j2: boolean, j3: boolean)
+  {
+    var nbjours: number = 0;
+    if (j1) { nbjours++; }
+    if (j2) { nbjours++; }
+    if (j3) { nbjours++; }
   	return nbjours;
   }
-  
-  goToRefreshListParticipant(){ window.location.reload(); }
 
-  goToNewParticipant(){ this.router.navigate(['/participant-create']); }
+  goToRefreshListParticipant() { this.retreiveDatas(); }
+
+  goToFiltrage() { this.retreiveDatas(); }
+
+  filtrageParNom() { this.retreiveDatas(); }
+  filtrageParStatut(event: any) { this.statutFiltre = event.target.value; this.retreiveDatas(); }
+  filtrageParArrive(event: any) { this.arriveFiltre = event.target.value; this.retreiveDatas(); }
+  filtrageReset() { this.nomFiltre = ""; this.statutFiltre = 0; this.arriveFiltre = 0; this.retreiveDatas(); }
+
+  goToNewParticipant() { this.router.navigate(['/participant-create']); }
 
   formParticipant(id: number) { this.router.navigate(['/participant-details', id]); }
 

+ 1 - 1
src/app/composants/production-list/production-list.component.html

@@ -32,4 +32,4 @@
 		</div>
 	}
 </div>
-</div>
+</div>

+ 5 - 6
src/app/composants/production-list/production-list.component.ts

@@ -4,13 +4,12 @@ import { MenuComponent } from '../menu/menu.component';
 import { ProductionShort, ProductionEnum, ProductionTypeList } from '../../interfaces/production';
 import { ProductionService } from '../../services/production.service';
 import { saveAs } from 'file-saver';
-import { TooltipModule } from 'ngx-bootstrap/tooltip'; 
+import { TooltipModule } from 'ngx-bootstrap/tooltip';
 
 @Component({ selector: 'app-production-list', imports: [TooltipModule, MenuComponent], templateUrl: './production-list.component.html', styleUrl: './production-list.component.css' })
 
 export class ProductionListComponent implements OnInit, AfterViewInit
 {
-  
   productions: ProductionShort[] = [];
 
   types: ProductionEnum[] = ProductionTypeList;
@@ -18,19 +17,19 @@ export class ProductionListComponent implements OnInit, AfterViewInit
   constructor(private productionService: ProductionService, private router: Router) { }
 
   ngOnInit() { this.retreiveDatas(); }
-  
+
   ngAfterViewInit() { }
 
   private retreiveDatas() { this.productionService.getListProduction().subscribe(data => { this.productions = data; }); }
 
-  goToRefreshListProduction(){ window.location.reload(); }
+  goToRefreshListProduction(){ this.retreiveDatas(); }
 
   goToNewProduction(){ this.router.navigate(['/production-create']); }
 
   formProduction(id: number) { this.router.navigate(['/production-details', id]); }
 
   getFile(id: number, nom: string) { this.productionService.getProductionFile(id).subscribe(response => { this.saveFile(response.body, nom); }); }
-  
+
   saveFile(data: any, filename?: string) { const blob = new Blob([data], {type: 'application/zip'}); saveAs(blob, filename); }
-  
+
 }

+ 8 - 8
src/app/composants/variable-details/variable-details.component.ts

@@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router';
 import { MenuComponent } from '../menu/menu.component';
 import { Variable } from '../../interfaces/variable';
 import { VariableService } from '../../services/variable.service';
-import { FormsModule } from '@angular/forms'; 
+import { FormsModule } from '@angular/forms';
 
 @Component({ selector: 'app-variable-details', imports: [FormsModule, MenuComponent], templateUrl: './variable-details.component.html', styleUrl: './variable-details.component.css' })
 
@@ -13,20 +13,20 @@ export class VariableDetailsComponent implements OnInit, AfterViewInit
   numeroVariable: number = 0;
 
   variable: Variable = new Variable();
-  
-  constructor(private variableService: VariableService, private route: ActivatedRoute, private router: Router) { }
 
-  ngOnInit(): void 
+  constructor(private variableService: VariableService, private route: ActivatedRoute, private router: Router, private menu: MenuComponent) { }
+
+  ngOnInit(): void
   {
     this.numeroVariable = this.route.snapshot.params['numeroVariable'];
     this.variable = new Variable();
     this.variableService.getByIdVariable(this.numeroVariable).subscribe( data => { this.variable = data; });
   }
-  
+
   ngAfterViewInit() { }
- 
+
   updateVariable(id: number) { this.router.navigate(['/variable-update', id]); }
-  
-  goToListVariable(){ window.location.reload(); }
+
+  goToListVariable() { this.router.navigate(['/variable-list'], { queryParams: { 'refresh': this.menu.getRandomInteger(1, 100000) } }); }
 
 }

+ 5 - 5
src/app/composants/variable-list/variable-list.component.html

@@ -3,14 +3,14 @@
 <div class="card shadow">
 	<div class="card-header">Table des variables</div>
 	<div class="card-header shadow-sm">
-		<div class="row">
+		<div class="row justify-content-between">
 			<div class="form-group col-sm-4 label-nobr">
 				<button type="button" (click)="goToRefreshListVariable()" class="btn bg-gradient btn-primary btn-sm field-separate" style="margin-right: 5px;"><i class="fa-solid fa-rotate"></i>&nbsp;Actualiser</button>
 				<button type="button" (click)="goToNewVariable()" class="btn bg-gradient btn-primary btn-sm field-separate" style="margin-right: 5px;"><i class="fa-solid fa-plus"></i>&nbsp;Créer</button>
 			</div>
-			<div class="form-group col-sm-2">
-        <select class="form-select form-select-sm field-separate" id="select_type" (change)="filtrageParType($event)">
-					<option selected> </option>
+  		<div class="form-group col-sm-2">
+				<select class="form-select form-select-sm field-separate" id="select_type" [(ngModel)]="typeFiltre" (change)="filtrageParType($event)">
+					<option> </option>
           @for (type of types; track type) {
 					<option [value]="type.type">{{ type.type }}</option>
 				  }
@@ -39,4 +39,4 @@
 		</table>
 	</div>
 </div>
-</div>
+</div>

+ 13 - 11
src/app/composants/variable-list/variable-list.component.ts

@@ -3,30 +3,32 @@ import { Router } from '@angular/router';
 import { MenuComponent } from '../menu/menu.component';
 import { Variable, VariableType } from '../../interfaces/variable';
 import { VariableService } from '../../services/variable.service';
+import { FormsModule, NgForm } from '@angular/forms';
 
-@Component({ selector: 'app-variable-list', imports: [MenuComponent], templateUrl: './variable-list.component.html', styleUrl: './variable-list.component.css' })
+@Component({ selector: 'app-variable-list', imports: [FormsModule, MenuComponent], templateUrl: './variable-list.component.html', styleUrl: './variable-list.component.css' })
 
 export class VariableListComponent implements OnInit, AfterViewInit
 {
-  
+
   types: VariableType[] = [];
-  
+  typeFiltre: string = "";
+
   variables: Variable[] = [];
 
   constructor(private variableService: VariableService, private router: Router, private menu: MenuComponent) { }
 
-  ngOnInit(): void { this.retreiveDatas(); this.retreiveParticipants(); }
-  
+  ngOnInit() { this.goToRefreshListVariable(); }
+
   ngAfterViewInit() { }
 
-  private retreiveDatas() { this.variableService.getListVariable().subscribe(data => { this.variables = data; }); }
-  private retreiveParticipants() { this.variableService.getOptionListVariableType().subscribe(data => { this.types = data; }); }
+  private retreiveDatas() { this.variableService.getListVariable(this.typeFiltre).subscribe(data => { this.variables = data; }); }
+  private retreiveTypes() { this.variableService.getOptionListVariableType().subscribe(data => { this.types = data; }); }
+
+  filtrageParType(event: any) { this.typeFiltre = event.target.value; this.goToRefreshListVariable(); }
 
-  filtrageParType(event: any) { this.router.navigate(['/variable-list'], { queryParams: { 'refresh': this.menu.getRandomInteger(1, 100000), 'type': event.target.value } }); }
-  
-  goToRefreshListVariable(){ window.location.reload(); }
+  goToRefreshListVariable() { this.retreiveDatas(); this.retreiveTypes(); }
 
-  goToNewVariable(){ this.router.navigate(['/variable-create']); }
+  goToNewVariable() { this.router.navigate(['/variable-create']); }
 
   formVariable(id: number) { this.router.navigate(['/variable-details', id]); }
 

+ 10 - 10
src/app/guarfs/logged.guard.ts → src/app/guards/admin.guard.ts

@@ -5,16 +5,16 @@ import { AccountService } from '../services/account.service';
 
 @Injectable({ providedIn: 'root' })
 
-export class LoggedGuard implements CanActivate 
-{      
- 
+export class AdminGuard implements CanActivate
+{
+
   constructor(private router: Router, private accountService: AccountService) {}
-  
-  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean 
-  {      
-    if (this.accountService.isLogged()) { return true; }
 
-    return false;      
+  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean
+  {
+    if (this.accountService.getRole() === 'ADMIN') { return true; }
+
+    return false;
   }
-   
-}    
+
+}

+ 21 - 0
src/app/guards/orga.guard.ts

@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+
+import { AccountService } from '../services/account.service';
+
+@Injectable({ providedIn: 'root' })
+
+export class OrgaGuard implements CanActivate
+{
+
+  constructor(private router: Router, private accountService: AccountService) {}
+
+  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean
+  {
+    if (this.accountService.getRole() === 'ADMIN') { return true; }
+    if (this.accountService.getRole() === 'ORGA') { return true; }
+
+    return false;
+  }
+
+}

+ 22 - 0
src/app/guards/user.guard.ts

@@ -0,0 +1,22 @@
+import { Injectable } from '@angular/core';
+import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+
+import { AccountService } from '../services/account.service';
+
+@Injectable({ providedIn: 'root' })
+
+export class UserGuard implements CanActivate
+{
+
+  constructor(private router: Router, private accountService: AccountService) {}
+
+  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean
+  {
+    if (this.accountService.getRole() === 'ADMIN') { return true; }
+    if (this.accountService.getRole() === 'ORGA') { return true; }
+    if (this.accountService.getRole() === 'USER') { return true; }
+
+    return false;
+  }
+
+}

+ 4 - 2
src/app/interfaces/user.ts

@@ -1,9 +1,11 @@
 
-export class User 
+export class User
 {
   username: string = "";
   password: string = "";
   nom: string = "";
   prenom: string = "";
   role: string = "";
-}
+  token: string = "";
+  erreur: string = "";
+}

+ 11 - 10
src/app/services/account.service.ts

@@ -8,37 +8,38 @@ import { Participant } from '../interfaces/participant';
 
 @Injectable({ providedIn: 'root' })
 
-export class AccountService 
+export class AccountService
 {
 
   private baseURLsig = Environnement.apiUrl + "sign";
-  
+
   private baseURLacc = Environnement.apiUrl + "account";
 
   private userSubject: BehaviorSubject<User | null>;
-  
+
   public user: Observable<User | null>;
 
   constructor(private httpClient: HttpClient)
   {
-    this.userSubject = new BehaviorSubject(JSON.parse(localStorage.getItem('user')!));
+    this.userSubject = new BehaviorSubject(JSON.parse(sessionStorage.getItem('user')!));
     this.user = this.userSubject.asObservable();
   }
 
   public isLogged() { if (this.userSubject.value) { return true; } return false; }
   public getUsername() { if (this.userSubject.value) { return this.userSubject.value.username; } return ""; }
   public getRole() { if (this.userSubject.value) { return this.userSubject.value.role; } return ""; }
-  
+  public getToken() { if (this.userSubject.value) { return this.userSubject.value.token; } return ""; }
+
   signIn(usr: User): Observable<User>
   {
-    return this.httpClient.post<User>(`${this.baseURLsig}/in`, usr).pipe(map(u => { localStorage.setItem('user', JSON.stringify(u)); this.userSubject.next(u); return u; }));
+    return this.httpClient.post<User>(`${this.baseURLsig}/in`, usr).pipe(map(u => { sessionStorage.setItem('user', JSON.stringify(u)); this.userSubject.next(u); return u; }));
   }
 
-  signOut() 
+  signOut()
   {
     this.httpClient.post<User>(`${this.baseURLsig}/signout`, null);
-    
-    localStorage.removeItem('user');
+
+    sessionStorage.removeItem('user');
     this.userSubject.next(null);
   }
 
@@ -48,4 +49,4 @@ export class AccountService
 
   updateProfil(participant: Participant): Observable<Object>{ return this.httpClient.put(`${this.baseURLacc}/update`, participant); }
 
-}
+}

+ 24 - 0
src/app/services/auth.interceptor.ts

@@ -0,0 +1,24 @@
+import { Injectable } from '@angular/core';
+import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { AccountService } from './account.service';
+
+@Injectable()
+
+export class AuthInterceptor implements HttpInterceptor
+{
+
+  private authToken: string = "";
+
+  constructor(private accountService: AccountService) { }
+
+  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>
+  {
+    const authToken = this.accountService.getToken();
+
+    const modified = request.clone({ headers: request.headers.append('Authorization', "Bearer " + authToken) });
+
+    return next.handle(modified);
+  }
+
+}

+ 15 - 6
src/app/services/participant.service.ts

@@ -1,19 +1,28 @@
 import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http'
+import { HttpClient, HttpParams } from '@angular/common/http'
 import { Observable } from 'rxjs';
 import { Environnement } from '../env';
 import { Participant, ParticipantList, ParticipantShort } from '../interfaces/participant';
 
 @Injectable({ providedIn: 'root' })
 
-export class ParticipantService 
+export class ParticipantService
 {
 
   private baseURL = Environnement.apiUrl + "participant";
 
   constructor(private httpClient: HttpClient) { }
-  
-  getListParticipant(): Observable<ParticipantList[]>{ return this.httpClient.get<Participant[]>(`${this.baseURL}/list`); }
+
+  getListParticipant(filtreNom: string, filtreStatut: number, filtreArrive: number): Observable<ParticipantList[]>
+  {
+    let params = new HttpParams();
+
+    params = params.append('nom', filtreNom);
+    params = params.append('statut', filtreStatut);
+    params = params.append('arrive', filtreArrive);
+
+    return this.httpClient.get<Participant[]>(`${this.baseURL}/list`, { params: params });
+  }
 
   getOptionListParticipant(): Observable<ParticipantShort[]>{ return this.httpClient.get<ParticipantShort[]>(`${this.baseURL}/option-list`); }
 
@@ -24,5 +33,5 @@ export class ParticipantService
   updateParticipant(id: number, participant: Participant): Observable<Object>{ return this.httpClient.put(`${this.baseURL}/update/${id}`, participant); }
 
   deleteParticipant(id: number): Observable<Object>{ return this.httpClient.delete(`${this.baseURL}/delete/${id}`); }
-  
-}
+
+}

+ 13 - 6
src/app/services/variable.service.ts

@@ -1,19 +1,26 @@
 import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http'
+import { HttpClient, HttpParams } from '@angular/common/http'
 import { Observable } from 'rxjs';
 import { Environnement } from '../env';
 import { Variable, VariableType } from '../interfaces/variable';
 
 @Injectable({ providedIn: 'root' })
 
-export class VariableService 
+export class VariableService
 {
 
   private baseURL = Environnement.apiUrl + "variable";
 
   constructor(private httpClient: HttpClient) { }
-  
-  getListVariable(): Observable<Variable[]>{ return this.httpClient.get<Variable[]>(`${this.baseURL}/list`); }
+
+  getListVariable(filtreType: string): Observable<Variable[]>
+  {
+    let params = new HttpParams();
+
+    if (filtreType !== null) { params = params.append('type', filtreType); }
+
+    return this.httpClient.get<Variable[]>(`${this.baseURL}/list`, { params: params });
+  }
 
   getOptionListVariableType(): Observable<VariableType[]>{ return this.httpClient.get<VariableType[]>(`${this.baseURL}/option-list`); }
 
@@ -24,5 +31,5 @@ export class VariableService
   updateVariable(id: number, variable: Variable): Observable<Object>{ return this.httpClient.put(`${this.baseURL}/update/${id}`, variable); }
 
   deleteVariable(id: number): Observable<Object>{ return this.httpClient.delete(`${this.baseURL}/delete/${id}`); }
-  
-}
+
+}