Files
Planification/CHANGELOG.md
T
Quentin a6ae6ba79e v2026.5.41 — Suppression des hardcodes runtime + UX admin + thème unifié
Suppression des hardcodes :
- Plus aucun hardcode runtime pour groupe EV, domaines, liste de techs,
  absences récurrentes. Tout lu depuis admin_config (chrome.storage.local),
  persiste entre les mises à jour d'extension.
- Au 1er install : aucun tech sélectionné → fetch lève no_team_configured,
  viewer affiche message invitant à configurer Paramètres → Équipe.
- Suppression de la fonction hardcodée isPillonelAbsentFriday() →
  remplacée par isRecurringAbsence(tech, isoDate) générique qui lit
  cfg.recurringAbsences. Label 'Absent le X' calculé depuis le jour.

UX admin :
- Auto-refresh à l'enregistrement (équipe / domaines / heures) → plus
  besoin de recharger l'extension manuellement.
- Bouton ✓ Appliquer pour les heures de la journée + toast de confirmation.
- Toasts au-dessus du flou du panel admin (z-index 11000 > 10000).
- Section Statuts retirée (placeholder lecture-seule).
- Tri équipe : inclus d'abord puis exclus, alphabétique.

Thème unifié :
- Toggle topbar et sélecteur Apparence écrivent dans la même clé cfg.theme.
- Mode 'Auto' résolu en JS via prefers-color-scheme (le CSS n'avait pas
  de bloc @media, ce qui faisait retomber sur clair même en OS sombre).
- Listener matchMedia pour bascule live en mode auto.

Conflits absence/réservation × intervention :
- Si une intervention est planifiée pendant qu'un tech a une absence
  (full-day ou partielle) ou une réservation au même créneau, sa carte
  (row classique + mini-card horizontale) est peinte en rouge plein.

