Uniformisation modale staff (Gestionnaire / Administrateur) + champs contrôlés #164

Closed
opened 2026-09-14 12:57:15 +00:00 by jmartin · 1 comment
Owner

Contexte

Dernière brique UX 0.1.0 : uniformiser la modale création/édition Gestionnaire / Administrateur (AdminUserFormDialog) sur le design system déjà OK des fiches dashboard (parent / AM / enfant / wizards).

Captures « pas OK » : AlertDialog 620, labels flottants Material, footer Material « Modifier », titres avec guillemets.

Réf. dépôt : docs/tmp/modales-staff-uniformisation-mini-spec.md


Mini-spec — Uniformisation modale staff (Gestionnaire / Administrateur)

Ticket : #164#164
Branche : feature/164-staff-modal-uniformisation (depuis develop)
Périmètre : front only — pas d’API / BDD
Milestone : 0.1.0


Objectif

Aligner la modale création / édition / consultation Gestionnaire et Administrateur (AdminUserFormDialog) sur le design system déjà OK des fiches dashboard (parent / AM / enfant / wizards validation).

Référence visuelle / code OK :

Référence Fichier
Shell 930 + header + footer ParentEditModal, AmEditModal, ChildDetailModal
Thème primaire ValidationModalTheme (0xFF6D4EA1, primaryElevatedStyle)
Champs contrôlés ValidationLabeledField + Validation*Field (validation_detail_section.dart)
Métriques ValidationFormMetrics

Cible « pas OK » (captures) :

Cible Fichier
Créer / Modifier / Consulter gestionnaire ou admin screens/administrateurs/creation/gestionnaires_create.dartAdminUserFormDialog

Appels existants à préserver (API / droits inchangés) :

  • user_management_panel.dart (création)
  • gestionnaire_management_widget.dart (édition)
  • admin_management_widget.dart (édition admin)

Problème actuel

Aspect Aujourd’hui Cible
Shell AlertDialog Material, largeur 620 Dialog custom, largeur 930, BorderRadius.circular(12)
Titre Modifier un "Gestionnaire" + avatar Titre clair sans guillemets ; icône rôle optionnelle discrète
Champs InputDecoration label flottant (bordure qui coupe le libellé) Label au-dessus (ValidationLabeledField)
Contrôles saisie Mixte (FrenchPhoneTextFormField / EmailTextFormField / TF bruts) Même famille que les fiches OK (ValidationPhoneField, ValidationEmailField, etc.)
Footer Actions Material à droite (FilledButton.icon « Modifier ») Fermer/Annuler à gauche · primaire pill · dirty-state
Dirty Absent (toujours « Modifier ») Sauvegarder / Aucune modification (édition)

UX cible

