Vous êtes sur la page 1sur 72

Progressive Web App

EUSKADI

Introduction

Marc Flausino - contact@codigo.best


Introduction
• Une Progressive Web App (PWA) est une
application web qui consiste en des pages ou
des sites web, et qui peuvent apparaître à
l'utilisateur de la même manière que les
applications natives ou les applications
mobiles (source wiki)

• Ce type d’application va donc permettre de


mettre en place un « front » type Angular,
React, Vue, etc., tout en donnant accès aux
services du téléphone via des
librairies/packages.

Marc Flausino - contact@codigo.best


Pourquoi ?
• L’utilisation d’une PWA nous permet de faire • Le temps de développement en natif peut
abstraction du langage natif propre à l’OS du être considérable et il faut se dire que toute
téléphone. évolution/correction devra être répercutée
sur les 2 projets !
• Si l’on veut coder une application native pour
Android et iOS, on devra créer 2 projets avec :
• Pour Android : • Avec une application PWA, on ne code que
• Développer en Java avec le Android SDK dans le logiciel dans un seul projet 
Android Studio
• Pour iOS :
• Payer un abonnement Apple Developer de 99$ par an à
Apple
• Développer en Swift (ou autre) avec le sdk iOS dans le
logiciel Xcode

Marc Flausino - contact@codigo.best


Inconvénients
• Etant donné que l’on va passer par le framework
de type PWA pour accéder aux services natifs du
téléphone, cela pourra s’avérer plus fastidieux
qu’en natif dans certains cas.
• Il faut s’assurer d’utiliser un framework PWA
régulièrement mis à jour et robuste.

Marc Flausino - contact@codigo.best


EUSKADI

Ionic Framework

Marc Flausino - contact@codigo.best


Ionic
• Le framework Ionic est un outil open source • Au final, dans l’application PWA :
permettant de construire des PWA. • on utilisera principalement les
• Il fonctionne avec un CLI tout comme les fonctionnalités du framework JS
framework JS populaires, ce qui facilite son (Angular, React, etc.) pour la partie
utilisation. métier et intelligente.
• Ionic vient se greffer à un framework JS que • On utilisera Ionic pour les vues (pages
vous choisirez au moment de la création du html) via des tags ionic adaptés à la vue
projet. mobile et souvent très proches des tags
Angular Material (ex : mat-button -> ion-
button).
• On utilisera Ionic pour accéder aux
fonctionnalités du téléphone

Marc Flausino - contact@codigo.best


Ionic
• Vous l’aurez compris, tout est fait pour que la • De plus, si vous avez déjà développé un front,
mise en place d’une application PWA soit très vous pourrez copier/coller vos :
rapide. • Objets métiers (models)
• Services
• Css
• Code de composant
• Vues html
• Et vous n‘aurez qu’à modifier
• Vos vues html pour utiliser les tags ionic
• Un peu de css éventuellement
• Un peu de code des composants

• Le gain de temps est considérable !

Marc Flausino - contact@codigo.best


Ionic
• Pour utiliser les fonctionnalités natives du téléphone et
l’interface web (PWA), Ionic utilisait autrefois une
librairie cordova mais aujourd’hui il utilise capacitor.
• Pour utiliser des fonctions natives du téléphone, la
méthode a évolué et on doit installer désormais des
packages via npm.
• https://ionicframework.com/docs/native

• Attention donc quand vous tombez sur des aides sur


internet à ne pas utiliser des méthodes qui sont sur
l’ancienne version ! D’autant plus qu’on peut trouver
l’utilisation de certains packages cordova encore
aujourd’hui (cordova-res) ! On s’emmêle vite.
Marc Flausino - contact@codigo.best
EUSKADI

Mise en place

Marc Flausino - contact@codigo.best


Mise en place
• Prérequis : On estime que vous avez
déjà installé node et npm sur votre
ordinateur.

• Nous utiliserons Ionic 6 avec Angular


12+
• Avant de continuer, assurez vous
d’avoir une version 12 minimum de
Angular : https://update.angular.io/

Marc Flausino - contact@codigo.best


