Version 2026.5.22 — Régénération tooltip hover après softUnpin
This commit is contained in:
@@ -7419,6 +7419,11 @@ function _attachPopupDragHandler(popup, dragbar) {
|
||||
startLeft = parseFloat(popup.style.left) || 0;
|
||||
startTop = parseFloat(popup.style.top) || 0;
|
||||
popup.classList.add("dragging");
|
||||
// v2026.5.19 : flag global pour que showTooltip ignore les mouseenter
|
||||
// pendant le drag. Ajout d'une classe sur <body> qui désactive les
|
||||
// pointer-events sur les cartes.
|
||||
state._popupDragging = true;
|
||||
document.body.classList.add("popup-dragging");
|
||||
document.addEventListener("mousemove", onMouseMove);
|
||||
document.addEventListener("mouseup", onMouseUp);
|
||||
});
|
||||
@@ -7624,10 +7629,10 @@ function bindTooltipInteractions() {
|
||||
}
|
||||
});
|
||||
|
||||
// Double-Ctrl : v4.3.0
|
||||
// - Si 0 popup épinglé ET un tooltip live visible : épingler
|
||||
// - Si EXACTEMENT 1 popup épinglé ET souris pas dessus : le fermer
|
||||
// - Si 2+ popups épinglés : ne fait rien (ambigu, user doit utiliser Échap)
|
||||
// Double-Ctrl : v2026.5.21 — toggle sur l'intervention survolée
|
||||
// - Si tooltip visible et iv pas encore épinglée pour cette date : épingle
|
||||
// - Si tooltip visible et iv déjà épinglée pour cette date : désépingle
|
||||
// - Sinon (pas de tooltip visible) : rien
|
||||
// On détecte 2 keydown Control dans une fenêtre de 400 ms.
|
||||
let lastCtrlTs = 0;
|
||||
document.addEventListener("keydown", (e) => {
|
||||
@@ -7636,17 +7641,36 @@ function bindTooltipInteractions() {
|
||||
const now = performance.now();
|
||||
if (now - lastCtrlTs < 400) {
|
||||
lastCtrlTs = 0;
|
||||
if (pinnedPopups.length === 0) {
|
||||
// Aucun popup épinglé : épingler le tooltip live s'il y en a un
|
||||
if (state.currentTooltipIv) pinTooltip();
|
||||
} else if (pinnedPopups.length === 1) {
|
||||
// 1 popup épinglé : le fermer si la souris n'est pas dessus
|
||||
const p = pinnedPopups[0];
|
||||
if (!p.el.matches(":hover")) {
|
||||
_closePinnedPopup(p.el);
|
||||
const iv = state.currentTooltipIv;
|
||||
if (!iv) return;
|
||||
const pinState = _getPinStateForIv(iv);
|
||||
if (pinState.isPinned && pinState.popup) {
|
||||
// Déjà épinglée : désépingle (ferme le popup correspondant)
|
||||
const idx = pinnedPopups.findIndex(p => p.el === pinState.popup);
|
||||
if (idx >= 0) pinnedPopups.splice(idx, 1);
|
||||
// Fermer aussi la pastille dock si elle existe
|
||||
if (pinState.popup._linkedPill) {
|
||||
try { pinState.popup._linkedPill.remove(); } catch (e) {}
|
||||
}
|
||||
try { pinState.popup.remove(); } catch (e) {}
|
||||
// Nettoyer dock si vide
|
||||
const dock = document.getElementById("pinned-popups-dock");
|
||||
if (dock && dock.querySelectorAll(".pinned-popup-dock-pill").length === 0) {
|
||||
dock.classList.remove("visible");
|
||||
const closeAllBtn = document.getElementById("pinned-popups-close-all");
|
||||
if (closeAllBtn) closeAllBtn.remove();
|
||||
} else {
|
||||
_ensureDockCloseAllBtn();
|
||||
}
|
||||
// Mettre à jour le tooltip hover (📍 → 📌)
|
||||
const tip = tooltipEl();
|
||||
if (tip && tip.classList.contains("visible")) {
|
||||
tip.innerHTML = buildTooltipHTML(iv);
|
||||
}
|
||||
} else {
|
||||
// Pas encore épinglée : épingle
|
||||
pinTooltip();
|
||||
}
|
||||
// 2+ popups : rien faire (Échap pour tout fermer)
|
||||
} else {
|
||||
lastCtrlTs = now;
|
||||
}
|
||||
@@ -7660,8 +7684,12 @@ function bindTooltipInteractions() {
|
||||
e.preventDefault();
|
||||
const action = btn.dataset.action;
|
||||
if (action === "pin") {
|
||||
// v4.3.0 : toujours épingler (le tooltip live clone son contenu en popup
|
||||
// détaché). Pour désépingler, l'user utilise × sur le popup, ou Échap.
|
||||
// v2026.5.22 : clic sur 📌/📍 dans le tooltip hover = TOUJOURS réépingler
|
||||
// à la position actuelle. Si un popup existe déjà pour cette iv+date,
|
||||
// il est supprimé avant d'en créer un nouveau à côté de la carte survolée.
|
||||
// (La suppression de l'ancien est faite dans pinTooltip() qui gère
|
||||
// l'unicité actionId+date — v2026.5.21.)
|
||||
// Pour désépingler : bouton 📍 dans la topbar du popup, double-Ctrl, ou Échap.
|
||||
if (state.currentTooltipIv) {
|
||||
pinTooltip();
|
||||
}
|
||||
@@ -7804,12 +7832,25 @@ function buildTooltipHTML(iv) {
|
||||
rows.push(`<dt></dt><dd style="color:var(--text-faint);font-size:11px">Cliquer pour ouvrir la fiche</dd>`);
|
||||
}
|
||||
|
||||
// v2026.5.21 : icône épingle adaptative
|
||||
// 📌 (épingle couchée) = pas encore épinglée, clic pour épingler
|
||||
// 📍 (épingle plantée, rouge) = déjà épinglée pour cette (ref + date)
|
||||
// — clic pour désépingler. NB : le popup a sa propre topbar avec un
|
||||
// bouton 📍 explicite ; celui-ci dans le tooltip hover sert surtout
|
||||
// à montrer visuellement l'état à l'user au survol.
|
||||
const _pinState = _getPinStateForIv(iv);
|
||||
const _pinIcon = _pinState.isPinned ? "📍" : "📌";
|
||||
const _pinTitle = _pinState.isPinned
|
||||
? "Cette intervention est déjà épinglée pour ce jour. Cliquer pour désépingler."
|
||||
: "Épingler la bulle (ou double-Ctrl). Cliquer à nouveau pour libérer.";
|
||||
const _pinClass = _pinState.isPinned ? " tooltip-pinbtn-active" : "";
|
||||
|
||||
if (rows.length === 0) {
|
||||
return `<div class="tooltip-actions">
|
||||
<div class="tooltip-actionbtn" data-action="reload" title="Recharger uniquement cette intervention">
|
||||
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2 8a6 6 0 1 0 1.76-4.24M2 3v3h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="tooltip-actionbtn tooltip-pinbtn" data-action="pin" title="Épingler la bulle (ou double-Ctrl). Cliquer à nouveau pour libérer.">📌</div>
|
||||
<div class="tooltip-actionbtn tooltip-pinbtn${_pinClass}" data-action="pin" title="${_pinTitle}">${_pinIcon}</div>
|
||||
</div><dl><dt>Info</dt><dd>Aucun détail disponible</dd></dl>`;
|
||||
}
|
||||
// v4.1.13/14 : boutons d'action en haut à droite (recharger + épingler)
|
||||
@@ -7817,10 +7858,30 @@ function buildTooltipHTML(iv) {
|
||||
<div class="tooltip-actionbtn" data-action="reload" title="Recharger uniquement cette intervention">
|
||||
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2 8a6 6 0 1 0 1.76-4.24M2 3v3h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<div class="tooltip-actionbtn tooltip-pinbtn" data-action="pin" title="Épingler la bulle (ou double-Ctrl). Cliquer à nouveau pour libérer.">📌</div>
|
||||
<div class="tooltip-actionbtn tooltip-pinbtn${_pinClass}" data-action="pin" title="${_pinTitle}">${_pinIcon}</div>
|
||||
</div><dl>${rows.join("")}</dl>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* v2026.5.21 : retourne l'état d'épinglage pour une intervention donnée
|
||||
* (pour la date actuellement affichée). Utilisé pour afficher 📌 vs 📍
|
||||
* dans le tooltip hover.
|
||||
*/
|
||||
function _getPinStateForIv(iv) {
|
||||
if (!iv || !iv.actionId) return { isPinned: false };
|
||||
const date = state.currentDate || "";
|
||||
const key = iv.actionId + "|" + date;
|
||||
for (const p of pinnedPopups) {
|
||||
if (!p || !p.el) continue;
|
||||
const aid = p.el.dataset.actionId || "";
|
||||
const d = p.el.dataset.originDate || "";
|
||||
if (aid + "|" + d === key) {
|
||||
return { isPinned: true, popup: p.el };
|
||||
}
|
||||
}
|
||||
return { isPinned: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Met en forme un texte d'action EasyVista en ajoutant des retours à la ligne
|
||||
* avant chaque étiquette connue ("Date :", "Lieu :", "Contact :", etc.).
|
||||
|
||||
Reference in New Issue
Block a user