V7.10 — Tableau de bord, guide, semaine type et enveloppe de formation

Reprise dans le répertoire de production du travail mené dans le worktree
ux-service-enfance :

- tableau de bord Service Enfance (dashboard.php) et navigation regroupée ;
- guide d'utilisation (faq.php) accessible depuis toute la navigation ;
- éditeur de semaine type mis en avant sur l'écran de saisie ;
- droit à l'enveloppe de formation par agent, en remplacement de la case
  « formation déjà prévue dans la répartition annuelle » ;
- correctif de « [object Object] » sur les cartes de quota du PTA ;
- motif de travail par défaut à la saisie, heures travaillées complètes
  dans les PDF.

Le docker-compose.yml de production est conservé : celui du worktree décrit
une pile de test (conteneurs et volume suffixés « test », ports 9080/9081),
qui aurait fait redémarrer l'application sur un volume MariaDB vide.

Les migrations database/migration_v7_9*.sql sont obligatoires ; le service
db-migrate les applique au déploiement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
PTA
2026-08-17 16:53:04 +02:00
parent 57bd8da5c8
commit 4201894e28
69 changed files with 5228 additions and 246 deletions

View File

@@ -20,6 +20,17 @@
return `<article class="summary-card"><span>${escapeHtml(label)}</span><strong>${escapeHtml(value)}</strong>${detail ? `<small>${escapeHtml(detail)}</small>` : ''}</article>`;
}
/**
* QuotaModel::enrich() renvoie les durées sous forme d'objet
* { minutes, heures_decimales, libelle } et non de chaîne. Passer l'objet
* tel quel à une interpolation affiche « [object Object] » — et un objet
* étant toujours truthy, un `||` ne rattrape jamais le coup. On lit donc
* explicitement le libellé, en gardant le nombre de minutes comme repli.
*/
function quotaLabel(enriched, fallbackMinutes) {
return enriched?.libelle || formatDuration(Number(fallbackMinutes || 0));
}
function renderSummary(data) {
current = data;
const agent = data.agent || {};
@@ -37,9 +48,9 @@
el('pta-summary-cards').innerHTML = [
card('Année civile PTA', `${formatDate(quota.date_debut_periode)} → ${formatDate(quota.date_fin_periode)}`),
card('Quotité', `${Number(quota.quotite_travail || 0).toLocaleString('fr-FR')} %`, `Référence : ${formatDuration(Number(quota.quota_reference_minutes || 96420))}`),
card('Quota à réaliser', quota.quota_cible || formatDuration(Number(quota.quota_cible_minutes || 0))),
card('Déjà affecté', quota.affectees || formatDuration(Number(quota.minutes_affectees || 0))),
card('Reste à affecter', quota.restantes || formatDuration(Number(quota.minutes_restantes || 0))),
card('Quota à réaliser', quotaLabel(quota.quota_cible, quota.quota_cible_minutes)),
card('Déjà affecté', quotaLabel(quota.affectees, quota.minutes_affectees)),
card('Reste à affecter', quotaLabel(quota.restantes, quota.minutes_restantes)),
card('Formation', `${counters.formation_duree || '0 h 00'} / ${counters.formation_cible_duree || '0 h 00'}`),
card('Congés annuels', `${Number(counters.conges_annuels_jours || 0)} / ${Number(counters.conges_annuels_cible || 25)} jours`),
card('Fractionnement', `${Number(counters.jours_fractionnement || 0)} / ${Number(counters.jours_fractionnement_cible || 2)} jours`),