Shell

  1. Dialog + ConstrainedBox(maxWidth: 930) + coins 12
  2. Header : titre + IconButton close (X)
  3. Divider sous header (comme fiches)
  4. Corps scrollable si besoin
  5. Footer fixe :
    • gauche : Fermer (édition / lecture) ou Annuler (création) ; Supprimer rouge à gauche si droit (#154 / #160) — même logique que ChildDetailModal
    • droite : primaire ValidationModalTheme.primaryElevatedStyle

Titres

Mode Titre
Création Créer un gestionnaire / Créer un administrateur
Édition Prénom NOM (personne) + sous-titre rôle si utile (Gestionnaire, Administrateur)
Lecture seule Même en-tête + champs disabled / readOnly

Interdit : guillemets autour du rôle ("Gestionnaire").

Layout champs (édition / création)

Ordre proposé (proche de l’existant, style OK) :

[ Prénom ]  [ Nom ]
[ Email ]
[ Mot de passe / Nouveau mot de passe ]  [ Téléphone ]
[ Relais principal ]   ← seulement si withRelais == true (gestionnaire)
  • Pas d’adresse / CP / ville ici (hors modèle staff actuel) → ne pas brancher le IdentityBlock complet (il force ces champs).
  • Réutiliser les briques ValidationLabeledField + champs contrôlés ci-dessous.

Boutons primaires

Mode Libellé primaire
Création Créer (disabled si formulaire invalide / submit en cours)
Édition Sauvegarder si dirty, sinon Aucune modification (disabled)
Lecture Pas de primaire (ou uniquement Fermer)

Champs contrôlés (obligatoire)

Réutiliser les widgets / utils déjà utilisés par les wizards et fiches. Pas de validation « maison » divergente.

Champ Widget / formatters Contrôles attendus
Prénom ValidationEditableField + PersonNameInputFormatter Requis (création / édition sauf identité verrouillée super_admin) ; trim / casse cohérente à la sauvegarde (comportement actuel _toTitleCase OK)
Nom idem idem
Email ValidationEmailField Requis ; normalise minuscules + trim au blur ; validateEmail ; max length via EmailMaxLengthFormatter
Téléphone ValidationPhoneField Formatage live FR (formatPhoneForDisplay) ; validateFrenchNationalPhone ; requis en création ; en édition : conserver règle actuelle (vide autorisé ou aligner sur fiche parent — décision : requis si renseigné, format FR strict ; création = requis)
Mot de passe TF stylé comme ValidationLabeledField + obscure toggle Création : requis, min 6 car. ; Édition : optionnel (vide = ne pas changer) ; pas d’autofill agressif en édition
Relais principal DropdownButtonFormField restylé (même décoration / hauteur que ValidationFieldDecoration) Liste existante RelaisService ; valeur null = « Aucun relais » ; disabled si loading / readOnly

Règles métier à conserver (non-régression)

  • readOnly : consultation sans save
  • adminMode / withRelais : admin sans relais ; gestionnaire avec
  • Verrouillage identité super_admin (_isLockedAdminIdentity)
  • Droits suppression (canDeleteGestionnaire / lignes SuppressionPersonLine)
  • Confirm suppression via showSuppressionConfirmDialog
  • Payloads create / update UserService inchangés (hors format téléphone normalisé à l’envoi, déjà le cas)

Implémentation suggérée

  1. Refactor UI de AdminUserFormDialog : remplacer AlertDialog par shell type fiches.
  2. Form : Form + ValidationLabeledField / ValidationEmailField / ValidationPhoneField / TF MDP aligné.
  3. Optionnel (si ça évite la copie) : extraire un petit DashboardFormModalShell (header / divider / footer) partagé — pas obligatoire pour livrer ; OK de dupliquer le pattern une fois comme les autres fiches.
  4. Déplacer le fichier (optionnel, même ticket ou follow-up) :
    screens/administrateurs/creation/gestionnaires_create.dartwidgets/dashboard/staff_user_form_modal.dart (rename classe StaffUserFormModal ou garder AdminUserFormDialog temporairement pour limiter le diff).
    Décision recommandée : rename fichier + classe StaffUserFormModal + update imports (cohérent #155).
  5. Smoke manuel : créer / éditer gestionnaire + admin ; téléphone invalide ; email invalide ; MDP court ; supprimer (si droit).

Hors scope

  • Refonte des fiches parent / AM / enfant (déjà OK)
  • Wizards validation dossier
  • Modales relais / DetailModal 620 / autres AlertDialog métier
  • Extraction forcée d’un design system Flutter packages
  • Back / règles droits (#154 / #160 déjà livrés)

Critères d’acceptation

  • Modale staff (gestionnaire et admin) : shell 930, header + divider + footer alignés fiches OK
  • Plus de titre avec guillemets autour du rôle
  • Labels au-dessus des champs (plus de label flottant Material qui coupe la bordure)
  • Email : format + normalisation blur ; refus email invalide au submit
  • Téléphone : format FR live + validation ; refus numéro invalide au submit
  • MDP : règles création / édition inchangées fonctionnellement, look aligné
  • Relais (gestionnaire) : dropdown restylé, même comportement
  • Dirty-state édition : Sauvegarder / Aucune modification
  • Suppression : bouton rouge à gauche + confirm existante
  • Création / édition / lecture / droits : non-régression fonctionnelle
  • rg AdminUserFormDialog → 0 ou alias de transition documenté ; imports à jour

Vérif

# Après rename éventuel
rg -n 'AdminUserFormDialog|gestionnaires_create' frontend/lib

# Les champs staff passent bien par la famille Validation*
rg -n 'ValidationEmailField|ValidationPhoneField|ValidationLabeledField|ValidationModalTheme' \
  frontend/lib/widgets/dashboard/staff_user_form_modal.dart \
  frontend/lib/screens/administrateurs/creation/gestionnaires_create.dart
## Contexte Dernière brique UX **0.1.0** : uniformiser la modale création/édition **Gestionnaire / Administrateur** (`AdminUserFormDialog`) sur le design system déjà OK des fiches dashboard (parent / AM / enfant / wizards). Captures « pas OK » : `AlertDialog` 620, labels flottants Material, footer Material « Modifier », titres avec guillemets. Réf. dépôt : `docs/tmp/modales-staff-uniformisation-mini-spec.md` --- # Mini-spec — Uniformisation modale staff (Gestionnaire / Administrateur) **Ticket** : **#164** — https://git.ptits-pas.fr/jmartin/petitspas/issues/164 **Branche** : `feature/164-staff-modal-uniformisation` (depuis `develop`) **Périmètre** : **front only** — pas d’API / BDD **Milestone** : **0.1.0** --- ## Objectif Aligner la modale création / édition / consultation **Gestionnaire** et **Administrateur** (`AdminUserFormDialog`) sur le design system déjà OK des fiches dashboard (parent / AM / enfant / wizards validation). Référence visuelle / code OK : | Référence | Fichier | |-----------|---------| | Shell 930 + header + footer | `ParentEditModal`, `AmEditModal`, `ChildDetailModal` | | Thème primaire | `ValidationModalTheme` (`0xFF6D4EA1`, `primaryElevatedStyle`) | | Champs contrôlés | `ValidationLabeledField` + `Validation*Field` (`validation_detail_section.dart`) | | Métriques | `ValidationFormMetrics` | Cible « pas OK » (captures) : | Cible | Fichier | |-------|---------| | Créer / Modifier / Consulter gestionnaire ou admin | `screens/administrateurs/creation/gestionnaires_create.dart` → `AdminUserFormDialog` | Appels existants à préserver (API / droits inchangés) : - `user_management_panel.dart` (création) - `gestionnaire_management_widget.dart` (édition) - `admin_management_widget.dart` (édition admin) --- ## Problème actuel | Aspect | Aujourd’hui | Cible | |--------|-------------|-------| | Shell | `AlertDialog` Material, largeur **620** | `Dialog` custom, largeur **930**, `BorderRadius.circular(12)` | | Titre | `Modifier un "Gestionnaire"` + avatar | Titre clair sans guillemets ; icône rôle optionnelle discrète | | Champs | `InputDecoration` label flottant (bordure qui coupe le libellé) | Label **au-dessus** (`ValidationLabeledField`) | | Contrôles saisie | Mixte (`FrenchPhoneTextFormField` / `EmailTextFormField` / TF bruts) | **Même famille** que les fiches OK (`ValidationPhoneField`, `ValidationEmailField`, etc.) | | Footer | Actions Material à droite (`FilledButton.icon` « Modifier ») | `Fermer`/`Annuler` à gauche · primaire pill · dirty-state | | Dirty | Absent (toujours « Modifier ») | `Sauvegarder` / `Aucune modification` (édition) | --- ## UX cible ### Shell 1. `Dialog` + `ConstrainedBox(maxWidth: 930)` + coins 12 2. Header : titre + `IconButton` close (`X`) 3. `Divider` sous header (comme fiches) 4. Corps scrollable si besoin 5. Footer fixe : - gauche : `Fermer` (édition / lecture) ou `Annuler` (création) ; `Supprimer` rouge **à gauche** si droit (#154 / #160) — même logique que `ChildDetailModal` - droite : primaire `ValidationModalTheme.primaryElevatedStyle` ### Titres | Mode | Titre | |------|-------| | Création | `Créer un gestionnaire` / `Créer un administrateur` | | Édition | `Prénom NOM` (personne) + sous-titre rôle si utile (`Gestionnaire`, `Administrateur`) | | Lecture seule | Même en-tête + champs disabled / readOnly | **Interdit** : guillemets autour du rôle (`"Gestionnaire"`). ### Layout champs (édition / création) Ordre proposé (proche de l’existant, style OK) : ``` [ Prénom ] [ Nom ] [ Email ] [ Mot de passe / Nouveau mot de passe ] [ Téléphone ] [ Relais principal ] ← seulement si withRelais == true (gestionnaire) ``` - **Pas** d’adresse / CP / ville ici (hors modèle staff actuel) → **ne pas** brancher le `IdentityBlock` complet (il force ces champs). - Réutiliser les **briques** `ValidationLabeledField` + champs contrôlés ci-dessous. ### Boutons primaires | Mode | Libellé primaire | |------|------------------| | Création | `Créer` (disabled si formulaire invalide / submit en cours) | | Édition | `Sauvegarder` si dirty, sinon `Aucune modification` (disabled) | | Lecture | Pas de primaire (ou uniquement `Fermer`) | --- ## Champs contrôlés (obligatoire) Réutiliser les widgets / utils déjà utilisés par les wizards et fiches. **Pas** de validation « maison » divergente. | Champ | Widget / formatters | Contrôles attendus | |-------|---------------------|--------------------| | **Prénom** | `ValidationEditableField` + `PersonNameInputFormatter` | Requis (création / édition sauf identité verrouillée super_admin) ; trim / casse cohérente à la sauvegarde (comportement actuel `_toTitleCase` OK) | | **Nom** | idem | idem | | **Email** | `ValidationEmailField` | Requis ; normalise minuscules + trim au blur ; `validateEmail` ; max length via `EmailMaxLengthFormatter` | | **Téléphone** | `ValidationPhoneField` | Formatage live FR (`formatPhoneForDisplay`) ; `validateFrenchNationalPhone` ; **requis en création** ; en édition : conserver règle actuelle (vide autorisé **ou** aligner sur fiche parent — **décision : requis si renseigné, format FR strict ; création = requis**) | | **Mot de passe** | TF stylé comme `ValidationLabeledField` + obscure toggle | Création : **requis**, min **6** car. ; Édition : optionnel (vide = ne pas changer) ; pas d’autofill agressif en édition | | **Relais principal** | `DropdownButtonFormField` **restylé** (même décoration / hauteur que `ValidationFieldDecoration`) | Liste existante `RelaisService` ; valeur `null` = « Aucun relais » ; disabled si loading / readOnly | ### Règles métier à conserver (non-régression) - `readOnly` : consultation sans save - `adminMode` / `withRelais` : admin sans relais ; gestionnaire avec - Verrouillage identité super_admin (`_isLockedAdminIdentity`) - Droits suppression (`canDeleteGestionnaire` / lignes `SuppressionPersonLine`) - Confirm suppression via `showSuppressionConfirmDialog` - Payloads create / update `UserService` inchangés (hors format téléphone normalisé à l’envoi, déjà le cas) --- ## Implémentation suggérée 1. **Refactor UI** de `AdminUserFormDialog` : remplacer `AlertDialog` par shell type fiches. 2. **Form** : `Form` + `ValidationLabeledField` / `ValidationEmailField` / `ValidationPhoneField` / TF MDP aligné. 3. **Optionnel (si ça évite la copie)** : extraire un petit `DashboardFormModalShell` (header / divider / footer) partagé — **pas obligatoire** pour livrer ; OK de dupliquer le pattern une fois comme les autres fiches. 4. **Déplacer le fichier** (optionnel, même ticket ou follow-up) : `screens/administrateurs/creation/gestionnaires_create.dart` → `widgets/dashboard/staff_user_form_modal.dart` (rename classe `StaffUserFormModal` ou garder `AdminUserFormDialog` temporairement pour limiter le diff). Décision recommandée : **rename fichier + classe** `StaffUserFormModal` + update imports (cohérent #155). 5. Smoke manuel : créer / éditer gestionnaire + admin ; téléphone invalide ; email invalide ; MDP court ; supprimer (si droit). --- ## Hors scope - Refonte des fiches parent / AM / enfant (déjà OK) - Wizards validation dossier - Modales relais / `DetailModal` 620 / autres `AlertDialog` métier - Extraction forcée d’un design system Flutter packages - Back / règles droits (#154 / #160 déjà livrés) --- ## Critères d’acceptation - [ ] Modale staff (gestionnaire **et** admin) : shell **930**, header + divider + footer alignés fiches OK - [ ] Plus de titre avec guillemets autour du rôle - [ ] Labels **au-dessus** des champs (plus de label flottant Material qui coupe la bordure) - [ ] Email : format + normalisation blur ; refus email invalide au submit - [ ] Téléphone : format FR live + validation ; refus numéro invalide au submit - [ ] MDP : règles création / édition inchangées fonctionnellement, look aligné - [ ] Relais (gestionnaire) : dropdown restylé, même comportement - [ ] Dirty-state édition : `Sauvegarder` / `Aucune modification` - [ ] Suppression : bouton rouge à gauche + confirm existante - [ ] Création / édition / lecture / droits : non-régression fonctionnelle - [ ] `rg AdminUserFormDialog` → 0 **ou** alias de transition documenté ; imports à jour --- ## Vérif ```bash # Après rename éventuel rg -n 'AdminUserFormDialog|gestionnaires_create' frontend/lib # Les champs staff passent bien par la famille Validation* rg -n 'ValidationEmailField|ValidationPhoneField|ValidationLabeledField|ValidationModalTheme' \ frontend/lib/widgets/dashboard/staff_user_form_modal.dart \ frontend/lib/screens/administrateurs/creation/gestionnaires_create.dart ```
jmartin added this to the 0.1.0 milestone 2026-09-14 12:57:15 +00:00
Author
Owner

Ferme - livre sur develop (3218daa) et master (f745079 squash). StaffUserFormModal (shell 930, Validation fields, dirty-state) ; AdminUserFormDialog retire.

Ferme - livre sur develop (3218daa) et master (f745079 squash). StaffUserFormModal (shell 930, Validation fields, dirty-state) ; AdminUserFormDialog retire.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jmartin/petitspas#164