V7.9 — Tableau de bord et navigation regroupée pour le Service Enfance
Le Service Enfance ouvrait onze onglets à plat et atterrissait sur l'écran de saisie, alors que son travail commence par le contrôle. Les chiffres qui déclenchent une action vivaient sur trois écrans distincts. - Nouvelle page dashboard.php, réservée au Service Enfance et devenue sa page d'atterrissage : quatre tuiles d'action, les brouillons les plus anciens avec ouverture directe sur la bonne semaine, les plages de couverture les plus déficitaires, et le suivi des quotas annuels par agent. - Navigation regroupée par intention (Piloter / Planifier / Consulter / Paramétrer). Les rôles à quelques pages gardent la barre simple. - Sous-titre propre à chaque page : le bandeau générique n'apprenait rien. - Pastille « À valider » alimentée depuis toutes les pages, et non plus seulement depuis la page qu'elle annonce. Aucune règle métier n'est modifiée : le tableau de bord relit ce que PlanningModel, CoverageModel et QuotaModel calculent déjà, et son endpoint est gardé par requireService(). Le droit d'accès à la page vient de la migration V7.9 ; sans elle, l'onglet n'apparaît pas et homeUrl() se replie sur planning. Vérifié sur la base réelle : les chiffres de quota du tableau de bord sont identiques à ceux de api/annual_overview.php, les trois rôles rendent leurs écrans sans erreur, le rendu JS a été exécuté dans un DOM avec la réponse réelle de l'API, et la page ne produit aucun attribut style inline (CSP). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
113
README_V7_9.md
Normal file
113
README_V7_9.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# PTA V7.9 — Parcours et lisibilité du Service Enfance
|
||||
|
||||
## Le problème traité
|
||||
|
||||
Le rôle **Service Enfance** ouvre onze écrans. Jusqu'ici :
|
||||
|
||||
- il atterrissait sur **Saisie**, alors que son travail commence par le contrôle et non par la saisie ;
|
||||
- les onze onglets étaient alignés à plat, sans hiérarchie : rien ne distinguait une tâche
|
||||
quotidienne (« À valider ») d'un référentiel modifié deux fois par an (« Administration ») ;
|
||||
- chaque bandeau de page affichait le **même** sous-titre générique, il fallait donc ouvrir un écran
|
||||
pour savoir à quoi il servait ;
|
||||
- les chiffres qui déclenchent une action (brouillons en attente, manques de couverture, quotas)
|
||||
vivaient sur trois écrans distincts : personne ne voyait l'état général sans faire le tour ;
|
||||
- la pastille « À valider » de la barre de navigation n'était alimentée que **sur la page
|
||||
« À valider » elle-même**, donc invisible là où elle aurait servi.
|
||||
|
||||
## Ce qui change
|
||||
|
||||
### 1. Un tableau de bord comme page d'accueil
|
||||
|
||||
Nouvelle page `dashboard.php`, **réservée au Service Enfance**, qui devient sa page d'atterrissage.
|
||||
|
||||
- **Quatre tuiles d'action**, vertes quand il n'y a rien à faire, rouges dès qu'un compteur remonte :
|
||||
plannings à valider, manques de couverture de la semaine, quotas dépassés, lieux sans horaires de
|
||||
couverture. Chaque tuile est un lien vers l'écran de traitement.
|
||||
- **« À valider en priorité »** : les cinq brouillons dont la semaine est la plus ancienne, avec un
|
||||
bouton **Contrôler** qui ouvre directement l'écran de saisie sur le bon agent, le bon lieu, la
|
||||
bonne semaine, curseur sur la validation.
|
||||
- **« Couverture à renforcer »** : les cinq plages les plus déficitaires, triées par nombre d'agents
|
||||
manquants, avec un lien vers l'écran de couverture déjà filtré.
|
||||
- **« Suivi des quotas annuels »** : consommation globale, reste à affecter, agents sans aucune heure,
|
||||
et le détail par agent avec une jauge et un lien vers sa vue annuelle.
|
||||
- **« Actions fréquentes »** : six raccourcis vers les écrans les plus utilisés.
|
||||
|
||||
Un sélecteur de semaine en haut de page rejoue l'ensemble des indicateurs de couverture, et indique
|
||||
si la semaine est scolaire, de vacances, ou à cheval sur les deux.
|
||||
|
||||
### 2. Navigation regroupée par intention
|
||||
|
||||
Les onglets sont désormais rangés en quatre groupes : **Piloter** (tableau de bord, à valider,
|
||||
couverture), **Planifier** (saisie, équipes), **Consulter** (par agent, par lieu, vue annuelle, PTA
|
||||
détaillé), **Paramétrer** (vacances, administration).
|
||||
|
||||
Les rôles qui n'ont que quelques pages — Agent (2), Responsable de structure (4) — gardent la barre
|
||||
simple d'avant, sans titres de groupe. Une page autorisée en base mais absente des groupes reste
|
||||
affichée dans un groupe « Autres » plutôt que de disparaître.
|
||||
|
||||
### 3. Chaque page dit ce qu'on y fait
|
||||
|
||||
Le sous-titre du bandeau est propre à chaque écran et décrit l'action, pas le produit.
|
||||
|
||||
### 4. La pastille « À valider » suit partout
|
||||
|
||||
Elle est alimentée depuis n'importe quel écran par un compteur léger
|
||||
(`api/dashboard_summary.php?scope=badges`). L'échec de cet appel est silencieux : une commodité ne
|
||||
doit jamais empêcher une page de fonctionner.
|
||||
|
||||
## Ce qui ne change pas
|
||||
|
||||
Aucune règle métier, aucun calcul, aucun droit n'est modifié.
|
||||
|
||||
Le tableau de bord ne fait que **relire** ce que les autres écrans calculent déjà : la file de
|
||||
validation vient de `PlanningModel::pendingValidation()`, la couverture de
|
||||
`CoverageModel::reportForStructure()`, et le quota reprend exactement la logique de `QuotaModel`
|
||||
(année civile, motifs décomptés uniquement, quota de l'année la plus proche à défaut de l'année
|
||||
exacte) — un agent ne peut donc pas afficher deux valeurs différentes selon l'écran consulté.
|
||||
|
||||
L'endpoint `api/dashboard_summary.php` est gardé par `requireService()` : 403 pour les autres rôles,
|
||||
401 sans session.
|
||||
|
||||
## Migration
|
||||
|
||||
```sql
|
||||
SOURCE database/migration_v7_9_tableau_de_bord.sql;
|
||||
```
|
||||
|
||||
Elle insère une seule ligne dans `acces_role_page`. **Elle doit être jouée en même temps que le
|
||||
déploiement du code**, dans un sens comme dans l'autre :
|
||||
|
||||
- code déployé, migration non jouée → l'onglet n'apparaît pas, le Service Enfance atterrit comme
|
||||
avant sur l'écran de saisie, et `dashboard.php` renvoie vers l'accueil. L'application reste
|
||||
entièrement fonctionnelle, simplement sans tableau de bord ;
|
||||
- migration jouée, code non déployé → l'onglet apparaît et pointe vers un fichier inexistant.
|
||||
|
||||
Retour arrière :
|
||||
|
||||
```sql
|
||||
DELETE FROM acces_role_page WHERE role = 'SERVICE_ENFANCE' AND page = 'dashboard';
|
||||
```
|
||||
|
||||
## Fichiers
|
||||
|
||||
| Ajouté | Rôle |
|
||||
| --- | --- |
|
||||
| `dashboard.php` | point d'entrée de la page |
|
||||
| `api/dashboard_summary.php` | endpoint JSON |
|
||||
| `app/Controllers/DashboardController.php` | agrégation et gardes d'accès |
|
||||
| `app/Models/DashboardModel.php` | suivi des quotas et compteurs |
|
||||
| `app/Views/pages/dashboard.php`, `app/Views/partials/dashboard.php` | vue |
|
||||
| `assets/js/dashboard.js` | module `PTA.modules.dashboard` |
|
||||
| `database/migration_v7_9_tableau_de_bord.sql` | droit d'accès à la page |
|
||||
|
||||
| Modifié | Raison |
|
||||
| --- | --- |
|
||||
| `app/Core/Access.php` | `homeUrl()` vise le tableau de bord, avec repli si la migration manque |
|
||||
| `app/Controllers/PageController.php` | méthode `dashboard()` et sous-titre propre à chaque page |
|
||||
| `app/Views/layouts/header.php` | navigation regroupée, sous-titre contextuel |
|
||||
| `app/Views/layouts/footer.php`, `app/Views/pages/role.php` | versions d'assets `?v=7.9` |
|
||||
| `assets/js/page-bootstrap.js` | pastille « À valider » sur toutes les pages |
|
||||
| `assets/style.css` | styles de la navigation groupée et du tableau de bord |
|
||||
|
||||
Les jauges de quota utilisent l'élément natif `<progress>` : la CSP interdit l'attribut `style`, une
|
||||
largeur ne peut donc pas être calculée en JavaScript sur une simple `div`.
|
||||
Reference in New Issue
Block a user