feat(catalog): pad map fit and graph hubs filter
All checks were successful
Build Docker Image / build (push) Successful in 5m4s
All checks were successful
Build Docker Image / build (push) Successful in 5m4s
This commit is contained in:
@@ -53,6 +53,7 @@ const props = withDefaults(defineProps<{
|
||||
initialCenter?: [number, number]
|
||||
initialZoom?: number
|
||||
infoLoading?: boolean
|
||||
fitPaddingLeft?: number
|
||||
relatedPoints?: Array<{
|
||||
uuid: string
|
||||
name: string
|
||||
@@ -67,6 +68,7 @@ const props = withDefaults(defineProps<{
|
||||
initialZoom: 2,
|
||||
useServerClustering: false,
|
||||
infoLoading: false,
|
||||
fitPaddingLeft: 0,
|
||||
items: () => [],
|
||||
clusteredPoints: () => [],
|
||||
clusteredPointsByType: undefined,
|
||||
@@ -88,6 +90,16 @@ const usesTypedClusters = computed(() => {
|
||||
return !!typed && Object.keys(typed).length > 0
|
||||
})
|
||||
|
||||
const buildFitPadding = (base: number) => {
|
||||
const extraLeft = Math.max(0, props.fitPaddingLeft || 0)
|
||||
return {
|
||||
top: base,
|
||||
bottom: base,
|
||||
left: base + extraLeft,
|
||||
right: base
|
||||
}
|
||||
}
|
||||
|
||||
// Entity type icons - SVG data URLs with specific colors
|
||||
const createEntityIcon = (type: 'offer' | 'hub' | 'supplier', color: string) => {
|
||||
const icons = {
|
||||
@@ -536,7 +548,7 @@ const initClientClusteringLayers = async (map: MapboxMapType) => {
|
||||
bounds.extend([item.longitude, item.latitude])
|
||||
}
|
||||
})
|
||||
map.fitBounds(bounds, { padding: 50, maxZoom: 10 })
|
||||
map.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 10 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}
|
||||
@@ -962,7 +974,7 @@ watch(() => props.infoLoading, (loading, wasLoading) => {
|
||||
bounds.extend([p.longitude, p.latitude])
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 80, maxZoom: 12 })
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(80), maxZoom: 12 })
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1013,7 +1025,7 @@ watch(() => props.clusteredPoints, (points) => {
|
||||
}
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 50, maxZoom: 6 })
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 6 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}
|
||||
@@ -1033,7 +1045,7 @@ watch(() => props.clusteredPointsByType, () => {
|
||||
})
|
||||
})
|
||||
if (!bounds.isEmpty()) {
|
||||
mapRef.value.fitBounds(bounds, { padding: 50, maxZoom: 6 })
|
||||
mapRef.value.fitBounds(bounds, { padding: buildFitPadding(50), maxZoom: 6 })
|
||||
didFitBounds.value = true
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
:hovered-item="hoveredItem"
|
||||
:related-points="relatedPoints"
|
||||
:info-loading="infoLoading"
|
||||
:fit-padding-left="fitPaddingLeft"
|
||||
@select-item="onMapSelect"
|
||||
@bounds-change="onBoundsChange"
|
||||
/>
|
||||
@@ -188,6 +189,34 @@ const { mapViewMode, setMapViewMode, selectMode, startSelect, cancelSelect } = u
|
||||
// Panel is open when selectMode is set OR when showPanel prop is true (info/quote)
|
||||
const isPanelOpen = computed(() => props.showPanel || selectMode.value !== null)
|
||||
|
||||
const isDesktop = ref(false)
|
||||
onMounted(() => {
|
||||
const media = window.matchMedia('(min-width: 1024px)')
|
||||
const update = () => {
|
||||
isDesktop.value = media.matches
|
||||
}
|
||||
update()
|
||||
media.addEventListener('change', update)
|
||||
onUnmounted(() => {
|
||||
media.removeEventListener('change', update)
|
||||
})
|
||||
})
|
||||
|
||||
const panelWidthPx = computed(() => {
|
||||
const match = props.panelWidth.match(/w-\[(\d+(?:\.\d+)?)rem\]/)
|
||||
if (match) return Number(match[1]) * 16
|
||||
if (props.panelWidth === 'w-96') return 24 * 16
|
||||
if (props.panelWidth === 'w-80') return 20 * 16
|
||||
return 0
|
||||
})
|
||||
|
||||
const fitPaddingLeft = computed(() => {
|
||||
if (!isPanelOpen.value || !isDesktop.value || panelWidthPx.value === 0) return 0
|
||||
const leftInset = 16
|
||||
const rightInset = 16
|
||||
return leftInset + panelWidthPx.value + rightInset
|
||||
})
|
||||
|
||||
// Open panel based on current mapViewMode
|
||||
const openPanel = () => {
|
||||
const newSelectMode = mapViewMode.value === 'hubs' ? 'hub'
|
||||
|
||||
Reference in New Issue
Block a user