Mise en place
• Ionic met à disposition un outil • En règle générale, on installe cet outil
permettant de nous faciliter la vie : de façon globale car on en aura besoin
Ionic CLI dans nos différents projets.
• À noter : On prononce chaque lettre de • Pour installer l’outil, on va donc taper :
CLI en français ou en anglais.
npm install -g @ionic/cli
• Cet outil va nous permettre de créer
divers types de composants voir • À noter : si l’installation échoue car vous n’avez pas le
même un squelette de projet. droit d’exécuter des scripts powershell (ce dont a besoin
l’outil), il faut lancer cette commande avec windows
powershell.
Set-ExecutionPolicy -Scope CurrentUser -
ExecutionPolicy RemoteSigned
Cf : https://angular.io/guide/setup-local

Marc Flausino - contact@codigo.best


Mise en place
• Vérifiez l’installation en affichant la version via la commande :
ionic --version

• Ionic CLI va donc nous mettre à disposition toutes sortes d’actions pour :
• La création d’un projet : ionic start monprojet
• Le test du projet : ionic serve
• La generation de composants : ionic generate
• Etc.
• Il est possible d’utiliser des raccourcis pour les actions, par exemple g au lieu de
generate. Par contre, ce n’est pas toujours très bien documenté.

Pour voir les actions disponibles : ionic --help


Pour voir le detail d’une action : ionic --help <action>

https://ionicframework.com/docs/v3/cli/commands.html

Marc Flausino - contact@codigo.best


Mise en place
• Intéressons-nous à la
génération de composants :
ionic --help g

• On retrouve la même façon


de faire qu’avec Angular.

Marc Flausino - contact@codigo.best


Mise en place

• Attention : même si le CLI est très


utile, rien ne nous empêche d’utiliser
le CLI Angular pour créer nos
composants, classes, services, etc.
• C’est d’ailleurs fortement conseillé car
vous verrez que le CLI de Ionic est
limité à ce sujet.

Marc Flausino - contact@codigo.best


EUSKADI

Ma première application

Marc Flausino - contact@codigo.best


Ma première application
• Nous allons créer une application
d’exemple qui affiche votre profil, vos
compétences et vos projets (sans être
exhaustif).

Marc Flausino - contact@codigo.best


Ma première application
• Créons une première application via le
CLI. On tape la commande :
ionic start
• Et on répond :
• Utilisation wizard : Non
• Framework : Angular
• Nom de projet : mon-profil
• Starter template : tabs
• Pour créer une application en se basant sur le
template tabs
• Création compte ionic : Non

Marc Flausino - contact@codigo.best


Ma première application
• Quand le traitement est terminé, un
dossier mon-profil est créé. C’est le
projet.
• Ouvrez le via VS Code.

Marc Flausino - contact@codigo.best


EUSKADI

Structure

Marc Flausino - contact@codigo.best


Structure
• À la racine du projet on trouve les
fichiers de configuration divers :
• Capacitor
• Ionic
• Angular
• Node
• TypeScript
• Tests
• Git
• Etc.

Marc Flausino - contact@codigo.best


Structure
• Le répertoire src contient nos fichiers
source. C’est là que nous travaillons.
• Il y a plusieurs sous-répertoires :
• app : contient les divers composants
(composants, classes, services, etc.)
• assets : contient les fichiers statiques
(images, css, js, fonts, etc.)
• environnements : contient les variables
d’environnement de notre application

Marc Flausino - contact@codigo.best


Structure
• Dans les répertoires app et assets on
aura tendance à créer des sous-
répertoires pour organiser
proprement notre projet.

• Exemple ci-contre

Marc Flausino - contact@codigo.best


Structure
• Dans le répertoire theme, on trouve le
scss avec les variables qui permettent
de définir les couleurs par défaut et
vont ainsi définir la personnalité de
notre site.

http://ionicframework.com/docs/theming/

Marc Flausino - contact@codigo.best


Structure
Configuration globale
2 fichiers mis à disposition pour stocker nos
variables d’application :
• Environnement.ts
• Pour l’environnement de développement
• Environnement.prod.ts
• Pour l’environnement de production

• Quand on déploie en mode « production » le


fichier .prod est utilisé comme fichier
d’environnement. Donc, les valeurs propres à
l’environnement de production doivent être
définies dans ce fichier.
Marc Flausino - contact@codigo.best
Structure
Configuration globale

Rappelez-vous que le projet repose sur Angular


