diff --git a/resources/docs/docs/creation-projet/create_project.md b/resources/docs/docs/creation-projet/create_project.md index 49e3aff3c89741f371a3afd88d95c660f2ba914f..59252a5092427332130b70b0dcd80c015d30f1d7 100644 --- a/resources/docs/docs/creation-projet/create_project.md +++ b/resources/docs/docs/creation-projet/create_project.md @@ -16,12 +16,13 @@ On te pose alors deux questions, utilise les flèches de ton clavier pour répon > ✔️ **Réponse**<br/> > `N` -Angular va initialiser ton projet et créer tout un tas de fichier (sans les fichiers de test en.spec.ts, car on l'a précisé en option avec *--skip-tests=true*). +Angular va initialiser ton projet et créer tout un tas de fichier (sans les fichiers de test en `.spec.ts`, car on l'a précisé en option avec *--skip-tests=true*). Une fois que c'est terminé, ouvre ton projet dans ton IDE. ## On ajoute Bootstrap Pour développer plus rapidement, on utilise des librairies de style et de composants. Il en existe plusieurs : Angular Material, Bootstrap, Tailwind ... Nous avons choisi Bootstrap pour ce projet. Pour le mettre en place : + * ouvre le terminal de ton IDE et lance `npm install bootstrap@5.3.3` * dans le ficher `style.scss`, ajoute en premier `@import "bootstrap";` diff --git a/resources/docs/docs/gestion-film/actions.md b/resources/docs/docs/gestion-film/actions.md index f64ecf1aa1b9bd084e0edad59ce7d6f0983bfd81..0f66fd3c05145eeab219a4e18e36a3b2abf4f470 100644 --- a/resources/docs/docs/gestion-film/actions.md +++ b/resources/docs/docs/gestion-film/actions.md @@ -25,13 +25,13 @@ HTML : Service TS : ``` deleteMovie(id: number): Observable<void> { - return this.httpClient.delete<void>(`${this.url}/movies/${id}`); + return this.httpClient.delete<void>(`${this.url}/${id}`); } ``` TS du composant: ``` -deleteFilm(id: number): void { - this.movieService.deleteMovie(id).subscribe(() => +deleteMovie(id: number): void { + this.moviesService.deleteMovie(id).subscribe(() => this.movies = this.movies.filter(film => film.id !== id) ); } diff --git a/resources/docs/docs/gestion-film/create-film.md b/resources/docs/docs/gestion-film/create-film.md index 71b420c115c774a490cc7c17a661f47741c8b9f9..dc6be3552fd57a7e47c0db16ed63e606e5d04526 100644 --- a/resources/docs/docs/gestion-film/create-film.md +++ b/resources/docs/docs/gestion-film/create-film.md @@ -6,7 +6,7 @@ Tu peux tester en cliquant sur *Nouveau film* sur [le site](https://allocine.tak ## Création du composant ***À toi de jouer ! 👾 Utilise Angular CLI via ton terminal*** -La commande est la même que celle utilisée pour générer le `HomeComponent`; il faut juste lui donner le nom *add-movie* pour que le composant généré s'appelle `AddMovieComponent`. +La commande est la même que celle utilisée pour générer le `HomeComponent`; il faut juste lui donner le nom *add-movie* pour que le composant généré s'appelle `AddMovieComponent`. Il faudrait qu'il se trouve dans le dossier existant `movies`. ## Nouvelle page = nouvelle route @@ -16,7 +16,7 @@ On veut ajouter une route à celles existantes : */add-movie* pour afficher le ` ## Le bouton -Pour ajouter un bouton, on utilise la balise `<button></button>` et on écrit entre les balises ce qu'on veut afficher dans le bouton : *Nouveau film*. +Pour ajouter un bouton dans `movies.component.html`, on utilise la balise `<button></button>` et on écrit entre les balises ce qu'on veut afficher dans le bouton : *Nouveau film*. Normalement, il ne sera pas très beau. > Tu as la [doc](https://getbootstrap.com/docs/5.0/components/buttons/) pour voir comment customiser ton bouton avec Bootstrap. @@ -33,31 +33,34 @@ Mais surtout, il ne se passe rien si je clique dessus ! 😬 Tout d'abord, on ajoute notre titre entre des balises `<h1></h1>`. Ensuite, on a 4 champs de formulaire composés d'un `<label>` et d'un `<input>`. -On crée une variable *movie* de type `Movie` avec ces 4 champs initialisés dans le `add-movie.component.ts`, les autres champs sont mis à `null` : +On crée une variable *movie* de type `Movie` avec ces 4 champs initialisés dans le `add-movie.component.ts`, les autres champs sont mis à `undefined` : ```ts -movie = { - title = ''; - director = ''; - releaseDate = new Date(); - synopsis = ''; - id: null, - rate: null, - image: null +movie: Movie = { + title: '', + director: '', + releaseDate: new Date(), + synopsis: '', + id: undefined, + rate: undefined, + image: undefined } ``` On te montre quoi ajouter pour le premier champ *titre* dans `add-movie.component.html` et on te laisse faire les autres : ```html -<div class="d-flex flex-column"> +<div class="d-flex flex-column w-50"> <label for="title">Titre</label> - <input type="text" id="title" [(ngModel)]="title"/> + <input type="text" id="title" [(ngModel)]="movie.title"/> </div> ``` +>Pour utiliser `ngModel`, il faut importer `FormsModule`. + >Les propriétés `for` et `id` servent à lier le `label` et l'`input` en HTML. >Le type permet de savoir quoi rentrer dans l'input, ici ce sera du texte. ->Il existe un type *date* dans la balise `input` +>Il existe un type *date* dans la balise `input` si besoin. + ### Le bouton de soumission du formulaire Maintenant, il faut recréer un bouton pour faire la soumission du formulaire. @@ -70,21 +73,23 @@ Attention, celui-ci n'a pas le même comportement ! On n'a pas besoin de la part > `(click)` permet de détecter à chaque fois qu'on clique sur le bouton >`addMovie()` est une fonction du TS qui est appelée à chaque clic. -Il faut alors définir la fonction `addMovie`, sinon notre code ne compilera pas. On veut que la méthode fasse un appel POST au back en lui donnant le nouveau film à ajouter. On doit donc passer par le `MovieService`. +Il faut alors définir la fonction `addMovie`, sinon notre code ne compilera pas. On veut que la méthode fasse un appel POST au back en lui donnant le nouveau film à ajouter. On doit donc passer par le `MoviesService`. Au retour du back, on navigue vers la page précédente si l'ajout s'est bien effectué. ```ts addMovie(): void { - this.movieService.addMovie(this.movie).subscribe( + this.moviesService.addMovie(this.movie).subscribe( () => this.router.navigate(['/movies']) ); } ``` -Mais... Ça ne compile pas... Car dans notre `MovieService` il n'y a pas de méthode addMovie ! Hop, on la crée : +>Si tu ne te souviens comment injecter ton `moviesService`, tu peux regarder dans `home.component.ts` comment on l'avait fait. + +Mais... Ça ne compile pas... Car dans notre `MoviesService` il n'y a pas de méthode `addMovie` ! Hop, on la crée : ```ts addMovie(movie: Movie): Observable<Movie> { - return this.httpClient.post<Movie>(movie); + return this.httpClient.post<Movie>(this.url, movie); } ``` diff --git a/resources/docs/docs/gestion-film/implem-component.md b/resources/docs/docs/gestion-film/implem-component.md index f4f5bbf4b36d6156c12b72572a05c28f2c554b0c..2915ecef1e918188f382afadd5cb6b6946c6912f 100644 --- a/resources/docs/docs/gestion-film/implem-component.md +++ b/resources/docs/docs/gestion-film/implem-component.md @@ -26,7 +26,7 @@ Dans le tableau, il te faut 6 colonnes (oui, on oublie la dernière avec les act ## Aide -❗Tu dois créer un service qui te permet d'appeler ton backend pour récupérer tous tes films : `MovieService`. +❗Tu dois utiliser ton `MoviesService` pour aller chercher les données. ❗Grâce à Bootstrap, la création du tableau est super simple ! Regarde la [documentation de Table](https://getbootstrap.com/docs/5.0/content/tables/){:target="\_blank"}. ❗Pense à bien formater la **date**. diff --git a/resources/docs/docs/gestion-film/navigation.md b/resources/docs/docs/gestion-film/navigation.md index b689ce08c8f9e1212c2241935dbc109cc31d9509..cfe022b54fdf40458352bffe6fbd8eb00ffcf555 100644 --- a/resources/docs/docs/gestion-film/navigation.md +++ b/resources/docs/docs/gestion-film/navigation.md @@ -53,7 +53,7 @@ export const appConfig: ApplicationConfig = { > On voit que l'import de `routes` est bien présent, que le fichier provide le `Router` d'Angular (avec `provideRouter`) et qu'on lui passe bien les routes en paramètres. Parfait ! ⭐ -Pour savoir si ce que l'on a fait fonctionne : rajoute */review* dans ton url après ton locahost (`http://localhost:4200/review`). Tu dois voir le contenu HTML de `ReviewComponent` : `<p>review works!</p>`. +Pour savoir si ce que l'on a fait fonctionne : rajoute */movies* dans ton url après ton localhost (`http://localhost:4200/movies`). Tu dois voir le contenu HTML de `MoviesComponent` : `<p>movies works!</p>`. ***C'est booon, les routes fonctionnent !!*** ⭐ @@ -67,7 +67,7 @@ Dans notre `NavbarComponent`, on peut ajouter un onglet *Gestion de films*. <nav class="navbar navbar-light navbar-expand bg-light ps-5"> <a class="navbar-brand">{{ title | titlecase }}</a> <a class="nav-item nav-link" href="#">Accueil</a> - <a class="nav-item nav-link" href="#">Gestion de films</a> + <a class="nav-item nav-link ms-3" href="#">Gestion de films</a> </nav> ``` @@ -77,7 +77,7 @@ On a donc 2 onglets : **Accueil** et **Gestion de films**. Ce sont des balises ` En Angular, nous n'utilisons pas `href` mais la directive `routerLink`. -À toi de jouer ! Remplace les `href` par des `routerLink` +À toi de jouer ! Remplace les `href` par des `routerLink` et importe `RouterLink`. ❗La valeur du routerLink doit correspondre aux **paths** indiqués dans les `Routes` > Le chemin du `MoviesComponent` est défini à 'review' dans le fichier `app.route.ts`. > Par contre, dans la directive routerLink, il faut le spécifier comme "/movies" (avec le /). @@ -88,7 +88,7 @@ Tu dois donc avoir : <nav class="navbar navbar-light navbar-expand bg-light ps-5"> <a class="navbar-brand">{{ title | titlecase }}</a> <a class="nav-item nav-link" routerLink="/">Accueil</a> - <a class="nav-item nav-link" routerLink="/movies">Gestion de films</a> + <a class="nav-item nav-link ms-3" routerLink="/movies">Gestion de films</a> </nav> ``` diff --git a/resources/docs/docs/premiere-page/home.md b/resources/docs/docs/premiere-page/home.md index 2edc313671102e985dc10605bc072776cae6217d..c8ade37e0b1eef9c2d382a02cf5d62cd2945b0ab 100644 --- a/resources/docs/docs/premiere-page/home.md +++ b/resources/docs/docs/premiere-page/home.md @@ -27,7 +27,7 @@ Les données à afficher sur la page viennent du backend que tu as lancé au mom ### 🚀 Notre objectif est donc de récupérer tous les films via un appel HTTP au backend et de les afficher sur notre page ### 1. Création du modèle -Pour récupérer tous les films nous utilisons ce [endpoint](http://localhost:8080/swagger-ui/index.html#/movie-controller/getMovies){:target="_blank"} qui est un appel GET +Pour récupérer tous les films nous utilisons ce [endpoint](http://localhost:8080/swagger-ui/index.html#/movie-controller/getMovies){:target="_blank"} qui est un appel GET. Elle retourne une liste d'objets Movie de cette forme : ``` { @@ -52,13 +52,13 @@ C'est parti : ```ts export interface Movie { - id: number; + id?: number; title: string; releaseDate: Date; director: string; - rate: number; + rate?: number; synopsis: string; - image: string; + image?: string; } ``` @@ -111,11 +111,11 @@ getMovies(): Observable<Movie[]> { Maintenant que ton appel au backend est accessible depuis la méthode `getMovies()` dans un service, tu dois l'appeler dans ton composant. Pour cela : -<ul> -<li>Rends-toi dans le fichier `home.component.ts`</li> -<li>Injecte ton service en créant une variable `private readonly moviesService = inject(MoviesService)`</li> -<li>Crée une variable pour récupérer ta liste de `Movie` : `movies$: Observable<Movie[]> = this.moviesService.getMovies()`</li> -</ul> + +- Rends-toi dans le fichier `home.component.ts` +- Injecte ton service en créant une variable `private readonly moviesService = inject(MoviesService)` +- Crée une variable pour récupérer ta liste de `Movie` : +```movies$: Observable<Movie[]> = this.moviesService.getMovies()``` > Comme vu un peu plus haut, on doit `subscribe` pour réellement trigger l'appel HTTP et récupérer le contenu d'un observable. On peut le faire de deux façons : > Soit en utilisant le `.subscribe()` comme ça : @@ -163,7 +163,7 @@ C'est parti ! ng g c home/movie ``` -Maintenant, on remplace nos balises `<p></p>` par notre nouveau composant dans le `HomeComponent` : +Maintenant, on remplace nos balises `<p></p>` par notre nouveau composant dans le `home.component.html` : ```angular17html @for (movie of movies$ | async; track movie.id) { <app-movie></app-movie> @@ -177,9 +177,11 @@ Nous avons besoin de passer les informations de la variable `movie` à notre `Mo - Dans `movie.component.ts`, on ajoute donc `@Input({required: true}) movie!: Movie` - Dans `home.component.html`, on ajoute le property binding `[movie]=movie` +Jette un oeil, à ton localhost maintenant que ca recompile ! On itère bien sur le `MovieComponent`. + On a donc accès à la variable `movie` dans le `movie.component.html` et on peut faire un truc tout beau ! -On te propose d'utiliser les [cards de Bootstrap](https://getbootstrap.com/docs/5.0/components/card/){:target="_blank"}. Tu peux t'inspirer de bout de code : +On te propose d'utiliser les [cards de Bootstrap](https://getbootstrap.com/docs/5.0/components/card/){:target="_blank"}. Tu peux t'inspirer de ce bout de code : ```angular17html <div class="card shadow m-4" style="width: 18rem; min-height: 55rem"> @if(movie.image) { diff --git a/resources/docs/docs/premiere-page/input.md b/resources/docs/docs/premiere-page/input.md index c2909a863298fdbe608f78ca97cebb9b810331ed..6ae38132b9ae2e0a7a20bbe055cab19e2d4f87d2 100644 --- a/resources/docs/docs/premiere-page/input.md +++ b/resources/docs/docs/premiere-page/input.md @@ -20,23 +20,27 @@ Cela se fait en deux étapes : > import { Input } from '@angular/core'; > ``` -- Va dans le fichier `navbar.component.html` et remplace le texte "Navbar" écrit en dur par ta variable `title`. -> 💡 On se souvient ! Pour afficher une variable TypeScript coté HTML, on utilise les *doubles moustaches* {{}} - -> 🤩 Tu peux ajouter le Pipe *titlecase* à l'intérieur de l'interpolation pour que le texte s'écrive avec une majuscule au début. -> ```{{ title | titlecase }}``` -> ⚠️ Attention, n'oublie pas l'import - ### 2. Passage du paramètre dans le composant parent - Normalement ton code ne compile plus. Tu devrais avoir une erreur `[ERROR] NG8008: Required input 'title' from component NavbarComponent must be specified. [plugin angular-compiler]`. En effet, on a ajouté une @Input required. - Rends-toi dans le fichier `app.component.html` -- Ajoute le property binding `[title]="title"` dans ton composant navbar +- Ajoute le property binding `[title]="title"` dans ton appel au composant navbar Tu dois avoir ceci : ``` <app-navbar [title]="title"></app-navbar> ``` +Ca recompile, mais on a rien changé visuellement non ? + +### 3. Utilisation de l'Input + +Va dans le fichier `navbar.component.html` et remplace le texte "Navbar" écrit en dur par ta variable `title`. +> 💡 On se souvient ! Pour afficher une variable TypeScript coté HTML, on utilise les *doubles moustaches* {{}} + +> 🤩 Tu peux ajouter le Pipe *titlecase* à l'intérieur de l'interpolation pour que le texte soit formatté avec une majuscule au début : +> ```{{ title | titlecase }}``` +> ⚠️ Attention, n'oublie pas l'import `TitleCasePipe` + Rends-toi sur [http://localhost:4200/](http://localhost:4200/){:target="_blank"} et vérifie que le titre que tu as défini est bien affiché dans ta navbar. > <h1> 🙋♀️ Checkpoint time 🙋♂️ diff --git a/resources/docs/docs/premiere-page/navbar.md b/resources/docs/docs/premiere-page/navbar.md index f2cf67e8d324adecbc01e483ddb06bca7f4621ff..eaebadbace1768e930f63c649ddfc7cd9dc4763d 100644 --- a/resources/docs/docs/premiere-page/navbar.md +++ b/resources/docs/docs/premiere-page/navbar.md @@ -47,7 +47,8 @@ Maintenant, ajoute : ```angular2html <app-navbar></app-navbar> ``` -><h2> ⚠️ Peu importe ce que tu utilises dans un composant, il faudra l'importer !</h2> +> ⚠️ On a une erreur de compilation : regarde sur ton localhost, tu vois le soucis ? +><h2>Peu importe ce que tu utilises dans un composant, il faudra l'importer !</h2> Rends-toi dans le `app.component.ts` : <ul> @@ -68,10 +69,10 @@ import { NavbarComponent } from "./navbar/navbar.component"; templateUrl: './app.component.html', styleUrl: './app.component.scss' }) -export class AppComponent { +export class AppComponent {...} ``` -> Si tu utilises l'IDE Intellij, il peut faire les imports automatiquement. +> Si tu utilises un IDE, il peut faire les imports automatiquement si tu commences par écrire la classe. Si tu retournes sur [http://localhost:4200/](http://localhost:4200/){:target="_blank"} , tu dois avoir: @@ -100,7 +101,7 @@ Tu dois avoir ce bouton qui s'affiche : ### 🎨 On fait une jolie navbar On utilise la navbar de Bootstrap comme expliqué [dans leur documentation](https://getbootstrap.com/docs/4.0/components/navbar/){:target="_blank"}. -Tu peux maintenant supprimer ton bouton bleu et le remplacer par : +Tu peux maintenant supprimer ton bouton bleu d'exemple et le remplacer par une vraie navbar : ```angular2html <nav class="navbar navbar-light navbar-expand bg-light ps-5"> <a class="navbar-brand">Navbar</a>