Make the map editor accept a click, and unclutter its panel
Clicking the map in the editor did nothing, ever. The click handler was bound inside `if (props.pickerMode)` at mount, and the editor mounts with no asset selected, so the handler was never attached; selecting an asset flipped the prop but nothing rebound it. The asset forms were unaffected because their picker mounts inside a modal that is already in picker mode, which is why this looked like an editor-only fault. The handler is now bound unconditionally and handleMapClick keeps its own picker-mode guard. Verified in a browser against the dev instance, both ways: with the old binding a click on a selected asset produced no position at all; with the fix the same click reports 1652, 1138. Markers are now drawn in picker mode too. Placing one relative to the machines already on the floor is the entire task, and the old code skipped rendering them whenever the map was a picker. Two things that looked like stray widgets: - The editor's panel header put a heading and three controls on one row inside a 320px panel, squeezing the search box until its placeholder read "Search na". The heading takes its own row and the controls share the next. - The legend drew its bar and border even with nothing to put in it, which read as an empty input box under the toolbar. It renders only when it has entries.
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Legend for asset type mode - shows subtypes when a type is selected -->
|
||||
<div class="map-legend" v-if="!pickerMode && assetTypeMode">
|
||||
<div class="map-legend" v-if="!pickerMode && assetTypeMode && hasLegendEntries">
|
||||
<!-- Show subtype legend when a specific type is selected -->
|
||||
<template v-if="selectedAssetType && Object.keys(visibleSubtypes).length">
|
||||
<span
|
||||
@@ -120,6 +120,14 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['markerClick', 'positionPicked'])
|
||||
|
||||
// An empty legend still drew its bar and border, which looked like a stray input
|
||||
// box under the toolbar. It renders only when it has something in it.
|
||||
const hasLegendEntries = computed(() => {
|
||||
if (props.selectedAssetType && Object.keys(visibleSubtypes.value).length) return true
|
||||
if (Object.keys(visibleAssetTypes.value).length) return true
|
||||
return overlayLegend.value.length > 0
|
||||
})
|
||||
|
||||
const mapContainer = ref(null)
|
||||
let map = null
|
||||
let imageOverlay = null
|
||||
@@ -296,17 +304,22 @@ function initMap() {
|
||||
map.setView([MAP_HEIGHT / 2, MAP_WIDTH / 2], initialZoom)
|
||||
map.setMaxBounds(bounds)
|
||||
|
||||
// Picker mode: click to set position
|
||||
if (props.pickerMode) {
|
||||
map.on('click', handleMapClick)
|
||||
// Bound UNCONDITIONALLY, and handleMapClick ignores the click when picker mode
|
||||
// is off. Binding it only when pickerMode was true AT MOUNT meant a map that
|
||||
// becomes a picker later never got a click handler at all: the map editor
|
||||
// opens with nothing selected, so clicking to place a marker did nothing, for
|
||||
// the whole life of the page. The asset forms only worked because their picker
|
||||
// is mounted inside a modal that is already in picker mode.
|
||||
map.on('click', handleMapClick)
|
||||
|
||||
// Show initial position if provided
|
||||
if (props.initialPosition) {
|
||||
setPickerPosition(props.initialPosition.left, props.initialPosition.top)
|
||||
}
|
||||
} else {
|
||||
renderMarkers()
|
||||
if (props.pickerMode && props.initialPosition) {
|
||||
setPickerPosition(props.initialPosition.left, props.initialPosition.top)
|
||||
}
|
||||
|
||||
// Existing markers are drawn in picker mode too: placing a marker relative to
|
||||
// the ones already on the floor is the whole task. The forms pass no markers,
|
||||
// so this costs them nothing.
|
||||
renderMarkers()
|
||||
}
|
||||
|
||||
function handleMapClick(e) {
|
||||
|
||||
@@ -518,13 +518,27 @@ function cancelEdit() {
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
/* The heading takes its own row and the three controls share the next one(s).
|
||||
All four on a single row inside a 320px panel squeezed the search box until
|
||||
its placeholder read "Search na". */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.panel-header h3 {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.panel-header .form-control {
|
||||
/* Shrinkable and equal, so nothing gets crushed to fit a sibling. */
|
||||
flex: 1 1 8rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.panel-header h3 {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
|
||||
Reference in New Issue
Block a user