v2026.5.35 — Fix popup épinglé position vue horizontale + stats gauche

This commit is contained in:
Quentin Rouiller
2026-04-24 13:11:16 +02:00
parent 02524e78b2
commit fd466504c2
3 changed files with 120 additions and 10 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "Planification", "name": "Planification",
"version": "2026.5.34", "version": "2026.5.35",
"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.",
"permissions": ["activeTab", "scripting", "storage", "tabs", "alarms"], "permissions": ["activeTab", "scripting", "storage", "tabs", "alarms"],
"host_permissions": [ "host_permissions": [
+68 -5
View File
@@ -3495,21 +3495,29 @@ html.view-horizontal .card {
} }
/* Header devient une barre latérale gauche fixe */ /* Header devient une barre latérale gauche fixe */
/* v2026.5.35 : réduit à 140px (au lieu de 200px) pour donner plus de place à la timeline */
html.view-horizontal .card-header { html.view-horizontal .card-header {
flex-direction: column !important; flex-direction: column !important;
align-items: flex-start !important; align-items: flex-start !important;
justify-content: center !important; justify-content: center !important;
min-width: 200px !important; min-width: 140px !important;
max-width: 200px !important; max-width: 140px !important;
border-bottom: none !important; border-bottom: none !important;
border-right: 1px solid var(--border) !important; border-right: 1px solid var(--border) !important;
padding: 8px 12px !important; padding: 6px 10px !important;
gap: 4px !important; gap: 3px !important;
flex: 0 0 auto; flex: 0 0 auto;
} }
html.view-horizontal .card-tech-name { html.view-horizontal .card-tech-name {
font-size: 14px !important; font-size: 13px !important;
font-weight: 600; font-weight: 600;
line-height: 1.2 !important;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
max-width: 100%;
} }
html.view-horizontal .card-tech-badge { html.view-horizontal .card-tech-badge {
font-size: 10px !important; font-size: 10px !important;
@@ -3575,3 +3583,58 @@ html.view-horizontal .tech-row-stats .stat-pill {
html.view-classic .tech-row-stats { html.view-classic .tech-row-stats {
display: none !important; display: none !important;
} }
/* ==========================================================================
v2026.5.35 : en vue horizontale, stats globales sur le CÔTÉ GAUCHE
(colonne verticale fixe) au lieu d'être au-dessus des cartes.
Libère de la hauteur verticale pour les 8 techs.
========================================================================== */
html.view-horizontal main {
display: flex;
flex-direction: row;
align-items: stretch;
}
html.view-horizontal .stats {
flex: 0 0 auto;
width: 200px;
flex-direction: column !important;
align-items: flex-start !important;
gap: 8px !important;
padding: 12px 16px !important;
border-right: 1px solid var(--border);
background: var(--bg-muted);
position: sticky;
top: 0;
align-self: flex-start;
min-height: calc(100vh - 80px);
font-size: 12px !important;
}
html.view-horizontal .stats .global-stat {
display: block;
width: 100%;
padding: 4px 0;
}
html.view-horizontal .stats .global-stat-main b {
font-size: 18px !important;
color: var(--text);
}
/* Masquer les séparateurs "·" en vue verticale */
html.view-horizontal .stats .global-stat-sep {
display: none !important;
}
html.view-horizontal .cards {
flex: 1 1 auto;
min-width: 0; /* autorise le shrink si grand nombre de techs */
}
/* Breakpoint étroit : stats plus compactes */
@media (max-width: 1400px) {
html.view-horizontal .stats {
width: 160px;
padding: 8px 12px !important;
font-size: 11px !important;
}
}
+49 -2
View File
@@ -7007,13 +7007,60 @@ function pinTooltip() {
if (closeAllBtn) closeAllBtn.remove(); if (closeAllBtn) closeAllBtn.remove();
} }
// Chercher la ligne source (row iv-v2) // Chercher la ligne source pour le positionnement.
// v2026.5.35 : en vue horizontale, les rows .intervention-v2 sont CACHÉES
// (display: none via CSS .view-horizontal). getBoundingClientRect d'un
// élément caché retourne (0,0,0,0) → popup part en haut à gauche.
// Solution : priorité au tooltip actuellement visible (qui EST la vraie
// source visuelle du clic/hover). Fallback sur le segment timeline. Enfin
// la row (qui marche en vue classique).
let rowEl = null; let rowEl = null;
const _isHorizontalView = document.documentElement.classList.contains("view-horizontal");
if (_isHorizontalView) {
console.log("[pinTooltip] vue horizontale → source = tooltip visible ou segment timeline");
// Priorité 1 : le tooltip actuellement affiché (meilleure source visuelle)
const currentTip = tooltipEl();
if (currentTip && currentTip.classList.contains("visible")) {
const r = currentTip.getBoundingClientRect();
if (r.width > 0 && r.height > 0) {
rowEl = currentTip;
console.log(`[pinTooltip] source = tooltip visible (${Math.round(r.left)}, ${Math.round(r.top)})`);
}
}
// Priorité 2 : segment timeline pour cette actionId
if (!rowEl && iv.actionId) {
// Il peut y avoir plusieurs .timeline-slot avec le même ivIdx si plusieurs
// cartes. On prend celui dont la row parente a le bon actionId.
const allSlots = document.querySelectorAll(".timeline-slot[data-iv-idx]");
for (const slot of allSlots) {
const card = slot.closest(".card");
if (!card) continue;
const ivIdx = slot.dataset.ivIdx;
const row = card.querySelector(`.intervention-v2[data-iv-idx="${ivIdx}"]`);
if (row && row.dataset.actionId === iv.actionId) {
const r = slot.getBoundingClientRect();
if (r.width > 0 && r.height > 0) {
rowEl = slot;
console.log(`[pinTooltip] source = segment timeline actionId=${iv.actionId}`);
break;
}
}
}
}
} else {
// Vue classique : chercher la row .intervention-v2 (comportement d'origine)
if (iv.actionId) { if (iv.actionId) {
rowEl = document.querySelector(`.intervention-v2[data-action-id="${iv.actionId}"]`); rowEl = document.querySelector(`.intervention-v2[data-action-id="${iv.actionId}"]`);
if (rowEl) {
console.log(`[pinTooltip] vue classique → source = row intervention-v2`);
} }
}
}
// Fallback final : le tooltip live (même s'il n'est pas visible) — position actuelle
if (!rowEl) { if (!rowEl) {
// Fallback : utiliser la position actuelle du tooltip live console.warn("[pinTooltip] aucune source visible trouvée → fallback tooltip live");
rowEl = srcEl; rowEl = srcEl;
} }