et qu’il se charge côté client (front), même si
c’est sur le téléphone de l’utilisateur, donc on ne
met pas de donnée critique dans le code (mot
de passe, clé privée, etc.).

• On pourra trouver dans ce fichier le


chemin vers l’API.

Marc Flausino - contact@codigo.best


EUSKADI

Utilisation

Marc Flausino - contact@codigo.best


Utilisation
• Il faut d’abord installer les packages • On accède via l’url : http://localhost:4200/
avec la commande :
npm install
• puis tester notre application cliente :
npm start

Marc Flausino - contact@codigo.best


Utilisation
• Que s’est-il passé ?

• On remarque dans package.json que notre


application est gérée par Angular quand on
lance la commande start : ng serve
• Cela est plutôt réconfortant, cela signifie
que la composition du projet web est en
grande partie gérée par Angular.
• En effet, comme dit précédemment Ionic
viendra ajouter une couche graphique via
les tags et s’occupera du déploiement et
de l’accès aux services natifs du téléphone
via certains packages.
Marc Flausino - contact@codigo.best
Utilisation
• Nous allons maintenant modifier les • Nous allons donc intervenir dans
libellés des tabs. Chaque tab plusieurs fichiers :
correspond en fait à une page, on y • tabs.page.html
accède via les boutons en bas de • Qui gère la création des 3 menus tabs
l’écran.
• tab<N>.page.html
• Où N est le numéro de la page, pour
chaque page

Marc Flausino - contact@codigo.best


Utilisation
• Faites en sorte de modifier les libellés • Nous allons donc intervenir dans
de la sorte : plusieurs fichiers :
• tabs.page.html
• Tab 1 devient Profil • Qui gère la création des 3 menus tabs
• Dans les tags ion-label
• Tab 2 devient Skills
• Tab 3 devient Projets • tab<N>.page.html
• Où N est le numéro de la page, pour
chaque page
• Dans les tags ion-title

Marc Flausino - contact@codigo.best


Utilisation
• Vous devriez voir les nouveaux libellés
correctement sur la page web.

Marc Flausino - contact@codigo.best


Utilisation
• Ce template utilise un composant • Nous allons supprimer ce composant
« explore-container » mutualisé dans pour intégrer notre propre contenu
chaque page tab. sur chaque page de tab.
• Supprimez la référence à ce composant
et son import dans les fichiers module de
• Suivez les étapes ci-contre puis chaque composant tab
redémarrez l’application via npm start (tab<N>.module.ts)
• Supprimez la référence à ce composant
dans chaque vue tab (tab<N>.page.html)
• Il n’y a plus de contenu sur les pages • Supprimez la référence à ce composant
et son import dans chaque test
(tab<N>.page.spec.ts)
• Supprimez le répertoire explore-
container

Marc Flausino - contact@codigo.best


EUSKADI

Page profil

Marc Flausino - contact@codigo.best


Page profil
• Avant de continuer, passons en vue « mobile » sur • Pour cela, nous utiliserons les
le navigateur
composants de vue de Ionic :
• https://ionicframework.com/docs/co
mponents

• Nous allons maintenant implémenter le contenu


sur la page Profil.
• Cette page doit contenir
• une photo de vous
• une phrase d’accroche
• ainsi qu’un bref descriptif de votre personnalité

Marc Flausino - contact@codigo.best


Page profil
• Composant principal et photo

• Copions d’abord l’exemple de composant card ci-dessous


dans la vue html du tag 1.
• https://ionicframework.com/docs/api/card#media-cards

• La page suivante montre le résultat

Marc Flausino - contact@codigo.best


Page profil

tab1.page.html -> Balise ion-content http://localhost:4200/tabs/tab1


<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Profil</ion-title>
</ion-toolbar>
</ion-header>

<ion-card>
<img alt="Silhouette of mountains"
src="https://ionicframework.com/docs/img/demos/card-media.png" />
<ion-card-header>
<ion-card-title>Card Title</ion-card-title>
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
</ion-card-header>

<ion-card-content>
Here's a small text description for the card content. Nothing more, nothing
less.
</ion-card-content>
</ion-card>

</ion-content>

Marc Flausino - contact@codigo.best