Permissions runtime pour domaines :
- manifest.json : optional_host_permissions [https://*/*].
- chrome.permissions.request() au save d'un domaine custom dans
  Paramètres → EasyVista. Refus → toast d'avertissement.

Synchronisation des heures EV :
- Helpers getDayBounds() côté background. day_start_hour, day_end_hour,
  begin_hour, end_hour des requêtes EV reflètent désormais cfg.dayStart
  et cfg.dayEnd. Avant : 8/18/19 hardcodés.

Vue horizontale :
- Popups au survol/clic limités à dessous/dessus (pas de gauche/droite
  car la sidebar à gauche et la timeline pleine largeur les rendent
  inutilisables).

Ménage de code :
- Suppression de CACHE_DAYS, LS_THEME, commentaire historique sur
  initAdminMenu(). Aucun symbole orphelin restant.

Contact mis à jour : quentin.rouiller@vd.ch
2026-04-27 02:11:14 +02:00

356 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CHANGELOG — Extension Planification EasyVista Canton de Vaud
> Ce changelog documente l'évolution de l'extension Chrome/Firefox "Planification"
> développée par Quentin Rouiller pour les techniciens DGNSI (Canton de Vaud).
>
> Les versions documentées ci-dessous sont celles dont les détails sont connus.
> Pour les versions plus anciennes, Claude Code se basera sur l'analyse du code
> source pour déterminer un message de commit pertinent.
---
## v2026.5.41 — Suppression des hardcodes (groupe / domaines / équipe) → tout depuis l'admin
### Plus aucun hardcode au runtime
- Le groupe EasyVista, les domaines (interne/externe) et la liste des
techniciens ne sont **plus codés en dur** dans `background.js` /
`viewer.js`. Tout est lu depuis `admin_config` (chrome.storage.local),
alimenté par les onglets **Équipe** et **EasyVista** du panel admin.
- `chrome.storage.local` survit aux mises à jour d'extension → la
configuration de l'utilisateur (groupe, équipe, absences récurrentes,
domaines) est conservée d'une version à l'autre.
### Domaines EasyVista (interne / externe)
- Défaut hardcodé conservé comme **filet de sécurité** au 1er install
(`https://itsma.etat-de-vaud.ch` + `https://itsma.vd.ch`).
- L'utilisateur peut les remplacer dans Paramètres → EasyVista. Le
service worker (`findEasyVistaSession`, `evFetch`, etc.) lit la valeur
effective via `getEvOrigins()`.
### Group ID EasyVista
- Défaut hardcodé conservé comme filet de sécurité (`191` = SI-CSS).
- Lu via `getGroupId()` dans `fetchPlanningXml`, `detectTeamFromEV` et
partout où c'était hardcodé.
- Le sélecteur de Paramètres → Équipe alimente `cfg.groupId`.
### Liste des techniciens
- **Aucun défaut hardcodé**. Sur un install vierge, `cfg.team` est
vide → le service worker lève `no_team_configured` plutôt que de
fetcher avec une liste fictive.
- Le viewer affiche : *"Aucun technicien sélectionné. Ouvrez ⚙
Paramètres → Équipe pour choisir le groupe EasyVista et cocher les
techniciens à afficher."*
- Lu via `getSupportIds()` (CSV des clés de `cfg.team`).
- Côté `viewer.js` : `TEAM` et `RECURRING_ABSENCES` sont des `let`
vides au démarrage, repeuplés par `_initTeamFromConfig()` appelé tôt
dans `init()`.
### Coulisses
- Nouveau dans `background.js` : helpers `getAdminConfig()`,
`getEvOrigins()`, `getGroupId()`, `getSupportIds()`,
`getDayBounds()` qui centralisent la lecture de la config persistée.
- `fetchPlanningXml()` lève `Error("no_team_configured")` quand la
liste de techs est vide ; le handler `fetchPlanning` propage l'erreur
au viewer via `err.kind`.
- Toutes les anciennes constantes hardcodées (`EV_ORIGINS`,
`DEFAULT_SUPPORT_IDS` interne à `detectTeamFromEV`,
`isPillonelAbsentFriday`) ont été remplacées ou retirées.
### Conflits absence/réservation × intervention
- Nouveau code visuel : si une intervention est planifiée pendant
qu'un tech a une **absence** (toute la journée ou demi-journée) ou
une **réservation** sur le même créneau, sa carte (row classique +
mini-card en vue horizontale) est peinte en **rouge plein** avec
texte blanc. Logique : full-day → toutes les interv en rouge ;
partiel → seules celles en chevauchement.
### Synchronisation des heures EV ↔ admin
- Les paramètres `day_start_hour` / `day_end_hour` envoyés à
`planning_xhr.php` et `begin_hour` / `end_hour` envoyés à
`plan_set_holidays_popup.php` (création absence) et
`plan_set_tech_planif_popup.php` (douchette) lisent désormais
`cfg.dayStart` / `cfg.dayEnd` (Paramètres → Apparence → Heures de la
journée). Avant : `8` / `18` / `19` figés en dur, ce qui rendait le
réglage des heures côté UI partiellement effectif (la timeline se
redessinait, mais les requêtes EV continuaient sur la plage hardcodée).
### Édition des domaines EV → permissions runtime
- `manifest.json` : ajout de `"optional_host_permissions":
["https://*/*"]` pour permettre l'édition des domaines EasyVista
vers des origines non prévues à l'install.
- Quand l'utilisateur saisit un domaine custom dans Paramètres →
EasyVista et clique sur Enregistrer, l'extension appelle
`chrome.permissions.request()` pour demander la permission au
navigateur. Si refus → toast d'avertissement, les fetches échoueront
jusqu'à acceptation.
- Les deux domaines hardcodés (`itsma.etat-de-vaud.ch` +
`itsma.vd.ch`) restent dans `host_permissions` (toujours accordés à
l'install), pas besoin de redemander la permission pour eux.
## v2026.5.40 — Vue horizontale enrichie (ref + ville + barre couleur)
**Branche** : current
- En vue horizontale, chaque segment timeline d'intervention contient
désormais :
- Une **barre verticale couleur catégorie** à gauche (mêmes teintes que
les `.intervention-dot` de la vue classique : livraison/recup/
remplacement/incident/rollout/réservation/autre)
- La **référence** (ex: `SYYMMDD_NNNNN`) en gras
- La **ville** en gris muted
- Hauteur de la timeline en horizontale passée de 22px à 32px pour laisser
la place au texte
- Fond des segments d'intervention : `--bg-elevated` neutre + bordure 1px
pour que le texte reste lisible (la couleur catégorie n'est plus en fond
plein, juste en barre gauche)
- Vue classique inchangée
- Réorganisation interne du repo : `src/` pour les sources, `dist/`
généré, `Autres/` pour build.sh + meta files (LICENSE, README,
CHANGELOG)
## v2026.5.39 — Séparation Matin / Après-midi + Apparence (thème, zoom, cache)
### Séparation matin / après-midi
- Séparateur visuel "MATIN" / "APRÈS-MIDI" entre les interventions
dans la vue classique : pill grise neutre, ligne 3px épaisse.
- Affiché aussi entre les absences partielles (demi-journée).
- Si une période est vide, son séparateur n'est pas affiché.
- Caché en vue horizontale (les rows sont masquées de toute façon).
### Timeline — coupure midi très visible
- Bande verticale composée d'un trait massif central (couleur --text)
+ stripes diagonales en arrière-plan (effet "césure"). 6 px de large
(7 px en vue horizontale). Visible immédiatement, pas de label superflu.
### Vue horizontale (sidebar)
- Boutons (Absence, Douchette, Actualiser, Tout recharger, Vider cache,
Thème) maintenant **vraiment** poussés en bas via `min-height: 100vh`
sur la sidebar.
- Bouton "Aujourd'hui" : style cohérent avec les flèches ◀ ▶ (même
padding, font-size, hauteur), texte centré, libellé complet
"Aujourd'hui" (au lieu de "Auj.").
- Espace visuel entre `Actualisé à HH:MM` et le bouton Absence (fine
bordure top + padding).
### Vue classique (topbar)
- Ordre verrouillé via CSS `order` : badge user → titre → date-nav →
capture-info → refresh-check. Évite les déplacements au retour de
vue horizontale.
### Section Apparence (admin) — refondue + en première position
- **Thème** : sélecteur Auto / Clair / Sombre (s'enregistre direct).
- **Durée du cache (jours)** : configurable, défaut 7 jours, range 1-365.
Lue par viewer.js (purge auto) ET background.js (au boot).
- **Taille du texte** : 5 niveaux (-20%, -10%, 100%, +10%, +20%) via CSS
`zoom` sur body. Persisté dans admin_config.textZoom et appliqué dès
le boot.
- Section "Apparence" est maintenant **la première** dans le panel admin.
## v2026.5.38 — Attribution auteur + nettoyage code
**Branche** : current
### Attribution auteur
- Ajout en-têtes copyright dans tous les fichiers source
(viewer.js, viewer.html, viewer.css, background.js)
- Ajout `@author Quentin Rouiller` sur les fonctions principales
(loadForDate, buildCard, buildTooltipHTML, pinTooltip, _softUnpinPopup,
positionTooltipAnchored, _applyViewMode, _moveElementsToSidebar,
_restoreElementsToTopbar, fetchAndShowCurrentUser, _maybeRetryFetchUser,
initAppClock, initAppFooter, bindTimelinePopover,
openPersistentTimelinePopup, showTooltip, _findFreePopupPosition,
_clampPopupInSafeArea, findEasyVistaSession, fetchPlanningXml,
fetchCurrentUser, detectNetworkContext)
- Ajout signature "Développé par Quentin Rouiller" en bas du popup
user-badge (style cohérent avec footer version : 11px, italique,
gris atténué, séparateur fin)
- Mise à jour `description` du manifest pour mentionner DGNSI
### Nettoyage et optimisation
- Retrait fonction vide `initAdminMenu()` (inutile depuis v2026.5.25,
l'admin passe par le bouton ⚙ Paramètres du popup user-badge)
- Retrait classe CSS orpheline `.date-picker-day` (déjà remplacée par
`.date-custom` en v2026.5.17)
- Retrait anciens styles CSS `.intervention` (layout v1, jamais générés
depuis le passage à `.intervention-v2`)
- Retrait commentaire orphelin `.intervention-v2.is-ghost` (classe
retirée en v4.3.3)
- Retrait 14× `console.log("[viewMode]")` debug verbose (gardé
uniquement les `console.warn` utiles pour erreurs)
- Retrait 5× `console.log("[bg]")` debug verbose dans
fetchPlanningXml / fetchFicheHtml / fetchSessionTimeRemaining /
extendSessionKeepAlive (gardé warnings + logs critiques)
- Remplacement `extendBtn.onclick` par `addEventListener("click", ...)`
pour plus de cohérence
### Builds
- `dist/chromium/` et `dist/firefox/` prêts à charger en mode dev
- `planification-v2026.5.38-chromium.zip` (~144 Ko)
- `planification-v2026.5.38-firefox.xpi` (~144 Ko, à signer sur AMO)
## v2026.5.37 — Refonte vue horizontale (sidebar complète)
- Topbar en haut supprimée en vue horizontale
- User-badge + titre déplacés tout en haut de la sidebar
- Bouton "Aujourd'hui" pleine largeur avec icône ↺
- Date + heure centrés sous le bouton
- Séparateur visuel
- Sélecteur de date pleine largeur
- Flèches ◀ ▶ côte à côte (wrapper #sidebar-arrows)
- Stats empilées
- Synchronisé à HH:MM
- Espace vide intentionnel
- Boutons du bas vers le haut (margin-top: auto sur Absence)
- Barre de rafraîchissement en overlay top-left
- Banderole pompier masquée en vue horizontale (badge + barre rouge à gauche conservés)
## v2026.5.36 — Sidebar verticale en vue horizontale
- Création wrapper flex-row #horizontal-wrapper contenant [sidebar] + [main]
- Sidebar 200px (170px sur <1400px), sticky, bg-muted
- Déplacement physique des éléments via JS (ELEMENTS_TO_RELOCATE)
- Mémorisation parents d'origine (data-orig-parent + data-orig-index)
- Restauration propre en vue classique
- Zone nom tech : 140px → 120px
## v2026.5.35 — Fix popup épinglé position vue horizontale + stats gauche
- Fix popup épinglé qui partait en haut à gauche en vue horizontale
- Cause : rows .intervention-v2 cachées (display: none) → getBoundingClientRect (0,0,0,0)
- Solution : priorité 1 tooltip visible, priorité 2 segment timeline, fallback srcEl
- Stats globales en colonne verticale 200px à gauche en vue horizontale
- Position sticky, fond bg-muted, séparateurs · masqués
- Zone nom tech 200px → 140px (vue horizontale)
## v2026.5.34 — Bouton 📌 restauré + badge user cliquable
- HTML : badge user toujours visible avec "?" par défaut (retiré class hidden)
- _softUnpinPopup refait en 8 étapes loggées
- Popup reste visible après désépinglage (plus de suppression auto au mouseleave)
- Restauration du bouton 📌 dans .tooltip-actions
- Handler click ré-attaché : clic 📌 = ré-épingle, clic ↻ = recharge
- _ensureSoftUnpinnedCleanupHandler : handler global clic hors popup
- _maybeRetryFetchUser : relance opportuniste après succès planning et reconnexion session
- Logs abondants : [currentUser], [softUnpin], [positionTooltip], [persistentTimeline], [showTooltip]
- Fonction positionTooltipAnchored unifiée (4 candidats droite/gauche/dessous/dessus)
- popup._linkedIv stocké pour ré-épinglage
## v2026.5.33 — Interactions vue horizontale différenciées
- Hover segment timeline en vue horizontale → grande popup directement (openPersistentTimelinePopup)
- Clic segment timeline en vue horizontale → ouvre fiche EasyVista
- Popup absence en vue horizontale : hover uniquement sur badge .card-tech-badge (pas sur carte entière)
- Vue classique : comportement inchangé
## v2026.5.32 — Vue horizontale togglable
- Bouton ⊞ "Vue" dans popup user-badge (à côté ⚙ Paramètres)
- Toggle Vue classique ↔ Vue horizontale persisté localStorage "view_mode"
- HTML class "view-classic" ou "view-horizontal" sur <html>
- Chaque tech = 1 ligne horizontale compacte en mode horizontal
- Card header devient barre latérale gauche fixe 200px
- Interventions détaillées masquées (display: none)
- Timeline horizontale pleine largeur
- Stats rapides .tech-row-stats ajoutés au header (nb interv, Xm · Ya)
## v2026.5.31 — Sarcelle pour absence récurrente (REJETÉ par utilisateur)
- Couleur Pillonel vendredi : sarcelle foncée #0f766e / soft #ccfbf1
- Variables --c-recurring, --c-recurring-soft
- Layout 4 colonnes forcées + scroll interne cartes (REJETÉ : "scroll en continu")
## v2026.5.30 — Absence récurrente cyan + mode compact 24"
- Absence récurrente Pillonel vendredi en cyan
- Mode compact @media (max-width: 1920px) avec grid-template-columns: repeat(4, 1fr)
## v2026.5.29 — Contraste++ + footer
- Contrastes encore plus forts (text-muted #d0d5de dark, #2e3642 light)
- Footer QRO/version : 13px badge avec fond bg-muted + bordure
- Fix highlight row : selector .intervention-v2[data-iv-idx]
- Scroll-into-view automatique au hover segment timeline
## v2026.5.28 — Ajustements visuels absences
- Retrait pastille ronde (.tech-name-dot supprimée) — barre gauche + badge suffisent
- "Maladie" → "Maladie/Accident"
- Contraste textes secondaires +30%
- Popups épinglés width fixe 520px (ne rétrécit plus au resize fenêtre)
- _clampPopupInSafeArea ne rétrécit plus si popup > zone dispo
## v2026.5.27 — Classification absences (Maladie/Congé/Pompier)
- Topbar une ligne : "Jeudi 23.04.26 • 21:55" (gros point •, même taille 22px)
- Fermeture auto popups non-épinglés au survol autre popup/carte
- Texte +20% topbar/stats/boutons
- Icône thème ☀/🌙 plus contrastée (bordure 1.5px, fond bg-muted, ombre)
- Classification absences (ABSENCE_LABELS) + absenceCategory : "maladie"|"conge"|"pompier"|null
- Couleurs : Maladie #4338ca indigo foncé, Congé #06b6d4 cyan, Pompier #b03030 rouge
- Badge + barre gauche + dégradé fond pour catégorie
- Libellé "Absent du DD.MM au DD.MM — Maladie/Accident"
- Suffixe `s` adaptatif (Congé/Congés)
## v2026.5.26 — Badge user inconnu cliquable + retry
- En cas d'échec fetch user, afficher rond gris "?" cliquable
- Bouton ⚙ Paramètres accessible même quand user inconnu
- Retry automatique 60s (max 10 essais = 10 min)
- Reset compteur au succès
## v2026.5.25 — Bouton Paramètres dans popup user-badge
- Remplace les 5 clics sur le titre pour ouvrir admin
- Bouton ⚙ Paramètres explicite dans le popup user-badge
## v2026.5.16-v2026.5.24 — Évolutions diverses (à compléter)
- v2026.5.17 : popup user-badge avec ligne session (MM:SS), couleur selon seuil
- v2026.5.18 : dock pastilles popups épinglés avec couleur catégorie
- v2026.5.19 : drag popup épinglé
- v2026.5.20 : safe area popups (topbar + dock)
- v2026.5.22 : régénération tooltip hover après softUnpin
- v2026.5.23 : reset bulleState.pinned + iv._reloading
---
## Versions antérieures (v5.x et v4.x)
> Ces versions sont à analyser par Claude Code à partir des fichiers source.
> Indices clés à chercher dans le viewer.js :
>
> - Présence de `pinTooltip` → version >= v4.x
> - Présence de `_softUnpinPopup` → version >= v4.3.3
> - Présence de `initSessionTimer` → version >= v5.0.9
> - Présence de `initAppClock` → version >= v5.0.0
> - Présence de `_applyViewMode` → version >= v2026.5.32
> - Présence de `bindTimelinePopover` → version >= v4.2.3
> - Présence de `openPersistentTimelinePopup` → version >= v4.2.3
> - Commentaires `// vX.Y.Z` au-dessus des fonctions = version d'introduction
### v5.0.0 — Refonte topbar (horloge, menu admin)
- initAppClock : horloge HH:MM au milieu topbar
- initAdminMenu : menu admin caché (5 clics sur titre)
- initSessionTimer : compteur de session EV (tick 1s)
### v4.x — Fonctions tooltip avancées
- v4.1.12 : moveTooltip devenu no-op (popup statique)
- v4.1.15 : pendant épinglage, ne pas remplacer contenu sur hover autre iv
- v4.2.3 : grande popup timeline persistante (clic), suit-souris (hover)
- v4.2.3 : bindTimelinePopover, showTimelinePopover, moveTimelineTooltip
- v4.2.4 : setTooltipViewportPosition (détection auto fixed/abs)
- v4.2.9 : pied de page discret QRO/version
- v4.2.9 : initModalScrollLock (bloquer scroll arrière modal)
- v4.3.0 : tooltip live libéré après épinglage (réutilisable autres survols)
- v4.3.3 : _softUnpinPopup (désépinglage mou)
### v3.x et antérieures — Versions de base
- À analyser par Claude Code
---
## Notes techniques persistantes (toutes versions)
- 8 techs hardcodés : "76272,83725,66635,92235,90070,40944,72485,86874"
- Pillonel Olivier (ID 40944) absent tous les vendredis (hardcodé)
- Group ID EasyVista : 191
- Domaines cibles : itsma.etat-de-vaud.ch (interne), itsma.vd.ch (externe)
- SSO : Canton ForgeRock OpenAM
- ABSENCE_LABELS = /^(cong[ée]s|maladie|pompier)$/i
- ADMIN_CONFIG_KEY = "admin_config"
- VIEW_MODE_KEY = "view_mode" (depuis v2026.5.32)
- DAY_NAMES_FULL = ["Dimanche", "Lundi", ..., "Samedi"]
- GUIDs forms EV : S={C99ECD05-3D48-4C62-ABF0-66292053AED6} demande, I={07ED9C68-6172-48EA-8A58-90912B0A283E} incident
- Couleurs catégories : livraison #2563eb, recup #16a34a, remplacement #ea580c, incident #8b5cf6, rollout #92400e, reservation #f59e0b, autre #6b7280
## Auteur
**Quentin Rouiller** (QRO)
Technicien DGNSI — Canton de Vaud
Contact : `quentin.rouiller@vd.ch`