# RFCP — Iteration 3.10.4: Terrain Profile Click Fix & TX Height ## Two bugs remaining from previous iterations. --- ## Bug 1: Terrain Profile click still places ruler point **Problem:** Clicking inside the Terrain Profile popup (chart area, close button, fresnel checkbox, anywhere in the popup) triggers the map click handler underneath, which places a ruler point or resets the measurement. **Previous fix was incomplete** — stopPropagation was added to some elements but not the entire popup container and its backdrop. **Fix:** The Terrain Profile popup needs a FULL click barrier. Every mouse event must be caught: ```typescript // The OUTERMOST container of the Terrain Profile popup:
{ e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} onMouseDown={(e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} onMouseUp={(e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} onPointerDown={(e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} onPointerUp={(e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} onDoubleClick={(e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }} > {/* All terrain profile content */}
``` **IMPORTANT:** `stopPropagation()` alone may not be enough because Leaflet listens to DOM events directly, not React synthetic events. The fix MUST also call `e.nativeEvent.stopImmediatePropagation()` to prevent Leaflet's native DOM listener from firing. **Alternative approach (more robust):** Add the popup OUTSIDE the Leaflet map container in the DOM tree. If the Terrain Profile div is a sibling or parent of the map div (not a child), Leaflet's event delegation won't catch clicks on it at all. ```tsx // In the main layout:
{/* Leaflet map renders here */}
{/* These are OUTSIDE the map container — Leaflet can't intercept */} {showTerrainProfile && ( )} {showLinkBudget && ( )}
``` If moving outside the map container is too much refactoring, the stopImmediatePropagation approach should work. But check: is the TerrainProfile component rendered INSIDE a Leaflet pane or overlay? If so, moving it out is the correct fix. **Also apply the same fix to:** - Link Budget Calculator panel - Any other floating panel/popup that sits over the map --- ## Bug 2: TX Height always shows 2m in Link Budget Calculator **Problem:** The Link Budget Calculator TRANSMITTER section always shows `Height: 2m` regardless of the actual site configuration. It should read the height from the selected site's settings. **Root cause:** The LinkBudgetPanel component likely reads `site.height` but the site object might store height in a different field name (e.g., `site.antennaHeight`, `site.towerHeight`, `site.params.height`, or per-sector height). **Fix:** Find where site height is stored and pass the correct value: ```typescript // In LinkBudgetPanel.tsx, find where TX height is set: // WRONG (probably current): const txHeight = site.height || 2; // Defaults to 2 if field is missing // Check the actual site data structure. It might be: const txHeight = site.antennaHeight || site.tower_height || site.params?.height || site.sectors?.[0]?.height // If height is per-sector || 30; // Default should be 30m for a typical cell tower, not 2m // Or if height is stored in meters in a nested config: const txHeight = selectedSite?.config?.height || selectedSite?.height || 30; ``` **Steps to debug:** 1. In the browser console (F12), find the selected site object 2. Check what field contains the height value 3. Update LinkBudgetPanel to read from the correct field **Display fix:** ```typescript // In the TRANSMITTER section of the panel:
Height: {txHeight} m
``` The height should also be EDITABLE in the link budget calculator (as an input field, not just display), since you might want to test "what if I put the antenna at 40m instead of 30m?" without changing the actual site config. ```typescript // Make height an editable field with site value as default: const [txHeightOverride, setTxHeightOverride] = useState(null); const txHeight = txHeightOverride ?? (site?.height || 30);
setTxHeightOverride(parseFloat(e.target.value))} /> m
``` --- ## Testing Checklist - [ ] Click ANYWHERE inside Terrain Profile popup — NO ruler point placed - [ ] Click Terrain Profile close button (X) — popup closes, no ruler point - [ ] Click Fresnel Zone checkbox — toggles, no ruler point - [ ] Click chart area — no ruler point - [ ] Drag/scroll inside chart — no map pan/zoom - [ ] TX Height in Link Budget shows actual site height (not 2m) - [ ] TX Height is editable for what-if scenarios - [ ] Changing TX height recalculates link budget ## Commit Message ``` fix(ui): block all click propagation from terrain profile, fix TX height - Add stopImmediatePropagation on terrain profile container - Prevent all mouse/pointer events from reaching Leaflet map - Fix TX height reading from site config (was defaulting to 2m) - Make TX height editable in link budget calculator ```