Page profil
• La balise ion-header définit une en- • Trouvez une photo de vous sur
tête. Elle sera positionnée en haut de internet et mettez le lien à la place de
son parent. l’image.
• La balise ion-content définit le • Modifiez la balise ion-card-title qui
contenu principal représente le titre et mettez votre
• La balise ion-card permet de créer nom et prénom
facilement des vues de type card tout • Modifiez la balise ion-card-subtitle
comme la balise mat-card avec qui représente le sous-titre et mettez
Angular Material. votre phrase d’accroche
• Modifiez la balise ion-card-content
qui représente le contenu de la card
et mettez votre descriptif
Marc Flausino - contact@codigo.best
Page profil
• N’oubliez pas que vous utilisez export class Tab1Page {

Angular, vous pouvez très bien name: string = "El Risitas";

déclarer des variables dans le constructor() {}


composant pour les utiliser dans la
vue html. }

<ion-card-header>
<ion-card-title>{{ name }}</ion-card-title>
<ion-card-subtitle>Me gusta las paelleras</ion-card-subtitle>
</ion-card-header>

Marc Flausino - contact@codigo.best


EUSKADI

Page Skills

Marc Flausino - contact@codigo.best


Page skills
• Pour la page skills, utilisons le composant List : ion-list
• https://ionicframework.com/docs/api/list

• Il ressemble beaucoup à mat-list de Angular Material.


• On y injecte des ion-item

Marc Flausino - contact@codigo.best


Page skills
• Ouvrons la page html du tab 2 et
ajoutons dans le ion-content une liste
avec un seul item.
<ion-list>
<ion-item>
<ion-icon name="star" slot="start"></ion-icon>
<ion-label>
<ion-text color="primary">Base de données</ion-
text>
<p>
<ion-chip color="success"
[outline]="true">Modélisation</ion-chip>
<ion-chip color="success">sql</ion-chip>
<ion-chip color="success">pl/sql</ion-chip>
<ion-chip color="success">DDL</ion-chip>
</p>
</ion-label>
</ion-item>
</ion-list>

Marc Flausino - contact@codigo.best


Page skills
• Quand on utilise des composants
ionic, il ne faut pas hésiter à consulter
<ion-list>
<ion-item>

la documentation qui est riche, claire <ion-icon name="star" slot="start"></ion-icon>


<ion-label>
et possède assez d’exemples pour text>
<ion-text color="primary">Base de données</ion-

mettre en œuvre rapidement du <p>

contenu. <ion-chip color="success"


[outline]="true">Modélisation</ion-chip>
<ion-chip color="success">sql</ion-chip>
<ion-chip color="success">pl/sql</ion-chip>
<ion-chip color="success">DDL</ion-chip>
• Ici nous avons créé un item dans une </p>
</ion-label>
liste. Cet item a un icône « star », un </ion-item>

label contenant du texte et une suite </ion-list>

de chip.

Marc Flausino - contact@codigo.best


Page skills
• Pour finaliser cette page, vous allez
créer une variable de type tableau
dans le composant contenant un
minimum de 5 de vos thématiques de
compétences avec une liste de mots
clés que vous afficherez sous forme de
chip.
• L’idée est que votre page html utilise ce
tableau pour alimenter
dynamiquement la ion-list.
• Vous devez faire en sorte de ne pouvoir
afficher l’icône star que pour certaines
thématiques.
Marc Flausino - contact@codigo.best
EUSKADI

Page projets

Marc Flausino - contact@codigo.best


Page projets
• Pour cette page projets vous allez
lister vos projets déjà réalisés.
• Nous allons utiliser le composant grid
avec le composant card.

Marc Flausino - contact@codigo.best


Page projets
• Créons un répertoire img dans le <ion-grid>
<ion-row>
répertoire assets du projet. <ion-col>
<ion-card>

• On dépose dans ce répertoire l’image <img alt="" src="/assets/img/esport.jpg" />


<ion-card-header>
qui servira pour présenter l’un de nos <ion-card-title>e-Sport</ion-card-title>

projets dans une card.


<ion-card-subtitle>Une app pour gérer les équipes
d'e-Sport</ion-card-subtitle>
</ion-card-header>

• Ensuite, on ajoute dans la page html <ion-card-content>


