← Accueil

Comment faire un diagramme de Gantt avec Power Apps ?

👨🏻‍💻 Par Julien Leture · Expert technique SharePoint, Power Platform et Microsoft 365 Copilot
🗓️ 20 octobre 2023 · 🕖 22 minutes de lecture · 📖 Article original sur LinkedIn

L'objectif de cet article est de montrer comment construire avec Power Apps une application de gestion de projets sous forme de diagramme de Gantt. Que vous soyez développeur low-code ou consultant fonctionnel, il y aura forcément quelques informations utiles à récupérer dans cet article.

Objectifs

Les éléments à mettre en œuvre pour ce prototype sont :

Les éléments qui ne sont pas traités (mais qui sont traitables avec plus de temps dans une version postérieure au prototype) :

Attention ! Toutes les formules proposées dans cet article ne fonctionnent que si le navigateur est paramétré en anglais car le séparateur utilisé par Power Apps (Power Fx) n'est pas le même en fonction de la langue. Par exemple, en français, la virgule doit être remplacée par un point-virgule et le point-virgule doit être doublé !
Un conseil : toujours développer les Power Apps avec un navigateur en anglais 🇬🇧, ça sera plus simple, notamment pour récupérer les formules issues de la documentation.

Définition

Selon Wikipédia, "le diagramme de Gantt est un outil utilisé en gestion de projet permettant de visualiser dans le temps les diverses tâches composant un projet. Il s'agit d'une représentation d'un graphe connexe, valué et orienté, qui permet de représenter graphiquement l'avancement du projet. (...) Le concept a été nommé d'après Henry L. Gantt, ingénieur américain qui a publié la description du diagramme en 1910".

Recherche d'une solution existante

Je n'ai jamais eu l'occasion de mettre en pratique le développement d'une Power Apps avec un affichage de type "diagramme de Gantt" pour le compte d'un client.

Naturellement, j'ai fait une recherche sur internet afin de voir si certains avaient déjà eu l'occasion de faire ce genre d'application. Bingo 🥳 On trouve un article de 2021 d'un certain Ron Larsen : Gantt-like Display Using Standard Power Apps Controls.

L'article de Ron permet donc de valider que l'idée d'une telle application est réalisable avec Power Apps.

Diagramme de Gantt réalisé avec Power Apps - Ron Larsen - 2021
Diagramme de Gantt réalisé avec Power Apps - Ron Larsen - 2021

Datant de 2 ans, j'avais cependant envie de mettre en pratique par moi-même. Et peut-être que les nouveaux composants modernes introduits fin 2023 peuvent améliorer l'ergonomie 🤔

Également, j'avais envie d'estimer la charge de travail nécessaire pour mettre en place un prototype fonctionnel.

L'objectif n'est donc pas de "copier" le travail de Ron, mais bien de refaire à ma manière, en partant de zéro, une nouvelle application.

Et comme je n'avais pas envie de garder ce projet pour moi, je le partage ici, en français et sur LinkedIn !

Si tu as envie de savoir faire ça, cet article est fait pour toi !
Si tu as envie de savoir faire ça, cet article est fait pour toi !

Jeu de données avec ChatGPT

Depuis un an, impossible d'échapper à ChatGPT. Mais là encore, je n'avais jamais eu l'occasion de l'utiliser sérieusement dans un "vrai" projet afin de gagner du temps.

Pour cette réalisation, je me suis donc servi de ChatGPT afin de générer un jeu de données propre. Ne voulant pas utiliser une source de données externe pour ce prototype, une structure statique en JSON était suffisante. Afin de valider que l'affichage reste propre et réactif avec de nombreux projets, j'ai donc utilisé ChatGPT pour générer la structure attendue.

Génère une structure en JSON pour définir des projets avec un titre (propriété Title), une date de début (StartDate) et une date de fin (EndDate) positionnées en 2023, un pourcentage de progression entre 0 et 100 (Progress), un utilisateur défini par un prénom et un nom en français et une catégorie dont la valeur est une couleur en anglais (Tag)

Cette première requête était presque suffisante. Les projets avaient cependant des intitulés incrémentaux (Projet 1, Projet 2, etc.). Je lui ai donc demandé d'utiliser des noms de fruits pour nommer les projets et d'ajouter en plus une description qui explique les bienfaits du fruit 🍉

