diff --git a/assets/js/hooks/coverage_hooks.ts b/assets/js/hooks/coverage_hooks.ts index c692bc14..af72da2f 100644 --- a/assets/js/hooks/coverage_hooks.ts +++ b/assets/js/hooks/coverage_hooks.ts @@ -503,12 +503,42 @@ export const MultiCoverageMap = { addCoverageLayer(this: MultiCoverageMapState, c: CoveragePayload) { const [minLat, minLon, maxLat, maxLon] = c.bbox const png = this.pngForCoverage(c) + if (!png) { + console.warn(`MultiCoverageMap: no PNG for coverage ${c.id}`) + return + } const overlay = L.imageOverlay(png, [[minLat, minLon], [maxLat, maxLon]], { opacity: this.currentOpacity(), interactive: false, }) this.overlays.set(c.id, overlay) + // Antenna marker (TX location with azimuth wedge). + if (c.tx.lat !== null && c.tx.lon !== null) { + const az = c.tx.azimuth ?? 0 + const icon = L.divIcon({ + className: "coverage-antenna-marker", + html: ` +
+ <%!-- Top bar: title, status, actions. Compact so the map can dominate. --%> +
<.icon name="hero-map-pin" class="h-4 w-4 inline" /> <.link navigate={~p"/sites/#{@coverage.site_id}"} class="hover:underline"> {@coverage.site && @coverage.site.name} @@ -20,13 +22,22 @@
<.icon name="hero-clock" class="h-4 w-4 inline" /> {t("Coverage is queued. Compute will start shortly.")} @@ -92,151 +104,304 @@
- {t("No heatmap available yet. Run compute to generate the coverage prediction.")} -
-| + {t("Tower")} + | ++ {t("Distance")} + | ++ RSSI + | +
|---|---|---|
| + {row.coverage.name} + | ++ {fmt_distance(row.distance_m, @probe_units)} + | ++ "text-gray-400" + + is_number(row.rssi) and row.rssi >= -75 -> + "text-green-600 dark:text-green-400 font-bold" + + is_number(row.rssi) and row.rssi >= -85 -> + "text-yellow-600 dark:text-yellow-400" + + is_number(row.rssi) -> + "text-red-600 dark:text-red-400" + + true -> + "text-gray-400" + end + ]}> + {fmt_rssi(row.rssi)} + | +
+ {t("No heatmap available yet. Run compute to generate the coverage prediction.")} +
+