Make off-map indicators clickable

This commit is contained in:
Morten V. Christiansen 2026-04-05 12:42:57 +02:00
parent 1c2c876a40
commit 0be14600fb
3 changed files with 48 additions and 2 deletions

View File

@ -23,6 +23,20 @@ const playBtn = document.getElementById("playBtn");
const pauseBtn = document.getElementById("pauseBtn"); const pauseBtn = document.getElementById("pauseBtn");
const resetBtn = document.getElementById("resetBtn"); const resetBtn = document.getElementById("resetBtn");
function openVehiclePopup(name) {
const v = vehicles[name];
if (!v) return;
if (!map.hasLayer(v.marker)) {
v.marker.addTo(map);
}
v.marker.setLatLng([v.displayLat, v.displayLon]);
setHeading(v.marker, v.displayHeading);
v.marker.setPopupContent(popupHtml(v.name, v));
v.marker.openPopup();
}
function carIcon(color) { function carIcon(color) {
return L.divIcon({ return L.divIcon({
className: "", className: "",
@ -455,13 +469,13 @@ function updateAlerts() {
: `Mulig tilstedeværelse fra ${direction.label}`; : `Mulig tilstedeværelse fra ${direction.label}`;
return ` return `
<div class="offmap-indicator ${v.presenceState === "covers" ? "covers" : ""}" data-vehicle="${v.name}"> <button type="button" class="offmap-indicator ${v.presenceState === "covers" ? "covers" : ""}" data-vehicle="${v.name}">
<div class="offmap-arrow" style="background:${v.color};">${direction.arrow}</div> <div class="offmap-arrow" style="background:${v.color};">${direction.arrow}</div>
<div class="offmap-meta"> <div class="offmap-meta">
<strong>${v.name}</strong> <strong>${v.name}</strong>
<span>${subtitle}</span> <span>${subtitle}</span>
</div> </div>
</div> </button>
`; `;
}).join(""); }).join("");
} }
@ -515,6 +529,14 @@ resetBtn.addEventListener("click", () => {
requestAnimationFrame(tick); requestAnimationFrame(tick);
}); });
offmapIndicatorsEl.addEventListener("click", (event) => {
const button = event.target.closest(".offmap-indicator");
if (!button) return;
const vehicleName = button.dataset.vehicle;
openVehiclePopup(vehicleName);
});
map.on("moveend zoomend", () => { map.on("moveend zoomend", () => {
for (const name of vehicleNames) { for (const name of vehicleNames) {
updateVehicleDisplay(vehicles[name]); updateVehicleDisplay(vehicles[name]);

View File

@ -76,6 +76,7 @@
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
gap: 10px; gap: 10px;
align-items: center; align-items: center;
width: 100%;
padding: 9px 11px; padding: 9px 11px;
border-radius: 12px; border-radius: 12px;
background: rgba(18, 18, 18, 0.86); background: rgba(18, 18, 18, 0.86);
@ -83,6 +84,14 @@
border: 1px solid rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.12);
box-shadow: 0 6px 18px rgba(0,0,0,0.22); box-shadow: 0 6px 18px rgba(0,0,0,0.22);
font: 12px/1.3 system-ui, sans-serif; font: 12px/1.3 system-ui, sans-serif;
pointer-events: auto;
cursor: pointer;
text-align: left;
}
.offmap-indicator:hover {
transform: translateY(-1px);
box-shadow: 0 8px 20px rgba(0,0,0,0.28);
} }
.offmap-indicator.covers { .offmap-indicator.covers {

View File

@ -90,4 +90,19 @@ test.describe('kort7 vehicle map', () => {
await expect(alerts).toContainText('Bil 10: usikkerhed dækker hele kortet'); await expect(alerts).toContainText('Bil 10: usikkerhed dækker hele kortet');
await expect(alerts).not.toContainText('Bil 8'); await expect(alerts).not.toContainText('Bil 8');
}); });
test('opens vehicle popup when clicking an off-map corner indicator', async ({ page }) => {
await page.goto('/kort7.html');
await page.getByRole('button', { name: 'Pause' }).click();
const indicator = page.locator('.offmap-indicator').filter({ hasText: 'Bil 9' });
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:');
});
}); });