De même, le JSON retourné avait des double-quotes sur le nom des propriétés. Cela posait problème à Power Apps, je lui ai donc demandé de mettre les propriétés sans double-quote, même si cela ne respecte pas les standards.

Et voilà le résultat obtenu (extrait) :

[{
    Title: "Cerise",
    StartDate: "2023-01-25",
    EndDate: "2023-02-01",
    Tag: "Red",
    Progress: 10,
    Owner: "Lucas Dubois",
    Description: "Les cerises sont remplies d'antioxydants et aident à réduire l'inflammation."
  },
  {
    Title: "Ananas",
    StartDate: "2023-02-10",
    EndDate: "2023-02-17",
    Tag: "Yellow",
    Progress: 55,
    Owner: "Léo Lefebvre",
    Description: "L'ananas est riche en bromélaïne, bénéfique pour la digestion."
  },
  {
    Title: "Kiwi",
    StartDate: "2023-02-18",
    EndDate: "2023-02-25",
    Tag: "Red",
    Progress: 20,
    Owner: "Julie Rousseau",
    Description: "Les kiwis sont chargés de vitamine K, essentielle pour la coagulation sanguine."
  }]
Voilà donc un usage concret de ChatGPT pour gagner du temps sur des tâches annexes au projet mais qui permet d'avoir des données propres et en quantité. Avec ChatGPT, fini les projets 1, 2, 3 ou tests A, B, C !

Structure initiale

Paramétrage du responsive

Dans Power Apps Studio, afin de mettre en place un début de mode responsive, il convient de désactiver l'option « Scale to fit » dans les options de l'application. Cela permettra de profiter de toute la place disponible en fonction de la taille de l'écran. Dès lors, sur chaque composant à déposer à l'écran, plutôt que de mettre ou de laisser des tailles en dur (comme 640 x 480) on utilisera systématiquement Parent.Width et Parent.Height afin d'affecter dynamiquement la taille du composant en fonction de la fenêtre.

Il faut désactiver Scale to fit pour profiter de toute la largeur d'un écran
Il faut désactiver "Scale to fit" pour profiter de toute la largeur d'un écran
Ne jamais mettre en dur des largeurs
Ne jamais mettre en dur des largeurs

Ecran principal

Pour faire un affichage de type « diagramme de Gantt », l'astuce telle que décrite dans l'article original de Ron, est d'utiliser deux galeries superposées à mettre sur un même écran :

Le projet nécessite d'utiliser conjointement une galerie verticales et horizontale
Le projet nécessite d'utiliser conjointement une galerie verticales et horizontale

Galerie verticale : les projets

La galerie verticale doit être alimentée par la collection de projets déclarée dans le OnStart (variable Projects). Il suffit de modifier la carte de la galerie en ajoutant le titre, la date de début et de fin.

J'ai profité de la construction de la collection (Projects) pour ajouter une colonne calculée afin d'obtenir le nombre de jours entre la date de début et la date de fin :

ClearCollect(Projects, AddColumns(ProjectsRaw, "Duration", DateDiff(ThisRecord.StartDate, ThisRecord.EndDate) + 1));

J'ai opté pour l'affichage de ce nombre de jour sous la forme d'un badge (composant moderne) dans un rond qui reprend la couleur du projet.

Ici la couleur est associée à un projet. On aurait pu associer la couleur au statut du projet (non démarré, en retard, terminé, etc.). C'est un choix tout à fait possible. L'objectif de la couleur est de différencier les projets en entre eux. En pratique, cela peut signifier un type de projet, un département, une direction, un métier, etc.

Mise en forme des projets dans une galerie verticale
Mise en forme des projets dans une galerie verticale

Pour la progression, c'est la couleur de fond de la cellule qui donne une indication sous la forme d'un thermomètre horizontal 🌡️ avec un effet de transparence :

Width = (ProjectWidth - rectangleSelection.Width) * ThisItem.Progress / 100
Fill = ColorFade(ColorValue(ThisItem.Tag), 80%)

Galerie horizontale : les jours

La galerie horizontale permet d'afficher des jours sous forme de colonne. Chaque colonne correspond donc à une journée avec une largeur volontairement réduite.

Si on considère que le planning démarre au 1er janvier 2023, la première colonne sera donc le 1er janvier 2023. La deuxième colonne sera le jour suivant, etc. Ainsi, il suffit d'incrémenter de 1 la valeur de chaque cellule et d'afficher la date correspondante.