<ion-chip color="success" [outline]="true">Typescript</ion-
du tab 3 une grid dans ion-content chip>
<ion-chip color="success" [outline]="true">Angular</ion-chip>
<ion-chip color="success" [outline]="true">Spring</ion-chip>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>

Marc Flausino - contact@codigo.best


Page projets
• Pour finaliser cette page, vous allez
créer une variable de type tableau
dans le composant contenant un
minimum de 3 de vos projets avec
une liste de mots clés que vous
afficherez sous forme de chip.
• L’idée est que votre page html utilise
ce tableau pour alimenter
dynamiquement la ion-row.
• Vous aurez une ion-col par projet
• Ceux qui le souhaitent peuvent
implémenter l’icône star ou autre.
Marc Flausino - contact@codigo.best
EUSKADI

icônes

Marc Flausino - contact@codigo.best


icônes
• Ionic possède une librairie disponible • Changez les icônes des 3 tabs à votre
de plusieurs icônes. Néanmoins, vous guise, dans le fichier tabs.page.html
pourrez intégrer d’autres librairies via les balises ion-icon. Vous trouverez
d’icône comme vous le feriez pour une liste de nom d’icônes à cette
Angular. adresse :
• https://ionic.io/ionicons

Marc Flausino - contact@codigo.best


EUSKADI

Android Studio

Marc Flausino - contact@codigo.best


Android Studio
• Grâce à ionic nous pouvons facilement
tester notre application sur un émulateur
de téléphone ou même notre propre
téléphone.

• Nous allons devoir installer le logiciel


Android Studio qui permet de gérer les
applications Android.

• https://developer.android.com/studio/ins
tall?hl=fr

• Suivez bien la procédure d’installation.


Marc Flausino - contact@codigo.best
Android Studio
• Une fois que le logiciel est installé, • Tapez sdk et cliquez sur sdk manager.
démarrez-le.
• Une fois dans le logiciel, tapez
• Ctrl+Maj+A sous windows
• Cmd+Maj+A sous mac

• Ce raccourci est magique, il permet de


trouver tous types d’actions dans
Android Studio.

Marc Flausino - contact@codigo.best


Android Studio
• Assurez vous qu’un SDK est bien installé, idéalement Android 11.0 (R)

Marc Flausino - contact@codigo.best


Android Studio
• Dans l’onglet SDK Tools on vérifie
que sont bien installés Android
Emulator, Android SDK platform-
tools, Google USB Driver, SDK
Build tools
• Ces outils sont utiles pour gérer
l’émulation et certaines
fonctionnalités.

Marc Flausino - contact@codigo.best


Déploiement Android
• Il est temps de créer un émulateur, on clique
sur le bouton device manager en forme de
téléphone en haut à droite

• Puis, dans l’onglet Virtual, on clique sur


Create device. On choisit la catégorie Phone
puis Pixel 2.

Marc Flausino - contact@codigo.best


Déploiement Android
• Sur l’écran suivant, on sélectionne le SDK • Après ces étapes, notre émulateur est créé,
« R » Api 30. Puis Next puis Finish. on le voit dans la liste du Device Manager.

Marc Flausino - contact@codigo.best


Android Studio- configuration
• Vous aurez intérêt à ajouter dans les variables • Dans la variable Path, on pourra également ajouter les
d’environnement système ces 3 variables (exemple ci- chemins vers android studio ainsi que vers certains outils
dessous avec windows) en pointant sur le répertoire SDK du sdk. Cela permettra entre autre, quand ionic lancera la
d’Android en général situé dans le répertoire AppData de commande pour ouvrir le projet dans Android Studio à ce
votre répertoire utilisateur sous Windows et que la commande soit reconnue.
/Applications/ADT sous MAC

• Exemple d’entrées dans le path sous windows.

Marc Flausino - contact@codigo.best


EUSKADI

Déploiement Android

Marc Flausino - contact@codigo.best


Android Studio
• Nous allons tester notre déploiement • Dans le fichier capacitor.config.ts
sur Android mais avant cela, nous modifiez le appId. Ce sera le chemin
allons modifier quelques éléments du package lors de la conversion vers
dans la configuration par défaut. Android.
• Saisir : com.simplon.monprofil

Marc Flausino - contact@codigo.best


Déploiement Android
• Maintenant qu’Android Studio est installé, ajoutons une commande dans le
fichier package.json dans la partie scripts

