Aller au contenu
ArticlesPower Apps

Power Apps

Créer des Generative Pages Power Apps avec Claude Code

Guide pratique pour construire des pages model-driven app en React, TypeScript et Fluent UI V9 avec les outils de génération de code AI et le PAC CLI.

Les model-driven apps de Power Apps ont longtemps été limitées à des formulaires et des vues générées automatiquement. Avec l'arrivée des generative pages, les développeurs disposent désormais d'un levier puissant : construire des pages sur-mesure en React, TypeScript et Fluent UI V9, directement intégrées dans l'expérience model-driven. C'est une approche code-first qui ouvre des possibilités jusqu'ici réservées aux applications custom, tout en bénéficiant de l'infrastructure Dataverse.

Cet article guide pas à pas la création d'un Project Tracker Dashboard, une page de suivi de projets avec des indicateurs visuels, un tableau filtré et des graphiques, en s'appuyant sur les outils de génération de code et le PAC CLI.

Pourquoi les Generative Pages changent la donne

Jusqu'à présent, personnaliser une model-driven app impliquait soit de modifier des formulaires via le maker portal, soit de développer un PCF control complet. Les generative pages comblent cet écart :

  • React 17 + TypeScript : un stack familier pour les développeurs web
  • Fluent UI V9 : le design system Microsoft, cohérent avec l'écosystème Power Platform
  • Accès natif à Dataverse : via le dataApi fourni dans les props du composant
  • Déploiement en une commande : pac model genpage upload pousse le code directement dans l'environnement cible
  • Architecture single-file : un seul fichier .tsx par page, pas de bundler à configurer

Prerequisites

Avant de commencer, vérifier que les éléments suivants sont en place :

  • Node.js 18+ installé (LTS recommandé)
  • PAC CLI à jour (pac install latest ou via le Visual Studio Code extension)
  • Claude Code avec le plugin model-apps activé
  • Un environnement Dataverse avec au moins une table personnalisée (ici, Project avec des colonnes comme Name, Status, Budget, StartDate)
  • Une model-driven app existante dans laquelle intégrer la page

Étape 1 : Configuration du projet

Installer le plugin model-apps

Le plugin model-apps pour Claude Code fournit les outils nécessaires à la génération et au déploiement des generative pages. Une fois installé, il expose des commandes dédiées dans l'interface CLI.

S'authentifier avec PAC CLI

Code
pac auth create --environment https://yourorg.crm.dynamics.com

Vérifier la connexion :

Code
pac auth list
pac org who

L'environnement actif doit pointer vers l'organisation Dataverse cible. Si plusieurs profils d'authentification existent, sélectionner le bon avec pac auth select --index <n>.

Sélectionner l'environnement

Code
pac env select --environment <environment-id>

Cette étape est cruciale : toutes les opérations suivantes (génération de types, upload) s'exécutent contre cet environnement.

Étape 2 : Générer le schéma de types

C'est l'étape la plus critique du processus. Les noms de colonnes Dataverse ne correspondent pas toujours à ce que l'on attend. Un champ affiché comme "Project Name" dans le maker portal peut avoir un nom logique cr_projectname ou new_name selon le publisher prefix.

Code
pac model genpage generate-types \
  --data-sources "pblab_project,pblab_task,pblab_deliverable" \
  --output-file RuntimeTypes.ts

Cette commande interroge les métadonnées Dataverse et génère un fichier TypeScript contenant :

  • Les noms logiques exacts de chaque colonne
  • Les types TypeScript correspondants
  • Les valeurs d'enum pour les colonnes de type choice/optionset

Pourquoi c'est indispensable ? Sans cette étape, les outils de génération de code risquent d'halluciner des noms de colonnes. Un projectName au lieu de cr_projectname provoquera une erreur silencieuse : la page se charge, mais les données n'apparaissent pas. Le fichier de types généré sert de source de vérité pour tout le code qui suit.

Flux de génération du schéma : des tables Dataverse au fichier RuntimeTypes.ts

Étape 3 : Écrire la page

Avec le schéma en main, la construction de la page suit des patterns bien définis.

Structure de base

Chaque generative page exporte un composant React qui reçoit des GeneratedComponentProps :

Code
import type { GeneratedComponentProps } from "./RuntimeTypes";
import { makeStyles, tokens, Title1 } from "@fluentui/react-components";

const useStyles = makeStyles({
  root: {
    padding: tokens.spacingHorizontalXXL,
    display: "flex",
    flexDirection: "column",
    gap: tokens.spacingVerticalL,
  },
});

const ProjectDashboard = (props: GeneratedComponentProps) => {
  const styles = useStyles();
  const { dataApi } = props;

  // ... logique du composant

  return (
    <div className={styles.root}>
      <Title1>Project Tracker Dashboard</Title1>
      {/* contenu */}
    </div>
  );
};

export default ProjectDashboard;

Interroger Dataverse

Le dataApi expose une méthode queryTable qui permet de récupérer des enregistrements :

Code
const [projects, setProjects] = React.useState<any[]>([]);

React.useEffect(() => {
  const fetchProjects = async () => {
    const result = await dataApi.queryTable("pblab_project", {
      select: [
        "pblab_name",
        "pblab_status",
        "pblab_completion_pct",
        "pblab_start_date",
        "pblab_target_date",
      ],
      filter: "statecode eq 0",
      orderBy: "pblab_start_date desc",
      pageSize: 50,
    });
    setProjects(result.rows);
  };
  fetchProjects();
}, [dataApi]);

