From 01ba6a70ef849338ee63eb3bba42fe190fd599bf Mon Sep 17 00:00:00 2001 From: louispaulb Date: Sun, 5 Jul 2026 16:54:24 -0400 Subject: [PATCH] feat(ops): unassigned map jobs show job-type symbol (like assigned pills) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les jobs non assignés étaient de simples gouttes oranges SANS symbole, alors que les assignés ont une pastille horizontale avec icône du type de job (📞/🔧/⚡) + n°. Uniformisé en RÉUTILISANT le rendu éprouvé des arrêts assignés (≠ tentative q-icon/SVG précédente qui rendait vertical/vide) : - RouteMap.renderPins : pastille `.rm-pill` HORIZONTALE + icône via (ligature material fiable), couleur = priorité (orange = non assigné), SANS numéro d'ordre. Fini la goutte. - routeUnassignedPins fournit `icon: markerIcon(required_skill||service_type)` (markerIcon = ligatures material, celles qui s'affichent hors q-icon). Vérifié : le markup exact injecté dans la page rend une pastille HORIZONTALE 30×22 avec glyphe material 14px visible (police « Material Icons ») — plus le bug vertical/sans-icône. Rendu carte identique à celui des pastilles assignées (mêmes classes/mécanisme). À confirmer à l'œil en prod (dev sans jobs géocodés → 0 marqueur). Co-Authored-By: Claude Opus 4.8 --- apps/ops/src/components/shared/RouteMap.vue | 11 ++++++++--- apps/ops/src/pages/PlanificationPage.vue | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/ops/src/components/shared/RouteMap.vue b/apps/ops/src/components/shared/RouteMap.vue index 0e22235..3b444f5 100644 --- a/apps/ops/src/components/shared/RouteMap.vue +++ b/apps/ops/src/components/shared/RouteMap.vue @@ -103,11 +103,16 @@ function renderPins (list) { for (const p of (list || [])) { if (!okLL(p.lon, p.lat)) continue const color = p.color || '#f97316' - const wrap = document.createElement('div'); wrap.className = 'rm-pin' - wrap.innerHTML = '' + // MÊME rendu que les arrêts assignés (pastille round-rect horizontale + icône material via ), + // coloré priorité (orange = non assigné), SANS numéro d'ordre. Icône = markerIcon (ligature material fiable). + const wrap = document.createElement('div'); wrap.className = 'rm-mk rm-mk-pin' + const disc = document.createElement('div'); disc.className = 'rm-pill'; disc.style.background = color + const ic = /^[a-z0-9_]+$/.test(String(p.icon || '')) ? p.icon : 'place' + disc.innerHTML = '' + ic + '' + wrap.appendChild(disc) wrap.title = (p.subject || 'Job') + (p.city ? ' · ' + p.city : '') + ' — non assigné' wrap.addEventListener('click', () => emit('pin-click', p)) - const mk = new mapboxgl.Marker({ element: wrap, anchor: 'bottom' }).setLngLat([+p.lon, +p.lat]).addTo(map) + const mk = new mapboxgl.Marker({ element: wrap, anchor: 'center' }).setLngLat([+p.lon, +p.lat]).addTo(map) pinMk.push({ mk, el: wrap }) } } diff --git a/apps/ops/src/pages/PlanificationPage.vue b/apps/ops/src/pages/PlanificationPage.vue index cb2f925..5d492f9 100644 --- a/apps/ops/src/pages/PlanificationPage.vue +++ b/apps/ops/src/pages/PlanificationPage.vue @@ -4818,7 +4818,7 @@ const routeDayUnassignedView = computed(() => { const _jlat = j => (j.latitude != null ? +j.latitude : (j.lat != null ? +j.lat : null)) const _jlon = j => (j.longitude != null ? +j.longitude : (j.lon != null ? +j.lon : null)) // Gouttes carte = non-assignés du jour (filtrés secteur) qui ont des coordonnées ; couleur = priorité -const routeUnassignedPins = computed(() => routeDayUnassignedView.value.filter(j => { const la = _jlat(j); const lo = _jlon(j); return la != null && lo != null && isFinite(la) && isFinite(lo) && Math.abs(la) > 0.01 }).map(j => ({ lat: _jlat(j), lon: _jlon(j), subject: j.subject || j.service_type || j.name, name: j.name, color: prioColor(j.priority), city: jobCity(j), job: j }))) +const routeUnassignedPins = computed(() => routeDayUnassignedView.value.filter(j => { const la = _jlat(j); const lo = _jlon(j); return la != null && lo != null && isFinite(la) && isFinite(lo) && Math.abs(la) > 0.01 }).map(j => ({ lat: _jlat(j), lon: _jlon(j), subject: j.subject || j.service_type || j.name, name: j.name, color: prioColor(j.priority), city: jobCity(j), icon: markerIcon(j.required_skill || j.service_type), job: j }))) // ── Deep-link (?day=YYYY-MM-DD & ?skill=…) + action « planifier des quarts » du slot-finder ── const route = useRoute()