diff --git a/CHANGELOG.md b/CHANGELOG.md index 608b4db..4cab65e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,33 @@ --- +## v2026.5.43 — Fix Firefox : positionnement menu dock + stabilité popup pin/unpin + +### Menu hover sur pastille du dock (popup réduit) +- Bug Firefox uniquement : quand un popup épinglé était réduit dans la + taskbar du bas, le menu qui apparaît au survol de la pastille + (Agrandir / Fermer) se positionnait trop haut, pas juste au-dessus de + la pastille. +- Cause : `getBoundingClientRect()` était appelé immédiatement après + `appendChild`, avant que Firefox n'ait calculé la mise en page. + Combiné avec un `transform: translateY(4px)` dans l'animation + `pill-hover-menu-appear`, Firefox lisait des dimensions décalées. +- Fix : positionnement hors écran initial, force-layout via + `void offsetHeight`, mesure des dimensions, puis pose finale. CSS de + l'animation simplifiée en opacité-only (plus de transform). + +### Stabilité popup au pin/unpin +- Bug : la popup épinglée bougeait visuellement et changeait légèrement + de taille quand on la dé-épinglait avec le bouton 📌 (puis l'inverse). +- Cause : `.pinned-popup` avait `padding-top: 28px` (place pour la + dragbar) et `border: 2px`, alors que `.soft-unpinned` avait + `padding-top: 12px` et `border: 1px`. Le contenu se décalait de 16px + vers le haut et la popup devenait 1px plus fine de chaque côté. +- Fix : `.soft-unpinned` conserve désormais `padding-top: 28px` et + `border: 2px` comme `.pinned-popup`. Bordure passe juste en + `--border-strong` (gris discret) plutôt que `--accent` (bleu) pour + signaler visuellement le mode "détaché". Position et taille stables. + ## v2026.5.42 — Nettoyage de commentaires + exemples génériques - Passage en revue des commentaires de `src/viewer.js` : les exemples qui @@ -66,7 +93,7 @@ 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. + `isXXXAbsentFriday`) ont été remplacées ou retirées. ### Conflits absence/réservation × intervention - Nouveau code visuel : si une intervention est planifiée pendant @@ -259,12 +286,12 @@ - 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 +- Couleur absence récurrente (jour fixe) : 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 +- Absences récurrentes (configurées par tech) en cyan - Mode compact @media (max-width: 1920px) avec grid-template-columns: repeat(4, 1fr) ## v2026.5.29 — Contraste++ + footer @@ -348,8 +375,8 @@ ## 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é) +- 8 techs hardcodés à l'origine (depuis v2026.5.41 : retirés, alimentés par admin_config) +- Absences récurrentes (un tech absent un jour fixe par semaine) hardcodées à l'origine, depuis v2026.5.41 configurables via Paramètres → Équipe - Group ID EasyVista : 191 - Domaines cibles : itsma.etat-de-vaud.ch (interne), itsma.vd.ch (externe) - SSO : Canton ForgeRock OpenAM diff --git a/README.md b/README.md index d0b0734..66b279c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Extension Chrome / Firefox pour visualiser de manière claire et rapide le plann - **Auteur** : Quentin Rouiller (QRO) - **Cible** : techniciens DGNSI (Canton de Vaud), EasyVista (`itsma.etat-de-vaud.ch` / `itsma.vd.ch`) - **Démarrage projet** : jeudi 16 avril 2026 -- **Version actuelle** : `v2026.5.42` +- **Version actuelle** : `v2026.5.43` - **Contact** : voir [page wiki Contact](https://gitea.netaplaid.ch/FroSteel/Planification/wiki/Contact) - **Manifest** : V3 (Chrome/Edge/Firefox) - **Format** : `.zip` (Chromium) + `.xpi` signé (Firefox) @@ -40,7 +40,7 @@ Extension Chrome / Firefox pour visualiser de manière claire et rapide le plann - **Congé / Congés** : cyan `#06b6d4` (suffixe `s` adaptatif) - **Pompier** : rouge `#b03030` - Badge + barre gauche colorée + dégradé fond -- Absence récurrente Pillonel vendredi : cyan (depuis v2026.5.30) +- Absences récurrentes (configurées par tech) : cyan (depuis v2026.5.30) ### User et session - Badge user avec photo/initiales en topbar @@ -87,7 +87,13 @@ Le numéro de **majeure** n'est **pas** un mois et **pas** un chiffre lié au ca ## Versions notables -### `v2026.5.42` (latest, 27 avril 2026) — Nettoyage de commentaires + exemples génériques +### `v2026.5.43` (latest, 27 avril 2026) — Fix Firefox : menu dock + stabilité popup pin/unpin +- Firefox : le menu hover sur les pastilles du dock (popup réduit) se + positionne désormais correctement au-dessus de la pastille. +- Pin/unpin : la popup épinglée ne bouge plus et garde la même taille + quand on la dé-épingle / re-épingle. + +### `v2026.5.42` — Nettoyage de commentaires + exemples génériques - Uniformisation des exemples utilisés dans les commentaires de `viewer.js` (parsing contacts/lieux/références/codes-barres) en placeholders abstraits. Comportement runtime strictement inchangé. @@ -99,7 +105,7 @@ Le numéro de **majeure** n'est **pas** un mois et **pas** un chiffre lié au ca - **Heures de la journée** : bouton ✓ Appliquer explicite (au lieu de save direct), toast de confirmation, refetch automatique du planning. Synchronisation effective avec les requêtes EV (`day_start_hour` / `day_end_hour` / `begin_hour` / `end_hour`) — avant, l'affichage changeait mais les requêtes restaient sur 8h-19h hardcodés. - **Thème unifié** : le toggle 🌙 de la topbar et le sélecteur Apparence du panel admin écrivent dans la même clé (`cfg.theme`). Le mode "Automatique" est résolu en JS via `prefers-color-scheme` (le CSS n'avait pas de bloc `@media`, ce qui faisait retomber sur le clair même quand l'OS était en sombre). Listener `matchMedia` pour bascule live en mode auto. - **Conflit absence/réservation × intervention** : 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 au même créneau, sa carte est peinte en **rouge plein** (intervention conflictuelle). Logique : full-day → toutes en rouge ; partiel → seules celles en chevauchement. -- **Pillonel & Cie** : suppression de la fonction hardcodée `isPillonelAbsentFriday()`. L'absence récurrente est désormais générique : `RECURRING_ABSENCES[tech.id]` lit `cfg.recurringAbsences` et le label "Absent le X" est calculé dynamiquement depuis le jour de la semaine. +- **Absences récurrentes génériques** : suppression de la fonction hardcodée `isXXXAbsentFriday()`. L'absence récurrente est désormais générique : `RECURRING_ABSENCES[tech.id]` lit `cfg.recurringAbsences` et le label "Absent le X" est calculé dynamiquement depuis le jour de la semaine. - **Notifications au-dessus du flou** : z-index `.toast-stack` relevé à 11000 (le panel admin est à 10000) pour que les toasts de feedback restent visibles quand l'admin est ouvert. - **Vue horizontale** : popups au survol/clic limités aux candidats `dessous`/`dessus` (la sidebar à gauche et la timeline pleine largeur rendent gauche/droite peu praticables). - **Tri équipe** : inclus d'abord, puis exclus, alphabétique dans chaque sous-groupe (ne saute plus quand on coche/décoche). @@ -211,7 +217,7 @@ Planning/ ### Constantes / valeurs hardcodées (toutes versions) - Group ID EV par défaut : `191` (SI-CSS) — surchargeable via le sélecteur depuis v2026.5.40 -- Pillonel Olivier (ID 40944) : absent tous les vendredis (récurrent) +- Absences récurrentes par tech : configurables via Paramètres → Équipe (depuis v2026.5.41) - GUIDs forms EV : - Demande : `S={C99ECD05-3D48-4C62-ABF0-66292053AED6}` - Incident : `I={07ED9C68-6172-48EA-8A58-90912B0A283E}` diff --git a/firefox-updates.json b/firefox-updates.json index 1512c57..bd1e131 100644 --- a/firefox-updates.json +++ b/firefox-updates.json @@ -2,6 +2,11 @@ "addons": { "planification-dgnsi@netaplaid.ch": { "updates": [ + { + "version": "2026.5.43", + "update_link": "https://gitea.netaplaid.ch/FroSteel/Planification/releases/download/v2026.5.43/planification-v2026.5.43-firefox.xpi", + "update_hash": "sha256:9d1f0cb49b98cdb46a0e022dc53c77c98fde380590e72036e188c128d6b19965" + }, { "version": "2026.5.42", "update_link": "https://gitea.netaplaid.ch/FroSteel/Planification/releases/download/v2026.5.42/planification-v2026.5.42-firefox.xpi", diff --git a/src/background.js b/src/background.js index e6c50e1..fff22be 100644 --- a/src/background.js +++ b/src/background.js @@ -1175,7 +1175,7 @@ async function detectTeamFromEV(origin, phpsessid, groupIdArg, supportIdsArg) { } console.log("[bg] parsing pattern 1 (checkbox) :", results.length, "résultats"); - // Pattern 2 : fallback + // Pattern 2 : fallback if (results.length === 0) { const rxOption = /]*value=["'](\d{4,7})["'][^>]*>([^<]+)<\/option>/gi; let mO; diff --git a/src/manifest.json b/src/manifest.json index e864b5c..da5852b 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Planification", - "version": "2026.5.42", + "version": "2026.5.43", "description": "Vue claire et rapide du planning des techniciens EasyVista. Développé par Quentin Rouiller — DGNSI, Canton de Vaud.", "permissions": [ "activeTab", diff --git a/src/viewer.css b/src/viewer.css index 3d5978f..080b3da 100644 --- a/src/viewer.css +++ b/src/viewer.css @@ -1670,7 +1670,7 @@ html.view-horizontal .timeline-noon { } /* ───────────────────────────────────────────────────────────────────────── - v4.1.20 : Message d'absence récurrente (Pillonel vendredi) + v4.1.20 : Message d'absence récurrente (configurée par tech) ───────────────────────────────────────────────────────────────────────── */ .tech-absence-recurring { padding: 14px 12px; @@ -2013,11 +2013,14 @@ body.modal-open { z-index: 5 !important; opacity: 1 !important; pointer-events: auto !important; - /* Pas de bordure bleue, pas de padding-top (plus de dragbar), juste les - styles de base du tooltip (hérités de .tooltip). */ - border: 1px solid var(--border-strong) !important; + /* v2026.5.43 : on conserve les MÊMES dimensions que .pinned-popup + (padding-top 28px, border 2px) pour que la popup ne bouge ni ne change + de taille au softUnpin. La dragbar est juste retirée (l'espace + reste, c'est le tradeoff pour préserver position + taille). + Bordure plus discrète (variable --border-strong au lieu de --accent). */ + border: 2px solid var(--border-strong) !important; box-shadow: var(--shadow-hover) !important; - padding-top: 12px !important; + padding-top: 28px !important; animation: none !important; } @@ -3045,9 +3048,12 @@ body.popup-dragging .pinned-popup { min-width: 130px; animation: pill-hover-menu-appear 0.12s ease-out; } +/* v2026.5.43 : pas de transform dans cette animation — Firefox inclut les + transforms dans getBoundingClientRect ce qui fausse le calcul de position + du menu juste après son insertion dans le DOM. Animation en opacité seule. */ @keyframes pill-hover-menu-appear { - from { opacity: 0; transform: translateY(4px); } - to { opacity: 1; transform: translateY(0); } + from { opacity: 0; } + to { opacity: 1; } } .pill-hover-menu-btn { display: flex; @@ -3419,7 +3425,7 @@ html.theme-dark .card.absence-cat-conge { } /* ========================================================================== - v2026.5.30 : absences récurrentes (Pillonel vendredi) en cyan + v2026.5.30 : absences récurrentes (configurées par tech) en cyan (même couleur que Congé mais texte distinct "Absent le vendredi") ========================================================================== */ diff --git a/src/viewer.js b/src/viewer.js index 1d5321f..a04562c 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -9339,9 +9339,19 @@ function _showPillHoverMenu(pill, popup) { }); menu.appendChild(closeBtn); + // v2026.5.43 (Firefox-fix) : positionner le menu HORS écran d'abord pour + // qu'il soit layouté sans flash, puis mesurer ses dimensions, puis poser + // la position finale. Sans ça, Firefox lit parfois des dimensions à 0 + // (timing de l'animation `pill-hover-menu-appear` + transform initial), + // ce qui projette le menu n'importe où sur l'écran. + menu.style.left = "-9999px"; + menu.style.top = "-9999px"; + menu.style.visibility = "hidden"; document.body.appendChild(menu); + // Force le navigateur à calculer la mise en page maintenant (Firefox ne + // le fait pas toujours sur getBoundingClientRect immédiat après append). + void menu.offsetHeight; - // Positionner au-dessus de la pastille const r = pill.getBoundingClientRect(); const menuR = menu.getBoundingClientRect(); let left = r.left + (r.width / 2) - (menuR.width / 2); @@ -9349,6 +9359,7 @@ function _showPillHoverMenu(pill, popup) { if (left + menuR.width > window.innerWidth - 4) left = window.innerWidth - menuR.width - 4; menu.style.left = left + "px"; menu.style.top = (r.top - menuR.height - 8) + "px"; + menu.style.visibility = ""; // Garder ouvert si la souris entre dans le menu menu.addEventListener("mouseenter", () => {