feat: add Phase 2 features to map-editor plugin (rich marker content)
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 16s

Implement marker editing modal with comprehensive content management:
- MarkerEditor.vue modal with custom overlay (replaces k-dialog)
- Edit marker on double-click or via edit button in list
- Required fields: title (validated), optional description
- Editable position (lat/lon) and custom icon support
- Content blocks system: add/remove/reorder text and image blocks
- French translations for all UI elements
- Click marker in list to center map on it with smooth animation
- Fix marker anchor to bottom (pin tip) for accurate positioning
- Auto-save with isDirty flag to detect any form changes

Modal features:
- Title field (required)
- Description textarea (optional)
- Position inputs (latitude/longitude)
- Icon selector (default or custom via UUID/filename)
- Content builder with text and image blocks
- Block reordering (up/down) and deletion
- Validation: save button enabled only when title filled and form modified

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-01-28 16:16:19 +01:00
parent dc84ff63a2
commit 437349cd2b
5 changed files with 532 additions and 94 deletions

View file

@ -191,9 +191,11 @@ export default {
try {
// Create MapLibre marker
// Anchor at bottom-center (where the pin tip is)
const marker = new maplibregl.Marker({
element: el,
draggable: true
draggable: true,
anchor: 'bottom'
})
.setLngLat([markerData.position.lon, markerData.position.lat])
.addTo(map.value);
@ -223,6 +225,12 @@ export default {
emit("marker-click", markerData.id);
});
// Handle marker double-click
el.addEventListener("dblclick", (e) => {
e.stopPropagation();
emit("marker-dblclick", markerData.id);
});
// Store marker reference
markerElements.value.set(markerData.id, {
marker,
@ -259,10 +267,21 @@ export default {
};
}
function centerOnPosition(lat, lon) {
if (map.value && map.value.loaded()) {
map.value.flyTo({
center: [lon, lat],
zoom: map.value.getZoom(),
duration: 1000
});
}
}
return {
mapContainer,
loading,
getCurrentCenter
getCurrentCenter,
centerOnPosition
};
}
};