From 3afe4ec28614cc3163d909d5b9036b006746e528 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 13:15:44 +0000
Subject: [PATCH 1/3] Initial plan
From 73f59d0d8844a5c6d33ac76888e977bffe7899e7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 13:21:57 +0000
Subject: [PATCH 2/3] docs: add detailed French pedagogical comments for
Angular TS and HTML files
Agent-Logs-Url: https://github.com/Invivoo/formation-angular/sessions/97fc6dec-0081-41e1-97ab-4935db462be6
Co-authored-by: saber-amaira <84281543+saber-amaira@users.noreply.github.com>
---
src/app/app.component.css | 6 ++
src/app/app.component.html | 12 ++++
src/app/app.component.ts | 31 +++++++++++
src/app/users/crud/crud.component.ts | 45 +++++++++++++++
src/app/users/model/user.model.ts | 15 +++++
src/app/users/services/users.service.ts | 55 +++++++++++++++++++
.../users/user-card/user-card.component.ts | 24 ++++++++
src/app/users/users-routing.module.ts | 20 +++++++
src/app/users/users.module.ts | 22 ++++++++
src/index.html | 17 ++++++
src/main.ts | 31 +++++++++++
11 files changed, 278 insertions(+)
create mode 100644 src/app/app.component.css
create mode 100644 src/app/app.component.html
create mode 100644 src/app/app.component.ts
create mode 100644 src/app/users/crud/crud.component.ts
create mode 100644 src/app/users/model/user.model.ts
create mode 100644 src/app/users/services/users.service.ts
create mode 100644 src/app/users/user-card/user-card.component.ts
create mode 100644 src/app/users/users-routing.module.ts
create mode 100644 src/app/users/users.module.ts
create mode 100644 src/index.html
create mode 100644 src/main.ts
diff --git a/src/app/app.component.css b/src/app/app.component.css
new file mode 100644
index 0000000..948f0ee
--- /dev/null
+++ b/src/app/app.component.css
@@ -0,0 +1,6 @@
+/* Styles du composant racine */
+nav {
+ display: flex;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
diff --git a/src/app/app.component.html b/src/app/app.component.html
new file mode 100644
index 0000000..e6a0f4b
--- /dev/null
+++ b/src/app/app.component.html
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
new file mode 100644
index 0000000..d92765c
--- /dev/null
+++ b/src/app/app.component.ts
@@ -0,0 +1,31 @@
+import { Component, OnInit } from '@angular/core';
+import { RouterLink, RouterOutlet } from '@angular/router';
+
+/**
+ * @Component transforme la classe TypeScript en composant Angular.
+ * selector:
+ * - nom de la balise HTML personnalisée utilisée dans index.html ().
+ * templateUrl:
+ * - chemin vers le fichier HTML du composant (vue).
+ * styleUrls:
+ * - liste de fichiers CSS appliqués uniquement à ce composant (encapsulation).
+ * standalone:
+ * - indique que le composant peut être démarré sans NgModule racine.
+ */
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [RouterOutlet, RouterLink],
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css'],
+})
+export class AppComponent implements OnInit {
+ /**
+ * ngOnInit est un hook du cycle de vie Angular.
+ * Il est appelé une fois, juste après la création du composant.
+ * C'est l'endroit recommandé pour lancer les initialisations simples.
+ */
+ ngOnInit(): void {
+ // Aucune initialisation spécifique pour le moment.
+ }
+}
diff --git a/src/app/users/crud/crud.component.ts b/src/app/users/crud/crud.component.ts
new file mode 100644
index 0000000..f37ec2f
--- /dev/null
+++ b/src/app/users/crud/crud.component.ts
@@ -0,0 +1,45 @@
+import { Component, OnInit } from '@angular/core';
+import { UsersService } from '../services/users.service';
+import { User } from '../model/user.model';
+
+/**
+ * Composant de liste CRUD.
+ * @Component configure:
+ * - selector: balise utilisable dans d'autres templates.
+ * - template: vue HTML inline de ce composant.
+ */
+@Component({
+ selector: 'app-crud',
+ template: `
+ Liste des utilisateurs
+
+ `,
+})
+export class CrudComponent implements OnInit {
+ /** Tableau alimenté avec les données de l'API */
+ userList: User[] = [];
+
+ /**
+ * Injection de dépendances:
+ * Angular fournit automatiquement une instance de UsersService.
+ */
+ constructor(private usersService: UsersService) {}
+
+ /**
+ * Hook de cycle de vie exécuté après la création du composant.
+ * On y déclenche l'initialisation métier (chargement de la liste).
+ */
+ ngOnInit(): void {
+ this.loadUsers();
+ }
+
+ /**
+ * Récupère les utilisateurs via le service.
+ * subscribe(...) consomme l'Observable et met à jour l'état local.
+ */
+ private loadUsers(): void {
+ this.usersService.getUsers().subscribe((users) => {
+ this.userList = users;
+ });
+ }
+}
diff --git a/src/app/users/model/user.model.ts b/src/app/users/model/user.model.ts
new file mode 100644
index 0000000..7eda6f7
--- /dev/null
+++ b/src/app/users/model/user.model.ts
@@ -0,0 +1,15 @@
+/**
+ * Interface décrivant la forme d'un utilisateur.
+ * Une interface TypeScript permet de typer les données manipulées
+ * pour éviter des erreurs et faciliter l'autocomplétion.
+ */
+export interface User {
+ /** Identifiant unique de l'utilisateur côté API/base de données */
+ id: number;
+ /** Prénom affiché dans l'interface */
+ firstName: string;
+ /** Nom de famille affiché dans l'interface */
+ lastName: string;
+ /** Adresse e-mail utilisée pour contacter ou rechercher l'utilisateur */
+ email: string;
+}
diff --git a/src/app/users/services/users.service.ts b/src/app/users/services/users.service.ts
new file mode 100644
index 0000000..2ff2018
--- /dev/null
+++ b/src/app/users/services/users.service.ts
@@ -0,0 +1,55 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { User } from '../model/user.model';
+
+/**
+ * URL de base de l'API REST des utilisateurs.
+ * Toutes les opérations CRUD partent de cette route.
+ */
+const baseUrl = 'http://localhost:8081/api/v1/employees';
+
+/**
+ * @Injectable permet à Angular d'instancier ce service via l'injection
+ * de dépendances. providedIn: 'root' signifie "singleton global".
+ */
+@Injectable({
+ providedIn: 'root',
+})
+export class UsersService {
+ /**
+ * HttpClient est injecté automatiquement par Angular.
+ * Il sert à faire les requêtes HTTP (GET, POST, PUT, DELETE).
+ */
+ constructor(private http: HttpClient) {}
+
+ /**
+ * Lit tous les utilisateurs.
+ * Retourne un Observable:
+ * - un Observable représente un flux asynchrone de données.
+ * - le composant s'abonne (subscribe) pour recevoir la réponse.
+ */
+ getUsers(): Observable {
+ return this.http.get(baseUrl);
+ }
+
+ /** Crée un nouvel utilisateur côté API. */
+ create(data: Partial): Observable {
+ return this.http.post(baseUrl, data);
+ }
+
+ /** Met à jour un utilisateur existant via son id. */
+ update(id: number, data: Partial): Observable {
+ return this.http.put(`${baseUrl}/${id}`, data);
+ }
+
+ /** Supprime un utilisateur via son id. */
+ delete(id: number): Observable {
+ return this.http.delete(`${baseUrl}/${id}`);
+ }
+
+ /** Recherche des utilisateurs par adresse e-mail. */
+ findByEmail(email: string): Observable {
+ return this.http.get(`${baseUrl}?email=${email}`);
+ }
+}
diff --git a/src/app/users/user-card/user-card.component.ts b/src/app/users/user-card/user-card.component.ts
new file mode 100644
index 0000000..1d38bcb
--- /dev/null
+++ b/src/app/users/user-card/user-card.component.ts
@@ -0,0 +1,24 @@
+import { Component, Input } from '@angular/core';
+import { User } from '../model/user.model';
+
+/**
+ * Composant enfant chargé d'afficher un utilisateur.
+ */
+@Component({
+ selector: 'app-user-card',
+ template: `
+
+ {{ user.firstName }} {{ user.lastName }}
+ {{ user.email }}
+
+ `,
+})
+export class UserCardComponent {
+ /**
+ * @Input() reçoit des données depuis le composant parent.
+ * Exemple:
+ *
+ * Le parent passe l'objet user au composant enfant.
+ */
+ @Input() user!: User;
+}
diff --git a/src/app/users/users-routing.module.ts b/src/app/users/users-routing.module.ts
new file mode 100644
index 0000000..98d7c90
--- /dev/null
+++ b/src/app/users/users-routing.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { CrudComponent } from './crud/crud.component';
+
+/**
+ * Configuration des routes internes au module users.
+ * - 'all' affiche la liste des utilisateurs.
+ * - 'create' pourrait afficher un formulaire de création
+ * (ici, on réutilise CrudComponent pour garder l'exemple simple).
+ */
+const routes: Routes = [
+ { path: 'all', component: CrudComponent },
+ { path: 'create', component: CrudComponent },
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule],
+})
+export class UsersRoutingModule {}
diff --git a/src/app/users/users.module.ts b/src/app/users/users.module.ts
new file mode 100644
index 0000000..3a955dd
--- /dev/null
+++ b/src/app/users/users.module.ts
@@ -0,0 +1,22 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { HttpClientModule } from '@angular/common/http';
+import { UsersRoutingModule } from './users-routing.module';
+import { CrudComponent } from './crud/crud.component';
+import { UserCardComponent } from './user-card/user-card.component';
+
+/**
+ * @NgModule regroupe les éléments liés à une fonctionnalité.
+ * imports:
+ * - modules dont ce module a besoin (directives Angular, HTTP, routing local).
+ * declarations:
+ * - composants appartenant à ce module.
+ * providers:
+ * - services créés pour ce module (vide ici car UsersService est fourni en root).
+ */
+@NgModule({
+ imports: [CommonModule, HttpClientModule, UsersRoutingModule],
+ declarations: [CrudComponent, UserCardComponent],
+ providers: [],
+})
+export class UsersModule {}
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..61cb123
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Formation Angular
+
+
+
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..f19eda7
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,31 @@
+import { bootstrapApplication } from '@angular/platform-browser';
+import { provideRouter, Routes } from '@angular/router';
+import { AppComponent } from './app/app.component';
+
+/**
+ * Routes principales de l'application.
+ * - '' affiche la page racine (AppComponent).
+ * - 'users' charge le module utilisateurs de façon paresseuse (lazy loading)
+ * pour éviter de charger tout le code dès le démarrage.
+ */
+const routes: Routes = [
+ { path: '', component: AppComponent },
+ {
+ path: 'users',
+ loadChildren: () =>
+ import('./app/users/users.module').then((m) => m.UsersModule),
+ },
+];
+
+/**
+ * Point d'entrée de l'application Angular.
+ * bootstrapApplication:
+ * - démarre l'application avec un composant racine standalone.
+ * providers:
+ * - enregistre des services globaux de l'application.
+ * provideRouter(routes):
+ * - active la navigation Angular et injecte la configuration des routes.
+ */
+bootstrapApplication(AppComponent, {
+ providers: [provideRouter(routes)],
+}).catch((err) => console.error(err));
From f56256eadda9bffde02633c5dd0f935513c65d18 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 13:23:17 +0000
Subject: [PATCH 3/3] fix: encode email query with HttpParams in users service
Agent-Logs-Url: https://github.com/Invivoo/formation-angular/sessions/97fc6dec-0081-41e1-97ab-4935db462be6
Co-authored-by: saber-amaira <84281543+saber-amaira@users.noreply.github.com>
---
src/app/users/services/users.service.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/app/users/services/users.service.ts b/src/app/users/services/users.service.ts
index 2ff2018..c581bc6 100644
--- a/src/app/users/services/users.service.ts
+++ b/src/app/users/services/users.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
+import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from '../model/user.model';
@@ -50,6 +50,7 @@ export class UsersService {
/** Recherche des utilisateurs par adresse e-mail. */
findByEmail(email: string): Observable {
- return this.http.get(`${baseUrl}?email=${email}`);
+ const params = new HttpParams().set('email', email);
+ return this.http.get(baseUrl, { params });
}
}