From 1e761ca2a8df7701ab937848a700ef328b179125 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Fri, 6 Feb 2026 11:23:56 +0700 Subject: [PATCH] Drive map markers by data, not visibility --- app/components/catalog/CatalogMap.vue | 43 +++++---------------------- app/components/page/CatalogPage.vue | 5 +--- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/app/components/catalog/CatalogMap.vue b/app/components/catalog/CatalogMap.vue index 033771e..00ce6a5 100644 --- a/app/components/catalog/CatalogMap.vue +++ b/app/components/catalog/CatalogMap.vue @@ -50,7 +50,6 @@ const props = withDefaults(defineProps<{ hoveredItem?: HoveredItem | null pointColor?: string entityType?: 'offer' | 'hub' | 'supplier' - visibleTypes?: Array<'offer' | 'hub' | 'supplier'> initialCenter?: [number, number] initialZoom?: number infoLoading?: boolean @@ -71,7 +70,6 @@ const props = withDefaults(defineProps<{ items: () => [], clusteredPoints: () => [], clusteredPointsByType: undefined, - visibleTypes: undefined, relatedPoints: () => [] }) @@ -300,10 +298,6 @@ const getServerClusterCountLayerId = (type: 'offer' | 'hub' | 'supplier') => `${ const getServerPointLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-points` const getServerPointLabelLayerId = (type: 'offer' | 'hub' | 'supplier') => `${props.mapId}-server-${type}-point-labels` -const isTypeVisible = (type: 'offer' | 'hub' | 'supplier') => { - if (!props.visibleTypes || props.visibleTypes.length === 0) return true - return props.visibleTypes.includes(type) -} const emitBoundsChange = (map: MapboxMapType) => { const bounds = map.getBounds() @@ -757,9 +751,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => { 'circle-stroke-width': 2, 'circle-stroke-color': '#ffffff' }, - layout: { - visibility: isTypeVisible(type) ? 'visible' : 'none' - } + layout: {} }) map.addLayer({ @@ -769,8 +761,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => { filter: ['>', ['get', 'count'], 1], layout: { 'text-field': ['get', 'count'], - 'text-size': 14, - visibility: isTypeVisible(type) ? 'visible' : 'none' + 'text-size': 14 }, paint: { 'text-color': '#ffffff' } }) @@ -783,8 +774,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => { layout: { 'icon-image': `entity-icon-${type}`, 'icon-size': 1, - 'icon-allow-overlap': true, - visibility: isTypeVisible(type) ? 'visible' : 'none' + 'icon-allow-overlap': true } }) @@ -797,8 +787,7 @@ const initServerClusteringLayersByType = async (map: MapboxMapType) => { 'text-field': ['get', 'name'], 'text-offset': [0, 1.8], 'text-size': 12, - 'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'], - visibility: isTypeVisible(type) ? 'visible' : 'none' + 'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'] }, paint: { 'text-color': '#ffffff', @@ -962,24 +951,7 @@ watch(() => props.relatedPoints, () => { } }, { deep: true }) -watch(() => props.visibleTypes, () => { - if (!mapRef.value || !mapInitialized.value) return - if (!usesTypedClusters.value) return - for (const type of CLUSTER_TYPES) { - const visibility = isTypeVisible(type) ? 'visible' : 'none' - const layers = [ - getServerClusterLayerId(type), - getServerClusterCountLayerId(type), - getServerPointLayerId(type), - getServerPointLabelLayerId(type) - ] - layers.forEach((layerId) => { - if (mapRef.value?.getLayer(layerId)) { - mapRef.value.setLayoutProperty(layerId, 'visibility', visibility) - } - }) - } -}, { deep: true }) +// no visibility toggling; layers are data-driven by query // Fit bounds when info loading finishes (all related data loaded) watch(() => props.infoLoading, (loading, wasLoading) => { @@ -1048,14 +1020,13 @@ watch(() => props.clusteredPoints, (points) => { } }, { immediate: true }) -watch([() => props.clusteredPointsByType, () => props.visibleTypes], () => { +watch(() => props.clusteredPointsByType, () => { if (!usesTypedClusters.value) return if (!mapRef.value || !mapInitialized.value) return if (didFitBounds.value) return const bounds = new LngLatBounds() - const visible = props.visibleTypes && props.visibleTypes.length > 0 ? props.visibleTypes : CLUSTER_TYPES - visible.forEach(type => { + CLUSTER_TYPES.forEach(type => { const points = serverClusteredGeoJsonByType.value[type]?.features ?? [] points.forEach((p) => { const coords = (p.geometry as GeoJSON.Point).coordinates as [number, number] diff --git a/app/components/page/CatalogPage.vue b/app/components/page/CatalogPage.vue index 76421d6..8d95b3d 100644 --- a/app/components/page/CatalogPage.vue +++ b/app/components/page/CatalogPage.vue @@ -18,8 +18,7 @@ :map-id="mapId" :items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)" :clustered-points="isInfoMode ? [] : (useServerClustering && !useTypedClusters ? clusteredNodes : [])" - :clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)" - :visible-types="useServerClustering && useTypedClusters ? visibleTypes : undefined" + :clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)" :use-server-clustering="useServerClustering && !isInfoMode" :point-color="activePointColor" :entity-type="activeEntityType" @@ -310,8 +309,6 @@ const activeClusterType = computed<'offer' | 'hub' | 'supplier'>(() => { return 'offer' }) -const visibleTypes = computed(() => [activeClusterType.value]) - const clusterLoading = computed(() => { if (!useTypedClusters.value) return singleClusterLoading.value if (activeClusterType.value === 'hub') return hubClusters.loading.value