Gérer les formatted values pour les enums

Les colonnes de type choice (optionset) retournent une valeur numérique brute. Pour afficher le libellé lisible, utiliser les formatted values :

Code
// Valeur brute : 948000001
const statusValue = project["pblab_status"];

// Libelle formate : "Active"
const statusLabel =
  project["pblab_status@OData.Community.Display.V1.FormattedValue"];

C'est un pattern essentiel que beaucoup de développeurs découvrent tardivement. Les formatted values fonctionnent aussi pour les dates, les devises et les lookups.

Styliser avec Fluent UI V9

Les makeStyles de Fluent UI V9 utilisent des design tokens pour garantir la cohérence visuelle :

Code
const useStyles = makeStyles({
  card: {
    padding: tokens.spacingHorizontalL,
    borderRadius: tokens.borderRadiusMedium,
    backgroundColor: tokens.colorNeutralBackground1,
    boxShadow: tokens.shadow4,
  },
  statusBadge: {
    paddingInline: tokens.spacingHorizontalS,
    paddingBlock: tokens.spacingVerticalXS,
    borderRadius: tokens.borderRadiusCircular,
    fontSize: tokens.fontSizeBase200,
    fontWeight: tokens.fontWeightSemibold,
  },
});

Les tokens s'adaptent automatiquement au thème actif de l'application (clair, sombre, high contrast). C'est un avantage majeur par rapport à des styles CSS hardcodés.

Exemple : le dashboard complet

Le Project Tracker Dashboard combine ces patterns pour afficher :

  • KPI cards en haut : nombre de projets, budget total, projets en retard
  • Tableau filtrable : liste des projets avec tri par colonne
  • Indicateurs de statut : badges colorés selon le statut (On Track, At Risk, Delayed)
  • Graphique de répartition : ventilation des projets par statut

Dashboard Project Tracker dans une model-driven app

Chaque élément utilise exclusivement les composants Fluent UI V9 (Card, Table, Badge, ProgressBar) et les design tokens pour le styling.

Étape 4 : Déployer la page

Le déploiement se fait en une seule commande :

Code
pac model genpage upload \
  --app-id <app-id> \
  --code-file ./project-tracker-dashboard.tsx \
  --name "Project Tracker Dashboard" \
  --data-sources "pblab_project,pblab_task,pblab_deliverable" \
  --add-to-sitemap

Le PAC CLI compile le fichier TypeScript, le package et le pousse dans l'environnement Dataverse. La page devient immédiatement disponible dans la model-driven app cible.

Points importants :

  • Le --app-id parameter attend l'identifiant unique de la model-driven app
  • Le fichier doit être un single .tsx file autonome : pas de imports externes au-delà de React et Fluent UI
  • Les dépendances autorisées sont pré-packagées par la plateforme : React 17, Fluent UI V9, et le SDK Dataverse

Étape 5 : Vérifier le résultat

Ouvrir la model-driven app dans le navigateur. La nouvelle page apparaît dans la navigation latérale (si elle a été ajoutée au sitemap) ou peut être accédée directement via son URL.

Vérifier :

  1. Les données s'affichent correctement : si une colonne est vide, vérifier le nom logique dans le fichier de types
  2. Les formatted values sont lisibles : les enums affichent bien les libellés, pas les valeurs numériques
  3. Le responsive fonctionne : Fluent UI V9 gère le responsive nativement, mais tester sur différentes tailles d'écran
  4. Le thème s'applique : basculer entre thème clair et sombre pour vérifier les tokens
Pipeline de déploiement : du .tsx à l'app live en ~30 secondes

Points clés à retenir

Le schéma d'abord, le code ensuite. La génération de types via pac model genpage generate-types n'est pas optionnelle : c'est la fondation de tout le processus. Sans les noms logiques exacts, le code ne fonctionnera pas.

Architecture single-file. Chaque generative page est un fichier .tsx autonome. Pas de configuration webpack, pas de package.json, pas de build pipeline. La plateforme gère tout.

Fluent UI V9 et design tokens. Utiliser systématiquement les tokens plutôt que des valeurs CSS hardcodées garantit la cohérence visuelle et la compatibilité avec les thèmes.

Formatted values pour les enums. Le pattern @OData.Community.Display.V1.FormattedValue est indispensable pour afficher des données lisibles.

Production-ready dès le départ. Le code généré tourne directement dans l'environnement Dataverse : pas de staging intermédiaire, pas de serveur à maintenir.

Et après ?

Les generative pages sont actuellement en preview (mars 2026). Microsoft continue d'enrichir les capacités : support de composants plus complexes, accès étendu aux APIs Dataverse, et intégration plus poussée avec Copilot Studio.

Pour suivre les évolutions, consulter la documentation officielle sur Microsoft Learn - Generative pages for model-driven apps.

Les développeurs Power Platform qui maîtrisent React et TypeScript ont désormais un outil puissant pour créer des expériences model-driven app sur-mesure, sans quitter l'écosystème Dataverse. C'est une évolution majeure vers le code-first dans un univers historiquement low-code.