"builddev": "ionic capacitor build android --configuration development",

• Cette commande permet de lancer le build pour android avec la config de


l’environnement de développement
• Puis on lance la commande via :
npm run builddev

Marc Flausino - contact@codigo.best


Déploiement Android
• La commande précédente de build va :
• Builder le projet
• Créer le répertoire projet android à la racine du
projet et créer/copier les fichiers nécessaires
dedans
• Lancer Android Studio avec ouverture de ce projet
android

• Attention : On devra relancer cette


commande à chaque fois que l’on veut
redéployer nos modifications sur android
pour les tester sur Android Studio.

Marc Flausino - contact@codigo.best


Déploiement Android
• Si tout va bien, vous voilà dans Android
Studio avec votre projet ouvert

• On retrouve à gauche le package java


com.simplon.monprofil avec la classe
principale qui va lancer notre application.
• Nous aborderons plus en détail
l’environnement Android Studio dans un
prochain cours.

Marc Flausino - contact@codigo.best


Déploiement Android
• Pour lancer notre application dans l’émulateur nous
devons le sélectionner si besoin en haut dans la
configuration de run.

• Une fois que c’est fait, on clique sur le bouton


• En bas à droite vous verrez la compilation se lancer via
Gradle (genre de npm), puis l’installation sur l’émulateur
et enfin le lancement de l’application sur laquelle vous
pourrez interagir.

Marc Flausino - contact@codigo.bestDF


Déploiement Android
• La vue Logcat, accessible tout en bas de l’écran permet de voir les logs
du téléphone, il est conseillé de filtrer avec le nom du package.

Marc Flausino - contact@codigo.best


EUSKADI

Plugins

Marc Flausino - contact@codigo.best


Plugins
• Pour accéder aux fonctionnalités natives du • On pourra déjà rechercher les plugins officiels sur
téléphone avec ionic on devra utiliser des plugins. le site de ionic :
• Dans la pratique, ce sont juste des packages que https://ionicframework.com/docs/native
l’on installera via npm. • Mais d’autres sont parfois disponibles sur npm.
• On devra donc se fier à la documentation (pas
toujours très complète ) de chaque plugin pour
comprendre comment l’utiliser. • À noter : Il faut admettre que l’utilisation de ces
plugins s’avère parfois une épreuve difficile
(erreurs, dysfonctionnements, pb
d’implémentation, manque de doc, etc.), bref,
soyez patients .

Marc Flausino - contact@codigo.best


Plugins
• Evidemment, pour tester ces fonctionnalités natives, on • Vous verrez à cette adresse quels types sont
renvoyés par chacune des méthodes de l’exemple et
devra le faire sur l’émulateur ou un vrai téléphone. en cliquant dessus vous aurez plus de détail :
• Suivez la procédure à cette adresse pour afficher sur votre
application, depuis l’émulateur, les informations du
téléphone :
https://ionicframework.com/docs/native/device

Voir page suivante…

Marc Flausino - contact@codigo.best


Plugins
• Vous pouvez laisser les console.log mais il faut également
afficher des informations dans la vue Profil :
• Le nom du téléphone (name)
• Le niveau de batterie (batteryLevel)

Marc Flausino - contact@codigo.best


EUSKADI

Le wizard
Petite parenthèse

Marc Flausino - contact@codigo.best


Le wizard
• Vous aurez peut être remarqué qu’un « wizard » est mis à
disposition pour nous aider à créer rapidement un projet
Ionic.

• https://ionicframework.com/start#basics

• Pour utiliser ce wizard il faudra créer un compte ionic ou lier


votre compte github/gitlab. Le wizard vous proposera
automatiquement de lier votre compte.
• Le wizard peut vous aider à créer rapidement un projet et le
déposer sur votre github/gitlab (à la racine).
• Cependant, à ce jour (février 2023) c’est une nouveauté et il
n’apporte pour l’instant pas de réel plus-value par rapport au
CLI. À suivre…
Marc Flausino - contact@codigo.best
Ce que l’on a vu dans ce cours…
• Introduction
• Ionic Framework
• Mise en place
• Ma première application
• Structure
• Utilisation / Création des pages
• Android Studio
• Déploiement Android
• Plugins
• Le wizard

Vous aimerez peut-être aussi