La date de départ doit être déclarée dans le OnStart de l'application, de même que le nombre de jours total à afficher dans le planning. Par exemple :

Set(CurrentStartDate, "2023-01-01");
Set(MaxDays, 365);

La propriétés Items de la galerie horizontale doit être une séquence numérique commençant à 0 jusqu'au nombre maximal de jour (MaxDays).

Parlons performance : au delà de 2 années, j'ai trouvé que l'affichage dans le navigateur commençait à ralentir.

Pour un premier test, autant rester sur une seule année (365 jours). La formule permettant de générer le tableau est donc :

Items = Sequence(MaxDays, 0)
Galerie verticale avec une séquence de 365 colonnes
Galerie verticale avec une séquence de 365 colonnes

Chaque cellule possède ainsi une valeur numérique (ThisItem.Value).

Pour convertir cette valeur en date, il suffit d'appliquer les formules suivantes afin d'incrémenter la date de départ :

Text(DateAdd(CurrentStartDate, ThisItem.Value), "ddd")
Text(DateAdd(CurrentStartDate, ThisItem.Value), "dd")
La galerie commence à se transformer en planning avec les bonnes dates
La galerie commence à se transformer en planning avec les bonnes dates

Petit à petit, on peut donc construire un affichage propre avec l'intitulé du jour et son numéro. On peut ajouter également un style grisé pour signaler les week-ends (samedi et dimanche).

Fill = If(Text(DateAdd(CurrentStartDate, ThisItem.Value), "ddd") = "Sat" || Text(DateAdd(CurrentStartDate, ThisItem.Value), "ddd") = "Sun", Color.LightGray, Color.White))

Enfin, à chaque 1er du mois, on affiche le libellé complet du mois et l'année (mmm yyyy).

Text = If(Text(DateAdd(CurrentStartDate, ThisItem.Value), "dd") = "01", "📅 " & Text(DateAdd(CurrentStartDate, ThisItem.Value), "mmmm yyyy"), "")

Au final, le résultat est le suivant :

Rendu final de la galerie horizontale
Rendu final de la galerie horizontale

Positionnement des projets

La grille du calendrier est désormais générée. L'écran est constitué de la sorte :

Les deux galeries en cours de construction, côte à côte sur le même écran
Les deux galeries en cours de construction, côte à côte sur le même écran

Il faut alors positionner les différents projets aux bonnes dates. Sachant que la première cellule correspond au 01/01/2023, si un projet démarre au 05/01/2023, il suffit de laisser 4 cellules vides et de commencer à la 5e cellule. Si le projet dure 3 jours, on remplit alors un rectangle de couleur d'une largeur équivalente à 3 jours.

Il est donc primordial de connaitre la largeur d'une journée. Pour mon prototype, j'ai choisi une largeur fixe de 90 pixels. Cette valeur est stockée dans une variable déclarée dans le OnStart : ColSize.

Set(ColSize, 90);

Il faut aussi connaitre la largeur de la « première colonne » qui correspond à l'affichage des projets dans la galerie verticale (la partie gauche). Dans mon cas, cette valeur est fixée à 240 pixels. D'un point de vue responsive, il aurait sûrement fallu faire un ratio de l'affichage (par exemple 1/5 de la largeur disponible avec une largeur minimale) :

Set(ProjectWidth, 240);

