Files
pta/README_V7_9.md
PTA b68ac15de5 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>
2026-08-10 16:48:50 +02:00

5.8 KiB

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

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 :

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.