:: Enseignements :: ESIPE :: E3INFO :: 2024-2025 :: Programmation Web avec JavaScript ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
TP noté d'Application Web - session 1
|
Le but de ce TP est de réaliser une application de sélection de vol d'avions (flights)
et de trouver le vol ayant le prix le moins cher (Best Value).
Vous devez créer vos fichiers dans le répertoire EXAM qui est un sous répertoire de votre
répertoire home dans l'environnement de TP noté. Seuls les fichiers créés dans ce répertoire
seront sauvegarder. Donc si vous ne créez pas les fichiers dans le répertoire EXAM
mais dans un autre répertoire, ils ne seront pas sauvegardés, donc pas corrigés.
Comme environnement coupe les communications TCP vers l'extérieur,
Il est important de faire attention à la qualité du code que vous allez rendre.
Avoir un code qui semble marcher, mais qui n'est pas maintenable, pas compréhensible ou
qui contient du code mort (qui ne sert à rien) sera fortement pénalisé.
Voilà une idée graphique de l'application que l'on veut réaliser
Et voilà l'arbre DOM que l'on souhaite obtenir.
Exercice 1 - Flight
Dans un premier temps, récupérer un
tar.gz le contient la commande
esbuild
et les bibliothèques
react et
react-dom.
Décompresser l'archive (
tar zxvf flight-node-modules.tgz)
flight-node-modules.tgz
dans le répertoire
EXAM.
Rappel, pour transformer le fichier JSX en JS, on utilise la commande
./node_modules/.bin/esbuild flight.jsx --bundle --outfile=flight.js
L'API REST du serveur est définie comme ceci:
-
Obtenir tous les vols: GET /api/flights
Cet appel renvoi l'ensemble des vols au format JSON.
Pour simuler les possibles changements de prix, à chaque requête, un des vols a
son prix changé (+ ou - 10 dollars).
Vous pouvez tester en copiant dans votre navigateur http://localhost:8080/api/flights.
-
Supprimer un vol: DELETE /api/flights/id
Avec id, la valeur de l'id de l'évènement que l'on veut supprimer.
Cet appel renvoi un code 200 si cela s'est bien passé.
Pour démarrer, on va utiliser le fichier
flight.html suivant
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
<script src="flight.js" type="text/javascript"></script>
<style>
.app {
text-align: center;
margin: 20px;
}
button {
margin: 10px;
padding: 8px 16px;
cursor: pointer;
border-radius: 20px;
border: none;
background-color: #007bff;
color: white;
}
button:hover {
background-color: #0056b3;
}
table {
margin: 20px auto;
border-collapse: collapse;
width: 80%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #dfdfdf;
cursor: pointer;
}
/* Display the sort order */
th.sort::after {
content: " ↓";
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
/* Highlight the cheapest flight */
tr.highlight {
background-color: #ffff00af !important;
}
</style>
</head>
<body>
<div id="App"></div>
</body>
</html>
Et pour le fichier
flight.jsx suivant
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
function App() {
return <div className="app"></div>;
}
window.onload = () => {
const appDOM = document.getElementById("App");
const root = ReactDOM.createRoot(appDOM);
root.render(<App/>);
};
On utilisera de plus le serveur Java
JExpress.java
pour servir les fichiers
flight.html et
flight.js et l'API REST spécifique aux vols.
-
Utiliser esbuild pour ré-écrire le fichier JSX en fichier JS puis
lancer le serveur java --enable-preview JExpress.java dans le répertoire courant et
vérifier avec un navigateur que l'application s'affiche bien à l'adresse
http://localhost:8080/flight.html.
-
A partir de maintenant, on va modifier le fichier flight.jsx pour créer notre application,
et il ne faudra pas oublier après chaque modification de relancer esbuild
ou alors, vous pouvez utiliser l'option --watch.
Créer un composants FlightList qui permet d'afficher les vols (flight)
sous forme d'une table. Un vol est caractérisé par un aéroport de départ (from),
un aéroport d'arrivée (to), un temp de vol (duration) et un prix (price).
Pour récupérer les vols sur les vols, faite un appel asynchrone à l'API dans un useEffect.
Pour l'affichage de la durée de vol, le serveur renvoie la durée en minutes, vous utiliserez la fonction
suivante pour afficher la durée de vol en heure.
function toHour(minutes) {
return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
}
Pour les prix, ils sont en dollars.
Pour trouver la structure exacte, utiliser l'image de l'arbre DOM et de l'application ci-dessus.
Écrire le composant FlightList et visualiser que l'affichage est correcte.
Note: pour l'instant, on ne s'occupe pas des boutons.
Note2: penser que comme vous affichez une liste de vols, il ne faut pas oublier les clés pour React.
-
Ajouter un composant DeleteButton à la fin de chaque ligne, qui permet de supprimer
le vol correspondant.
Pour éviter trop d'aller-retour au serveur, le bouton "Delete" va demander la suppression au serveur
et si celle-ci est confirmée, supprimer la ligne dans l'affichage.
Attention, on vous demande de ne pas refaire un accès au serveur pour demander à nouveau la liste
des vols. Le changement au niveau de l'affichage est suffisant.
-
Ajouter un composant RefreshButton qui permet de remettre à jour la liste des vols
en redemandant au serveur la liste de vols. Le bouton doit être placé au-dessus de la table HTML.
-
On souhaite maintenant ajouter un composant CheapestButton qui met en sur-brillance (highlight)
le vol le moins cher parmi les vols affichés (il y a une classe pour cela dans le CSS).
La surbrillance doit disparaitre lorsque l'on demande un ré-affichage des vols avec le bouton "Refresh Flights"
car les prix peuvent avoir changé. Même chose si l'on demande la suppression d'un des vols.
Pour trouver le vol le moins chère, vous pouvez faire une boucle sur les vols ou (bonus) utiliser la méthode
reduce.
Ajouter le composant à l'application.
Note: vérifier que votre code ne plante pas si tous les vols ont été supprimée et
que l'on demande le vol le moins cher !
-
On veut maintenant pouvoir trier l'affichage des vols en fonction de l'aéroport de départ (from).
Pour cela, ajouter un composant qui permet de trier les vols si l'on clique sur le titre "From" de la table.
Par défaut, aucun trie le doit être fait, c'est uniquement lorsque l'utilisateur le demande que le trie
doit être fait.
Rappel: pour trier en JavaScript, on utilise une fonction de comparaison comme celle-ci
function compareFlight(f1, f2) {
if (f1.from < f2.from) {
return -1;
}
if (f1.from > f2.from) {
return 1;
}
return 0;
}
-
Vérifier que si un vol est en surbrillance, il doit rester en surbrillance (il sera juste déplacé par le trie).
Vérifier que si l'on rafraichit l'affichage en rechargeant les vols, le trie ne doit pas être remis à zéro.
Faites les changements qui s'imposent.
-
Enfin, modifier votre code pour qu'il marche aussi pour trier selon les autres colonnes
(to, duration, price), sachant que l'on ne peut trier qu'une colonne à la fois.
Attention, si vous avez trop de duplication dans votre code, je ne vais pas être content,
essayer d'avoir un seul et même code qui fait les différents tris.
-
Enfin, ajouter une flèche (regarder le CSS), qui indique visuellement la colonne
qui est triée (s'il y en a une).
© Université de Marne-la-Vallée