La valeur du X (position sur l'abscisse) pour la date de début d'un projet peut donc se calculer de cette manière :

Largeur de la première colonne + nombre de jours entre le 01/01/2023 et la date de démarrage * largeur d'une journée
X = ProjectWidth + DateDiff(CurrentStartDate, ThisItem.StartDate) * ColSize

La largeur du rectangle (Width) correspond donc au nombre de jours de la tâche, avec un minimum de 1 jour pour les dates qui tiennent en une seule journée, multiplié par la largeur d'une journée :

Width = (DateDiff(CurrentStartDate, ThisItem.EndDate) - DateDiff(CurrentDateYear, ThisItem.StartDate) + 1) * ColSize
Ça commence à prendre forme ! Note : sur la capture la variable CurrentStartDate est nommée CurrentDateYear (mais il s'agit bien de la même valeur)
Un rectangle permet de positionner le projet dans le planning avec sa couleur associée
Un rectangle permet de positionner le projet dans le planning avec sa couleur associée

A ce stade, la tâche est bien positionnée avec un rectangle qui correspond à la date de début et de fin du projet. Cependant, l'affichage se limite à la largeur de l'écran et il est impossible d'avoir tout le planning sur un seul écran.

Il va donc falloir faire un déplacement horizontal pour avancer ou reculer dans le temps. Ainsi la première cellule du planning ne sera pas forcément le 01/01/2023 mais le 15/01/2023 ou le 01/08/2023, selon le déplacement de l'utilisateur.

Il faut donc ajouter une deuxième translation sur le rectangle afin de calculer le décalage entre la première cellule (01/01/2023) du planning et la première cellule réellement affichée à l'écran.

Avant de présenter la solution technique, il faut permettre à l'utilisateur de changer la date d'affichage. J'ai mis en place quatre mécaniques complémentaire :

Choix d'une date par un calendrier ou des boutons précédent/suivant
Choix d'une date par un calendrier ou des boutons précédent/suivant
Slider pour changer la date ou bouton 01/01/2023 pour revenir au premier jour
Slider pour changer la date ou bouton 01/01/2023 pour revenir au premier jour

Afin que tous ces composants soient synchronisés entre eux, chacun calcule le delta entre la première date du planning (01/01/2023) et la nouvelle date. Ce décalage est stocké dans une variable nommée Offset (décalage).

Par défaut à 0, l'offset change donc à la manipulation de ces boutons. Par exemple, si j'avance d'une semaine, l'Offset vaut -7 car pour avancer dans le temps, on pousse vers la gauche le planning.

Dans le studio, on voit bien la galerie des dates se déplacer à l'horizontal
Dans le studio, on voit bien la galerie des dates se déplacer à l'horizontal

Pour le slider, on affecte cette formule :

OnChange = Set(Offset, Self.Value * -1);

Pour le date picker, on affecte cette formule :

OnChange = Set(Offset, DateDiff(datePicker.SelectedDate, CurrentStartDate));

Pour le bouton "semaine suivante", on affecte cette formule (OffsetStep est une variable déclarée dans le OnStart dont la valeur vaut 7) :

OnSelect = Set(Offset, Offset - OffsetStep);

La nouvelle formule de la position X du rectangle qui correspond à chaque projet doit donc prendre en compte cette nouvelle variable Offset :

X = ProjectWidth + DateDiff(CurrentStartDate, ThisItem.StartDate) * ColSize + Offset * ColSize

Egalement, au clic sur un projet, le planning se positionne automatiquement à la date de démarrage. Il faut donc modifier la valeur du Offset avec cette formule :

OnSelect = Set(Offset, DateDiff(ThisItem.StartDate, CurrentStartDate))

Panneau d'information

La sélection d'un projet permet de se positionner à la date de démarrage. Mais cela affiche également sur la droite un panneau d'information avec le détail du projet, dont la description et l'avancement sous forme d'un thermomètre horizontal.

Détail du projet sur la droite
Détail du projet sur la droite

Ce panneau est masqué si la largeur de l'écran est insuffisante. Pour cela, il faut ajouter dans le OnVisible de l'écran, une variable qui va tester la largeur de l'écran par rapport à des constantes prédéfinies (smartphone, tablette, ordinateur) :

Set(LargeScreen, Self.Size >= ScreenSize.Large);

Ensuite, sur la panneau de droite, il faut conditionner la valeur de Visible :

Visible = LargeScreen

Même sans le panneau de droite, l'affichage sur mobile (mode responsive) n'est pas optimal. C'est une limite connue et acceptable pour un prototype. En revanche, sur un écran très large, on bénéficie d'un planning très étendu !

Rendu sur smartphone
Rendu sur smartphone
Rendu sur un écran large
Rendu sur un écran large

Filtres et tris

De manière très classique, j'ai ajouté dans l'entête une zone de texte afin de filtrer les données affichées. La propriété Items de la galerie des projets se charge de faire un filtre sur l'ensemble des propriétés du projet (titre, progression, description, etc.).

Barre de filtre dans l'entête
Barre de filtre dans l'entête

La valeur du filtre est mis dans une variable déclarée dans le OnStart (Filter). Cette valeur est ensuite utilisée pour filter les données sur la galerie des projets :

Items = If(Filter <> "", Filter(Projects, Filter in Title || Filter in Tag || Filter in Progress || Filter in Owner), Projects)

Pour les tris, des boutons ont été ajoutés au dessus des projets. Deux types de boutons sont présents :

Il y avait probablement mieux à faire d'un point de vue ergonomie et expérience utilisateur ! J'attends vos retours dans les commentaires 📑

Items = If(SortByDays,
 Sort(Projects, Duration, If(SortDirAsc, SortOrder.Ascending, SortOrder.Descending)),
 If(SortByDates, ...
Attention, il faut en réalité combiner le tri et le filtre. La formule de Items est donc plus complexe que celle fournie dans ce bloc de code. En pratique, un tel projet ne manipulera pas une structure JSON mais bien une source de données externe (Dataverse, SQL, etc.). Il faudra donc déléguer à la source le filtre et le tri, et non les gérer en local par Power Apps.
Boutons de tri au dessus des projets
Boutons de tri au dessus des projets

Tâches d'un projet

A ce stage, l'écran n'affiche que des projets.

En réalité, dans un diagramme de Gantt on trouve des projets et un ensemble de tâches affectées à ce projet. C'est là qu'intervient la notion de prérequis : certaines tâches ne peuvent démarrées que si la précédente est terminée. La gestion d'un projet n'est pas le thème de cet article, mais la visualisation de ce comportement est cependant primordial et doit faire parti du prototype.

J'ai donc fait évoluer la structure JSON du jeu de données pour introduire la notion de projet parent. Bien sûr, il aurait fallu utiliser des identifiants internes ou des codes uniques pour chaque projet. Dans cet exemple, c'est le nom du projet qui sert de clé.

Exemple (extrait) :

Set(ProjectsRaw, [
  {
    Title: "Power Apps Gantt",
    StartDate: "2023-01-02",
    EndDate: "2023-03-10",
    Tag: "Green",
    Progress: 0,
    Owner: "Julien Leture",
    Description: "Try to create a Gantt application with Power Apps Canvas.",
    ParentProject: ""
  },
  {
    Title: "Pre sales",
    StartDate: "2023-01-02",
    EndDate: "2023-01-12",
    Tag: "Green",
    Progress: 100,
    Owner: "Julien Leture",
    Description: "",
    ParentProject: "Power Apps Gantt"
  },
  {
    Title: "Prototype",
    StartDate: "2023-01-18",
    EndDate: "2023-01-20",
    Tag: "Green",
    Progress: 80,
    Owner: "Julien Leture",
    Description: "",
    ParentProject: "Power Apps Gantt"
  },
  {
    Title: "Specifications",
    StartDate: "2023-01-18",
    EndDate: "2023-02-03",
    Tag: "Green",
    Progress: 10,
    Owner: "Pierre Frambois",
    Description: "",
    ParentProject: "Power Apps Gantt"
  }]
);

Par défaut, la galerie n'affiche que les projets, sans leurs tâches. Les projets ayant des enfants se voient attribuer un nouveau bouton à bascule (toggle 🔘) afin de pouvoir déplier, et donc afficher, les tâches associées.

Ce bouton est conditionné par la présence d'enfants, donc de projets qui ont pour parent le projet courant. Un LookUp permet de le vérifier et de conditionner la propriété Visible :

Visible = ThisItem.ParentProject = "" && Not(IsBlank(LookUp(Projects, ParentProject = ThisItem.Title)))

Pour les sous-tâches d'un projet, j'ai ajouté une petite barre horizontale sur la gauche pour montrer la filiation avec le projet parent.

Projet qui contient des tâches associées
Projet qui contient des tâches associées
Voilà qui permet de terminer ce prototype ! 👏 Tous les comportements attendus sont intégrés et fonctionnels.

Composants modernes

Ce prototype est aussi l'occasion d'utiliser les nouveaux composants modernes de Power Apps Canvas introduits début 2023 en preview. Pour information, on peut combiner les anciens et les nouveaux composants, y compris dans la carte d'une galerie.

Egalement, les composants modernes n'étant sont pas encore en GA (General Availability) aujourd'hui, il faut donc les activer dans les options de l'application : Modern controls and themes.

Composants modernes
Composants modernes

Un des ajouts les plus appréciables est l'arrivée des thèmes de couleur. En changeant de thème, toutes les couleurs (et leur dégradé) s'adaptent. Plus besoin de repasser sur chaque composant pour modifier la couleur de fond, de survol, de la bordure !

Pour le moment, seuls les thèmes natifs sont utilisables, mais il est évident que l'on pourra bientôt créer ses propres thèmes pour respecter la charte du client et la partager au sein de plusieurs applications.

Changement du thème en un clic
Changement du thème en un clic

Pour utiliser la couleur du thème dans son projet, il suffit d'utiliser les propriétés accessible par App.Theme.Colors. Outre Primary qui est la couleur de base, on trouve les nuances sombres (de Dark10 à Dark80) et claires (de Lighter10 à Lighter80).

App.Theme.Colors.Primary
App.Theme.Colors.Dark10
App.Theme.Colors.Lighter10

Un des nouveaux composants proposés est l'entête (header) qui permet d'afficher un logo et un titre sur la gauche et le profil de l'utilisateur connecté sur la droite. Tout cela en déposant le composant sur un écran sans rien configurer de plus ! La couleur étant bien sûr reprise du thème.

L'entête s'obtient en un clic. Seule la barre de recherche a été ajoutée en plus.
L'entête s'obtient en un clic. Seule la barre de recherche a été ajoutée en plus.
Les composants modernes sont dans un onglet à part
Les composants modernes sont dans un onglet à part

Chiffrage

Outre l'objectif de faisabilité qui était validé avant même de commencer grâce à l'article publié en 2021 sur un forum par un certain Ron, ce prototype devait aussi servir à estimer le temps de réalisation.

Ma consommation sur le projet est la suivante :

On arrive donc à 2 jours de travail pour avoir un prototype propre et fonctionnel 🎉 Bien sûr je ne suis pas novice sur Power Apps, j'accumule quelques années d'expériences, ce chiffre est donc une estimation qui peut varier en fonction du profil. Mais ne comptez pas faire ce travail en 1 heure. En revanche, 10 jours, par exemple, serait surévalué.
Pour rappel, les données utilisées ici sont statiques, évitant de fait la délégation, qui est un point fondamental dans une Power Apps (déléguer signifie laisser gérer le fournisseur de donnée les filtres et les tris pour éviter de le faire faire par la Power Apps en local).

Plus spécifiquement, pour des diagrammes de Gantt, la collision entre les projets et les règles de gestion sur les dépendances ne sont pas traitées : ce prototype ne sert qu'à mettre en place l'affichage et le filtrage des données.

Bonus

En plus de la vue Gantt, j'ai créé trois autres écrans :

Ecran d'accueil pour choisir sa vue
Ecran d'accueil pour choisir sa vue
Galerie de projets avec un filtre par couleur
Galerie de projets avec un filtre par couleur
Vue sous forme de graphe pour suivre la progression
Vue sous forme de graphe pour suivre la progression
Vue graph réduite à un seul projet avec ses tâches
Vue graph réduite à un seul projet avec ses tâches

Résumé

Réaliser un diagramme de Gantt avec Power Apps, c'est possible ! Avec deux galeries (l'une pour les projets et l'autre pour le planning), le tour est joué. Pour faciliter la construction de cette application, toutes les variables doivent être déclarées dans le OnStart de l'application. Notamment :

Il ne faut pas tomber dans le piège de mettre en dur certaines valeurs comme la largeur de chaque jour ou le décalage initial sur la gauche. Avec ces variables il devient très facile de modifier profondément l'affichage.

Vous voulez faire un zoom sur le planning ? Il suffit d'ajouter un bouton qui modifie la valeur de ColWidth et tout se recalcule automatiquement. Vous voulez changer la date de début ? Il suffit de modifier CurrentStartDate (d'où le Current dans le nom de la variable, l'idée étant de pouvoir paginer par année le diagramme).

A vous de low-coder ! 👨🏫

Une variable modifiée et tout l'affichage s'adapte, ici pour réduire la largeur de chaque journée
Une variable modifiée et tout l'affichage s'adapte, ici pour réduire la largeur de chaque journée
N'hésitez pas à laisser un message dans les commentaires LinkedIn ou à partager cet article, cela me donnera de la visibilité et permettra de récompenser mon travail. Merci 🥰

#powerapps #gantt #powerplatform #lowcode