Compare commits

...

1 Commits

Author SHA1 Message Date
FroSteel 7e497de40e Version 2026.5.30 — Absence récurrente cyan + mode compact 24"
[code interpolé]
2026-04-23 17:00:00 +02:00
3 changed files with 40 additions and 29 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "Planification", "name": "Planification",
"version": "2026.5.29", "version": "2026.5.30",
"description": "Vue claire et rapide du planning des techniciens EasyVista. Regroupe interventions et réservations par tech, affiche horaires, contact, lieu, catégorie et statut en un coup d'œil.", "description": "Vue claire et rapide du planning des techniciens EasyVista. Regroupe interventions et réservations par tech, affiche horaires, contact, lieu, catégorie et statut en un coup d'œil.",
"browser_specific_settings": { "browser_specific_settings": {
"gecko": { "gecko": {
+8 -5
View File
@@ -2622,12 +2622,15 @@ header.topbar::before {
v2026.5.23 : refonte complète en style "onglet" single-line, compact v2026.5.23 : refonte complète en style "onglet" single-line, compact
========================================================================== */ ========================================================================== */
.pinned-popup.pinned-popup-minimized { .pinned-popup.pinned-popup-minimized {
display: flex !important;
flex-direction: row !important;
align-items: center !important;
min-width: 300px !important; min-width: 300px !important;
max-width: 360px !important; max-width: 400px !important;
width: 300px !important; width: auto !important;
height: auto !important; height: 36px !important;
min-height: 80px !important; min-height: 36px !important;
padding: 44px 16px 16px 16px !important; padding: 0 6px 0 4px !important;
overflow: visible; overflow: visible;
background: var(--bg-elevated) !important; background: var(--bg-elevated) !important;
border: 1px solid var(--border) !important; border: 1px solid var(--border) !important;
+31 -23
View File
@@ -5275,17 +5275,34 @@ function openPersistentTimelinePopup(el) {
return; return;
} }
const ivIdx = el.dataset.ivIdx; const ivIdx = el.dataset.ivIdx;
if (ivIdx === undefined) return; if (ivIdx === undefined) {
console.log("[persistentTimeline] segment sans ivIdx (hole/absence vide) — abandon");
return;
}
const cardEl = el.closest(".card"); const cardEl = el.closest(".card");
if (!cardEl) return; if (!cardEl) {
console.warn("[persistentTimeline] pas de .card parent trouvée");
return;
}
const row = cardEl.querySelector(`.intervention-v2[data-iv-idx="${ivIdx}"]`); const row = cardEl.querySelector(`.intervention-v2[data-iv-idx="${ivIdx}"]`);
if (!row) return; if (!row) {
console.warn(`[persistentTimeline] row intervention-v2[data-iv-idx="${ivIdx}"] introuvable`);
return;
}
const actionId = row.dataset.actionId; const actionId = row.dataset.actionId;
const iv = findIvByActionId(actionId); const iv = findIvByActionId(actionId);
if (!iv) return; if (!iv) {
console.warn(`[persistentTimeline] iv pour actionId=${actionId} introuvable`);
return;
}
const tip = tooltipEl(); const tip = tooltipEl();
if (!tip) return; if (!tip) {
console.warn("[persistentTimeline] tooltipEl() null");
return;
}
console.log(`[persistentTimeline] ouverture grande popup pour iv actionId=${actionId}`);
// Nettoyer tout état précédent (ancrage, épinglage, timers) // Nettoyer tout état précédent (ancrage, épinglage, timers)
bulleState.pinned = false; bulleState.pinned = false;
@@ -5298,29 +5315,20 @@ function openPersistentTimelinePopup(el) {
tip.innerHTML = buildTooltipHTML(iv); tip.innerHTML = buildTooltipHTML(iv);
tip.classList.remove("hidden"); tip.classList.remove("hidden");
tip.classList.add("visible"); tip.classList.add("visible");
// mode "anchored" : le hover ne doit pas la remplacer par une autre popup // mode "anchored" : le hover timeline ne doit pas la remplacer par la petite popup
tip.dataset.mode = "anchored"; tip.dataset.mode = "anchored";
state.currentTooltipIv = iv; state.currentTooltipIv = iv;
// Position : juste sous le segment timeline. D'abord on reset les coords // v2026.5.34 : utiliser positionTooltipAnchored() unifié, en préférant
// pour que getBoundingClientRect() reflète la vraie taille du nouveau // dessous (sous le segment timeline) via opts.anchorBelow = true.
// contenu. //
// D'abord on reset les coords pour que le tipRect soit correctement mesuré
// avec le nouveau contenu.
tip.style.left = "-9999px"; tip.style.left = "-9999px";
tip.style.top = "0px"; tip.style.top = "0px";
// Forcer un reflow pour que tipRect soit à jour avec le nouveau contenu // Force reflow
const tipRect = tip.getBoundingClientRect(); void tip.offsetWidth;
const r = el.getBoundingClientRect(); positionTooltipAnchored(el, { anchorBelow: true });
let x = r.left;
let y = r.bottom + 8;
if (x + tipRect.width > window.innerWidth - 8) x = window.innerWidth - tipRect.width - 8;
if (x < 4) x = 4;
if (y + tipRect.height > window.innerHeight - 8) {
y = r.top - tipRect.height - 8;
}
if (y < 4) y = 4;
// Positionner proprement (avec détection auto fixed vs abs)
setTooltipViewportPosition(x, y);
} }
function showTimelinePopover(e, el) { function showTimelinePopover(e, el) {