planif: fix figement carte des tournées suggérées (boucle de rendu) + tracés routiers réels
Cause : :routes="suggestRoutes.map(...)" inline créait un NOUVEAU tableau à chaque rendu → watch deep
de RouteMap → draw → emit('metrics') → onRouteMetrics mutait realRoutes → re-rendu → nouveau tableau →
BOUCLE INFINIE (onglet figé ; le remplacement asynchrone OSRM ne finissait jamais → lignes à vol d'oiseau).
Fix : computed CACHÉ suggestMapRoutes (réf stable) + onRouteMetrics idempotent. La géométrie routière OSRM
(vérifiée côté serveur : 200, ~405 pts) s'affiche maintenant.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9142d6dd26
commit
746a8de6df
|
|
@ -1141,7 +1141,7 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="suggestDlg.view === 'map'">
|
<div v-if="suggestDlg.view === 'map'">
|
||||||
<RouteMap :routes="suggestRoutes.map(r => ({ id: r.techId, name: r.techName, color: r.color, home: r.home, stops: r.stops }))" height="440px" @metrics="onRouteMetrics" @stop-click="onReviewStopClick" />
|
<RouteMap :routes="suggestMapRoutes" height="440px" @metrics="onRouteMetrics" @stop-click="onReviewStopClick" />
|
||||||
<div class="suggest-legend">
|
<div class="suggest-legend">
|
||||||
<span v-for="r in suggestRoutes" :key="r.techId" class="suggest-leg"><span class="suggest-leg-dot" :style="{ background: r.color }"></span>{{ r.techName }} · {{ r.stops.length }} arrêt(s)<span v-if="realRoutes[r.techId]"> · 🚗 {{ realRoutes[r.techId].km }} km / {{ realRoutes[r.techId].mins }} min</span><span v-else-if="r.km"> · 🚗 ≈{{ r.km }} km</span></span>
|
<span v-for="r in suggestRoutes" :key="r.techId" class="suggest-leg"><span class="suggest-leg-dot" :style="{ background: r.color }"></span>{{ r.techName }} · {{ r.stops.length }} arrêt(s)<span v-if="realRoutes[r.techId]"> · 🚗 {{ realRoutes[r.techId].km }} km / {{ realRoutes[r.techId].mins }} min</span><span v-else-if="r.km"> · 🚗 ≈{{ r.km }} km</span></span>
|
||||||
<span v-if="!suggestRoutes.length" class="text-grey-6" style="font-size:12px">Aucun job géolocalisé ce jour (utilise « Localiser » sur le pool pour les placer sur la carte).</span>
|
<span v-if="!suggestRoutes.length" class="text-grey-6" style="font-size:12px">Aucun job géolocalisé ce jour (utilise « Localiser » sur le pool pour les placer sur la carte).</span>
|
||||||
|
|
@ -3452,7 +3452,15 @@ function refreshAssignMap () {
|
||||||
function destroyAssignMap () { assignLasso.value = false; if (_assignMapRO) { try { _assignMapRO.disconnect() } catch (e) {} _assignMapRO = null } if (_assignMap) { try { _assignMap.remove() } catch (e) {} _assignMap = null } }
|
function destroyAssignMap () { assignLasso.value = false; if (_assignMapRO) { try { _assignMapRO.disconnect() } catch (e) {} _assignMapRO = null } if (_assignMap) { try { _assignMap.remove() } catch (e) {} _assignMap = null } }
|
||||||
// ── Grande carte des TOURNÉES proposées (revue Suggérer) : ligne domicile→arrêts par tech, 1 couleur/tech, 1 jour ──
|
// ── Grande carte des TOURNÉES proposées (revue Suggérer) : ligne domicile→arrêts par tech, 1 couleur/tech, 1 jour ──
|
||||||
// Carte de la revue = composant partagé <RouteMap> (P2). Les métriques réelles (OSRM) remontent ici pour la légende.
|
// Carte de la revue = composant partagé <RouteMap> (P2). Les métriques réelles (OSRM) remontent ici pour la légende.
|
||||||
function onRouteMetrics (m) { for (const k in realRoutes) delete realRoutes[k]; Object.assign(realRoutes, m) }
|
function onRouteMetrics (m) {
|
||||||
|
// Idempotent : ne muter realRoutes QUE si les valeurs changent (sinon re-rendu inutile → risque de boucle avec RouteMap)
|
||||||
|
const keys = Object.keys(m || {})
|
||||||
|
let same = keys.length === Object.keys(realRoutes).length
|
||||||
|
if (same) for (const k of keys) { const a = realRoutes[k], b = m[k]; if (!a || a.km !== b.km || a.mins !== b.mins) { same = false; break } }
|
||||||
|
if (same) return
|
||||||
|
for (const k in realRoutes) delete realRoutes[k]
|
||||||
|
Object.assign(realRoutes, m)
|
||||||
|
}
|
||||||
// D v2 — routes RÉELLES : Mapbox Directions par tech (domicile→arrêts) → géométrie routière + distance/durée réelles. Cache par signature.
|
// D v2 — routes RÉELLES : Mapbox Directions par tech (domicile→arrêts) → géométrie routière + distance/durée réelles. Cache par signature.
|
||||||
const _routeCache = new Map()
|
const _routeCache = new Map()
|
||||||
const realRoutes = reactive({}) // techId → { km, mins } (la légende préfère ces valeurs réelles quand présentes)
|
const realRoutes = reactive({}) // techId → { km, mins } (la légende préfère ces valeurs réelles quand présentes)
|
||||||
|
|
@ -5019,6 +5027,10 @@ const suggestRoutes = computed(() => {
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
})
|
})
|
||||||
|
// RÉFÉRENCE STABLE pour <RouteMap :routes> — computed CACHÉ (ne change QUE si suggestRoutes change).
|
||||||
|
// AVANT : `:routes="suggestRoutes.map(...)"` inline créait un NOUVEAU tableau à CHAQUE rendu → le watch deep de RouteMap
|
||||||
|
// redessinait → emit('metrics') → onRouteMetrics muta realRoutes → re-rendu → nouveau tableau → BOUCLE INFINIE (figeait la carte).
|
||||||
|
const suggestMapRoutes = computed(() => suggestRoutes.value.map(r => ({ id: r.techId, name: r.techName, color: r.color, home: r.home, stops: r.stops })))
|
||||||
// Carte de la revue = <RouteMap> (réactif sur suggestRoutes) — il ne reste qu'à défauter le jour affiché à l'ouverture de la vue carte.
|
// Carte de la revue = <RouteMap> (réactif sur suggestRoutes) — il ne reste qu'à défauter le jour affiché à l'ouverture de la vue carte.
|
||||||
watch(() => suggestDlg.view, (v) => { if (v === 'map' && !suggestMapDay.value) suggestMapDay.value = suggestWindow.value[0] || '' })
|
watch(() => suggestDlg.view, (v) => { if (v === 'map' && !suggestMapDay.value) suggestMapDay.value = suggestWindow.value[0] || '' })
|
||||||
// ── P3 — Onglet « Tournées » : tournées RÉELLES (jobs assignés, occupation) de la journée choisie, 1 couleur/tech, tracés OSRM (RouteMap). ──
|
// ── P3 — Onglet « Tournées » : tournées RÉELLES (jobs assignés, occupation) de la journée choisie, 1 couleur/tech, tracés OSRM (RouteMap). ──
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user