diff --git a/kort7/app.js b/kort7/app.js index 0e12b10..e554057 100644 --- a/kort7/app.js +++ b/kort7/app.js @@ -19,6 +19,7 @@ L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { const statusEl = document.getElementById("status"); const alertsEl = document.getElementById("presenceAlerts"); +const selectedVehicleInfoEl = document.getElementById("selectedVehicleInfo"); const offmapIndicatorsEl = document.getElementById("offmapIndicators"); const playBtn = document.getElementById("playBtn"); const pauseBtn = document.getElementById("pauseBtn"); @@ -33,6 +34,23 @@ function highlightOffmapIndicator(name) { }); } +function renderSelectedVehicleInfo(v, sourceLabel = "kort") { + if (!v) { + selectedVehicleInfoEl.textContent = "Klik på et køretøj eller en hjørneindikator for detaljer."; + return; + } + + selectedVehicleInfoEl.innerHTML = ` + ${v.name} · valgt fra ${sourceLabel} + Tid: ${fmtTs(v.current.ts)}
+ Position: ${v.displayLat.toFixed(5)}, ${v.displayLon.toFixed(5)}
+ Hastighed: ${v.current.speedMps} m/s
+ Retning: ${v.displayHeading.toFixed(0)}°
+ Usikkerhed: ${v.current.uncertaintyM} m
+ Status: ${v.presenceStateLabel || "ja"} + `; +} + function flashVehicleMarker(v) { const markerEl = v.marker.getElement(); if (!markerEl) return; @@ -48,6 +66,7 @@ function openVehiclePopup(name) { forcedPopupVehicle = name; highlightOffmapIndicator(name); + renderSelectedVehicleInfo(v, "hjørneindikator"); if (!map.hasLayer(v.marker)) { v.marker.addTo(map); @@ -354,6 +373,11 @@ for (const name of vehicleNames) { }; marker.bindPopup(popupHtml(name, vehicles[name])); + marker.on("click", () => { + forcedPopupVehicle = name; + highlightOffmapIndicator(null); + renderSelectedVehicleInfo(vehicles[name], "kort"); + }); setHeading(marker, first.headingDeg); } @@ -365,6 +389,9 @@ const TIME_SCALE = 0.175; function resetDemo() { simTime = 0; lastFrameTime = null; + forcedPopupVehicle = null; + highlightOffmapIndicator(null); + renderSelectedVehicleInfo(null); for (const name of vehicleNames) { const v = vehicles[name]; @@ -585,6 +612,7 @@ map.on("popupclose", (event) => { if (popupVehicle && forcedPopupVehicle === popupVehicle.name) { forcedPopupVehicle = null; highlightOffmapIndicator(null); + renderSelectedVehicleInfo(null); updateVehicleDisplay(popupVehicle); } }); diff --git a/kort7/kort7.html b/kort7/kort7.html index b95956e..ac7f7e2 100644 --- a/kort7/kort7.html +++ b/kort7/kort7.html @@ -42,6 +42,22 @@ white-space: pre-line; } + .hud .selection { + margin-top: 10px; + padding-top: 10px; + border-top: 1px solid rgba(0,0,0,0.08); + max-width: 320px; + font: 12px/1.4 system-ui, sans-serif; + color: #1f2937; + } + + .hud .selection strong { + display: block; + margin-bottom: 4px; + font-size: 13px; + color: #111827; + } + .hud .alerts { margin-top: 8px; display: grid; @@ -162,6 +178,7 @@
+
Klik på et køretøj eller en hjørneindikator for detaljer.
diff --git a/kort7/tests/kort7.spec.js b/kort7/tests/kort7.spec.js index 0f5f67a..a3e26dc 100644 --- a/kort7/tests/kort7.spec.js +++ b/kort7/tests/kort7.spec.js @@ -91,7 +91,7 @@ test.describe('kort7 vehicle map', () => { await expect(alerts).not.toContainText('Bil 8'); }); - test('opens vehicle popup when clicking an off-map corner indicator', async ({ page }) => { + test('updates left info panel when clicking an off-map corner indicator', async ({ page }) => { await page.goto('/kort7.html'); await page.getByRole('button', { name: 'Pause' }).click(); @@ -99,16 +99,10 @@ test.describe('kort7 vehicle map', () => { await expect(indicator).toBeVisible(); await indicator.click(); - const popup = page.locator('.leaflet-popup'); - await expect(popup).toBeVisible(); - await expect(popup).toContainText('Bil 9'); - await expect(popup).toContainText('Usikkerhed:'); - await expect(popup).toContainText('På kortet:'); - - await expect(page.locator('.leaflet-popup')).toBeVisible(); - - const popupBox = await page.locator('.leaflet-popup').boundingBox(); - expect(popupBox).not.toBeNull(); - expect(popupBox.y).toBeLessThan(220); + const selection = page.locator('#selectedVehicleInfo'); + await expect(selection).toContainText('Bil 9'); + await expect(selection).toContainText('valgt fra hjørneindikator'); + await expect(selection).toContainText('Usikkerhed: 9000 m'); + await expect(indicator).toHaveClass(/active/); }); });