feat: add map framing save button and prevent initial load save
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 17s

- Add "Définir le cadrage" button in multi mode to save current map
  center and zoom as default framing
- Add getCurrentZoom() method in MapPreview to retrieve current zoom level
- Fix: prevent automatic save on initial load with isInitialLoad flag
  to avoid marking page as modified when loading existing data
- Style: dark button theme for save framing button

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-02-06 09:20:12 +01:00
parent 8e67431622
commit 5531aebc04
4 changed files with 20738 additions and 606 deletions

View file

@ -17,6 +17,17 @@
<!-- Map preview -->
<div class="map-preview-container">
<!-- Save framing button (multi mode only) -->
<button
v-if="mode === 'multi'"
class="save-framing-button"
type="button"
@click="saveCurrentFraming"
title="Utiliser le niveau de zoom et centrage actuel comme cadrage par défaut"
>
Définir le cadrage
</button>
<MapPreview
v-if="mapReady"
ref="mapPreview"
@ -100,6 +111,7 @@ export default {
const mapReady = ref(false);
const mapPreview = ref(null);
const selectedMarkerId = ref(null);
const isInitialLoad = ref(true);
// Extract page ID from field name
// For single mode, we don't need the API
@ -132,14 +144,15 @@ export default {
? useMarkersApi(pageId.value)
: { markers: ref([]), loading: ref(false), error: ref(null) };
const { center, zoom, loadMapData, debouncedSave } = useMapData({
defaultCenter: {
lat: props.defaultCenter[0],
lon: props.defaultCenter[1],
},
defaultZoom: props.defaultZoom,
onSave: (yamlString) => emit('input', yamlString),
});
const { center, zoom, loadMapData, saveMapData, debouncedSave } =
useMapData({
defaultCenter: {
lat: props.defaultCenter[0],
lon: props.defaultCenter[1],
},
defaultZoom: props.defaultZoom,
onSave: (yamlString) => emit('input', yamlString),
});
// Computed: markers based on mode
const markers = computed(() => {
@ -290,13 +303,19 @@ export default {
await nextTick();
mapReady.value = true;
// Mark initial load as complete
// Use nextTick to ensure all reactive updates from loadMapData are done
await nextTick();
isInitialLoad.value = false;
});
// Watch center and zoom for automatic save (multi mode only)
watch(
[center, zoom],
() => {
if (props.mode === 'multi') {
// Don't save during initial load to avoid marking page as modified
if (props.mode === 'multi' && !isInitialLoad.value) {
debouncedSave();
}
},
@ -484,6 +503,32 @@ export default {
}
}
/**
* Save current map framing (center + zoom)
*/
function saveCurrentFraming() {
if (!mapPreview.value) return;
// Get current center and zoom from the map
const currentCenter = mapPreview.value.getCurrentCenter
? mapPreview.value.getCurrentCenter()
: { lat: center.value.lat, lon: center.value.lon };
const currentZoom = mapPreview.value.getCurrentZoom
? mapPreview.value.getCurrentZoom()
: zoom.value;
// Update state
center.value = {
lat: currentCenter.lat,
lon: currentCenter.lon,
};
zoom.value = currentZoom;
// Save immediately (not debounced)
saveMapData();
}
return {
// State
center,
@ -504,6 +549,7 @@ export default {
handleLocationSelect,
deleteMarker,
editMarker,
saveCurrentFraming,
};
},
};
@ -537,4 +583,29 @@ export default {
background: #f0f0f0;
min-width: 0;
}
.save-framing-button {
position: absolute;
top: 10px;
right: 10px;
z-index: 1000;
padding: 8px 16px;
background: var(--color-black);
border: 1px solid var(--color-border);
border-radius: var(--rounded);
font-size: 13px;
font-weight: 500;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.2s;
}
.save-framing-button:hover {
background: var(--color-gray-700);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.save-framing-button:active {
transform: translateY(1px);
}
</style>

View file

@ -309,6 +309,13 @@ export default {
};
}
function getCurrentZoom() {
if (map.value && map.value.loaded()) {
return map.value.getZoom();
}
return props.zoom;
}
function centerOnPosition(lat, lon) {
if (map.value && map.value.loaded()) {
map.value.flyTo({
@ -323,6 +330,7 @@ export default {
mapContainer,
loading,
getCurrentCenter,
getCurrentZoom,
centerOnPosition
};
}