Commit aba1f0fd authored by François Agneray's avatar François Agneray
Browse files

Agents => ok, missions en cours

parent 3466791a
Pipeline #6813 passed with stages
in 1 minute and 11 seconds
# Les agents
Maintenant que nous avons geré l'authentification nous pouvons développer notre application.
Nous allons commencer pa le module `agent` qui va nous permettre de charger la liste des agents présents dans la base de données.
En effet, le module `mission` nécessite d'avoir la liste des agents pour fonctionner.
## TP : Module agent
1. Ajouter un nouveau module `AgentModule` avec un fichier de routing `AgentRoutingModule` et un service `AgentService`
2. Créer un component `AgentListComponent` avec juste un titre `Liste des agents`
3. Ajouter une route `agent-list` dans `AgentRoutingModule` pour pointer sur le component `AgentListComponent`. N'oubliez pas de le protéger avec le `AuthGuard`.
4. Ajouter le module `AgentModule` au module principal `AppModule`
5. Ajouter une barre de menu dans le `AppComponent` avant le `<router-outlet></router-outlet>` pour naviguer entre les pges `mission-list` et `agent-list`
6. Completement à droite dans la barre de menu ajouter un bouton de deconnexion qui ferra appel à la méthode `clearTokenFromLocalStorage` de `LoginService`
7. Le bouton de déconnexion doit effacer complétement le `userToken` et renvoyer l'utilisateur sur la page `login`
8. La barre de menu de doit être visible que lorsque l'utilisateur est connecté
## TP: Service agent
Voici un exemple d'un objet agent :
```ts
{
firstname: "Aliev",
lastname: "Kallistrat",
status: "Chercheur·se",
cap: 1500
}
```
1. Dans le module `AgentModule` ajouter une interface `agent.model` pour définir l'objet `Agent`
2. Dans le service `AgentService` ajouter une propriété `agents` qui stockera la liste des agents et deux propriétés `agentsIsLoading`, `agentsIsLoaded`
3. Ajouter une méthode `loadAgentList` qui permettra de charger la liste des agents et d'affecter le résultat à la propriété `agents`
4. Dans le component `AgentListComponent` appeler à l'initialisation la méthode `loadAgentList` du service `AgentService`
5. Dans le module `AgentModule` ajouter un component `AgentListTableComponent`
6. Passer en paramètre d'entré de `AgentListTableComponent` la liste `agents`
7. A l'aide d'une table bootstrap afficher les agents dans `AgentListTableComponent`
8. La table ne doit être visible que si `agentsIsLoaded` est true
9. Si `agentsIsLoading` est true afficher un spinner
**Résultat attendu :**
![agent_s1](img/agent_s1.png#center)
\ No newline at end of file
......@@ -70,4 +70,85 @@ Dans cette partie nous allons développer le module `LoginModule` qui permettre
![auth_s1](img/auth_s1.png#center)
![auth_s2](img/auth_s2.png#center)
\ No newline at end of file
![auth_s2](img/auth_s2.png#center)
## Le Local Storage
Pour le moment notre authentification n'est pas persistante, cela signifie que sir l'utilisateur recharge sa page il devra se reconnecter.
Pour faire en sorte que l'utilisateur ne se reconnecte pas à chaque rechargement de l'application nous allons devoir stocker le `token` de maniere persistante.
Pour cela nous allons utiliser une fonctionnalité disponible dans les navigateurs le `LocalStorage`. Le `LocalStorage` va permettre aux développeurs de stocker des informations coté client. Au rechargement de la page il pourra alors récuperer les informations stockées.
Pour l'utiliser vous devez appeler la variable `localStorage` disponible n'importe où dans l'application. Pour stocker une variable il faut utiliser la méthode `setItem(key: string, value: string)`, pour rècuperer une variable il faut utiliser la méthode `getItem(key: string)` et pour supprimer une variable il faut utiliser `removeItem(key: string)`.
Attention le localstorage ne peut stocker des chaînes de caractères et pas des variables complexes comme des objets. Pour stocker des objets il faudra alors les serialiser.
Exemple :
```ts
// Stockage de la variable userToken
const userTokenJson = JSON.stringify(this.userToken); // sérialisation
localStorage.setItem('userToken', userTokenJson);
// Récuperation de la variable userToken
const userTokenJson = localStorage.getItem('userToken');
this.userToken = JSON.parse(userTokenJson as string); // désérialisation
// Suppression de la variable userToken
localStorage.removeItem('userToken');
```
## TP : Persistance du token
1. Ajouter une méthode `saveTokenToLocalStorage` dans le service `LoginService` qui stockera l'objet `userToken` dans le Local Storage
2. Ajouter une méthode `restoreTokenFromLocalStorage` dans le service `LoginService` pour restaurer l'objet `userToken` depuis le Local Storage
3. Au login de l'utilisateur n'oubliez pas d'appeler la fonction pour stocker le `userToken` dans le Local Storage
4. Dans le component principal `AppComponent` implémenter l'interface `OnInit` et ajouter la méthode `ngOnInit()`
5. La méthode `ngOnInit()` sera appelée au démarrage de l'application. Pour restaurer le token vous devez donc appeler la méthode `restoreTokenFromLocalStorage` du service `LoginService`
6. Ajouter une méthode `clearTokenFromLocalStorage()` dans le service `LoginService` qui va supprimer l'objet `userToken` depuis le Local Storage. Nous utiliserons cette méthode plus tard dans le TP.
Vous pouvez alors constater qu'une fois connecté le rechargement de la page `mission-list` ne redirige pas sur la page `login`. Le token est bien restauré au démarrage.
## TP : Http Interceptor
Pour prouver au serveur que nous avons l'autorisation d'utiliser l'application nous devons envoyer à chaque requête http le `token` dans le Header Authorization sous la forme `Authorization: Bearer <token>`. Pour faire cela Angular met à notre disposition un mecanisme appelé `HttpInterceptor` et qui va modifier la requête pour nous à chaque appel de `HttpClient`.
Pour pouvoir l'utiliser nous devons ajouter un nouveau service qui implemente l'interface `HttpInterceptor` et qui oblige à ajouter une méthode `intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>`. Cette méthode sera executé à chaque fois qu'une requête est envoyé. C'est ici que nous allons ajouter notre `token`.
- Ajouter le service `TokenInterceptorService`, comme ceci :
```ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoginService } from './login.service';
@Injectable()
export class TokenInterceptorService implements HttpInterceptor {
constructor(private loginService: LoginService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const userToken = this.loginService.userToken;
let newHeaders = req.headers;
if (userToken) {
newHeaders = newHeaders.append('Authorization', `Bearer ${userToken.token}`);
}
return next.handle(req.clone({headers: newHeaders}));
}
}
```
- Il faut ensuite déclarer cet interceptor dans notre module `LoginModule` dans la partie `providers`, comme ceci :
```ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptorService } from './token-interceptor.service';
...
providers: [
LoginService,
AuthGuard,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptorService, multi: true }
]
...
```
# Les missions
\ No newline at end of file
# Les missions
Nous allons maintenant developper le module mission
## TP : Module mission
1. Ajouter un module `MissionModule` sur le même principe que le module `AgentModule`
2. Déplacer le component `MissionListComponent` dans le module `MissionModule`
3. Ajouter un component `MissionListTableComponent` pour afficher la tableau des missions
4. Ajouter deux colonnes supplémentaires avec deux boutons `Modifier` et `Supprimer`
5. Au dessus du tableau ajouter un bouton `Ajouter une mission`
## TP : Le service mission
Voici un exemple d'un objet Mission :
```ts
{
cost: 680,
country: "Australie",
date_from: "2021-01-13",
date_to: "2021-02-10",
id_mission: 1,
ref_agent: 2
}
```
1. Dans le module `MissionModule` ajouter une interface `mission.model` pour définir l'objet `Mission`
2. Dans le service `MissionService` ajouter la méthode `loadMissionList` pour charger les missions
3. Dans le service `MissionService` ajouter la méthode `editMission` pour editer une mission
4. Dans le service `MissionService` ajouter la méthode `delMission` pour supprimer une mission
**Résultat attendu :**
![mission_s1](img/mission_s1.png#center)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment