Four fixes around the dispatch header following dispatcher feedback:
1. **⋯ overflow menu was invisible**: .sb-header had `overflow:hidden`,
which clipped the absolutely-positioned dropdown right at the
header's bottom edge. Switched the header to `overflow:visible`
(children all have flex-shrink:0 + a flex:1 center, so the layout
doesn't actually overflow horizontally). Bumped z-index to 5000
for safety on top of map/calendar layers.
2. **NLP/Assistant IA bar hidden by default**: was eagerly rendering
on every page load, with the long French placeholder polluting
the header below the toolbar. The user just wanted the icon. Now
`nlpVisible` defaults to false, persisted in localStorage so power
users who flip it on keep it open across sessions. Toggle still
lives in the ⋯ menu.
3. **Click a tech in the resource list now flies the map to them**:
selectTechOnBoard previously only opened the map panel. Now it
also `map.flyTo({ center })` using `tech.gpsCoords ?? tech.coords`
— live Traccar position wins when the tech is online; falls back
to the saved home base. Animated, deferred a tick so map.resize()
happens first, otherwise flyTo can land on garbage coords during
the panel's open transition.
4. **Board view tabs collapsed into a "Vue principale ▾" dropdown**:
was [Vue principale][Par région][+] inline. Now a single button
showing the active view; click reveals the others + the future
"+ Nouvelle vue" entry. Same dropdown component as the ⋯ menu
(shared CSS, click-outside + ESC close).
Three connected UX changes:
1. **Map centered on Gigafibre HQ on first load** —
Sainte-Clotilde (lng=-73.6756, lat=45.1599), zoom 10 — covers the
service area (Sainte-Clotilde + Châteauguay + Napierville +
Hemmingford). Was downtown Montréal.
2. **Right-click on a tech pin** opens the existing techCtx menu
(already used from the calendar via @ctx-tech). New entries:
• 📍 Adresse de départ… → openTechHomeDialog
• 🎯 Choisir sur la carte → startTechGeoFix (mirrors the existing
geoFixJob flow used for jobs)
3. **The 📍 button in the GPS sidebar** now offers a 2-option chooser
first: "Saisir une adresse" or "Cliquer sur la carte". Picking the
map option drops the user into geoFixTech mode.
Implementation:
• useMap.js: new geoFixTech ref + startTechGeoFix/cancelTechGeoFix
+ a contextmenu listener on each tech outer wrapper that calls
openTechCtx(e, tech). The map's main click handler now branches:
if geoFixTech is set, persist the lng/lat via saveTechHome (passed
in via deps as a forward-bound arrow because saveTechHome is
destructured below the useMap call in DispatchPage).
• DispatchPage.vue: new banner shown while in pick mode (animated
indigo bar at top, "Cliquez sur la carte pour {tech}", with a
cancel button); ESC also cancels.
• dispatch-styles.scss: .sb-geofix-banner styles + reusing the
existing pulse keyframe.
The map marker container was being created with an inline
`position:relative`, which overrode Mapbox GL's `.mapboxgl-marker`
class (which applies `position:absolute`). Mapbox writes
`transform: translate(<x>, <y>)` to that exact element on every
zoom/pan frame to project lat/lng → screen coordinates. With the
element kept in the document flow (relative), the transform is
interpreted against the document origin instead of the map pane,
so the pin visually drifts as the user zooms in on a tech.
Removing the inline `position:relative` lets the Mapbox class win.
The SVG ring and the avatar div are children with `position:absolute`
inside outer; absolute children only need a positioned ancestor to
form a containing block — `position:absolute` (Mapbox's value)
qualifies just as well as relative, so the avatar stays centered.
Ops app (Vue/Quasar PWA) with dispatch V2 integration, tag system,
customer 360, tickets, and dashboard. Served via standalone nginx
container at erp.gigafibre.ca/ops/ with Traefik StripPrefix + Authentik SSO.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>