feat(catalog): focus map during quote search
All checks were successful
Build Docker Image / build (push) Successful in 4m47s
All checks were successful
Build Docker Image / build (push) Successful in 4m47s
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
:map-id="mapId"
|
:map-id="mapId"
|
||||||
:items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)"
|
:items="isInfoMode ? [] : (useServerClustering ? [] : itemsWithCoords)"
|
||||||
:clustered-points="isInfoMode ? [] : (useServerClustering && !useTypedClusters ? clusteredNodes : [])"
|
:clustered-points="isInfoMode ? [] : (useServerClustering && !useTypedClusters ? clusteredNodes : [])"
|
||||||
:clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)"
|
:clustered-points-by-type="isInfoMode ? undefined : (useServerClustering && useTypedClusters ? clusteredPointsByType : undefined)"
|
||||||
:use-server-clustering="useServerClustering && !isInfoMode"
|
:use-server-clustering="useServerClustering && !isInfoMode"
|
||||||
:point-color="activePointColor"
|
:point-color="activePointColor"
|
||||||
:entity-type="activeEntityType"
|
:entity-type="activeEntityType"
|
||||||
@@ -255,6 +255,7 @@ const props = withDefaults(defineProps<{
|
|||||||
showPanel?: boolean
|
showPanel?: boolean
|
||||||
filterByBounds?: boolean
|
filterByBounds?: boolean
|
||||||
infoLoading?: boolean
|
infoLoading?: boolean
|
||||||
|
forceInfoMode?: boolean
|
||||||
panelWidth?: string
|
panelWidth?: string
|
||||||
hideViewToggle?: boolean
|
hideViewToggle?: boolean
|
||||||
relatedPoints?: Array<{
|
relatedPoints?: Array<{
|
||||||
@@ -275,6 +276,7 @@ const props = withDefaults(defineProps<{
|
|||||||
showPanel: false,
|
showPanel: false,
|
||||||
filterByBounds: false,
|
filterByBounds: false,
|
||||||
infoLoading: false,
|
infoLoading: false,
|
||||||
|
forceInfoMode: false,
|
||||||
panelWidth: 'w-96',
|
panelWidth: 'w-96',
|
||||||
hideViewToggle: false,
|
hideViewToggle: false,
|
||||||
relatedPoints: () => []
|
relatedPoints: () => []
|
||||||
@@ -364,7 +366,7 @@ const selectedMapItem = ref<MapItem | null>(null)
|
|||||||
const mobilePanelExpanded = ref(false)
|
const mobilePanelExpanded = ref(false)
|
||||||
|
|
||||||
// Info mode - when relatedPoints are present, hide clusters and show only related points
|
// Info mode - when relatedPoints are present, hide clusters and show only related points
|
||||||
const isInfoMode = computed(() => props.relatedPoints && props.relatedPoints.length > 0)
|
const isInfoMode = computed(() => props.forceInfoMode || (props.relatedPoints && props.relatedPoints.length > 0))
|
||||||
|
|
||||||
// Hovered item with coordinates for map highlight
|
// Hovered item with coordinates for map highlight
|
||||||
const hoveredItem = computed(() => {
|
const hoveredItem = computed(() => {
|
||||||
|
|||||||
@@ -14,7 +14,9 @@
|
|||||||
:show-panel="showPanel && !kycSheetUuid"
|
:show-panel="showPanel && !kycSheetUuid"
|
||||||
:filter-by-bounds="filterByBounds"
|
:filter-by-bounds="filterByBounds"
|
||||||
:related-points="relatedPoints"
|
:related-points="relatedPoints"
|
||||||
:info-loading="isInfoLoading"
|
:info-loading="mapInfoLoading"
|
||||||
|
:force-info-mode="forceInfoMode"
|
||||||
|
:hide-view-toggle="hideViewToggle"
|
||||||
@select="onMapSelect"
|
@select="onMapSelect"
|
||||||
@bounds-change="onBoundsChange"
|
@bounds-change="onBoundsChange"
|
||||||
@update:filter-by-bounds="$event ? setBoundsInUrl(currentMapBounds) : clearBoundsFromUrl()"
|
@update:filter-by-bounds="$event ? setBoundsInUrl(currentMapBounds) : clearBoundsFromUrl()"
|
||||||
@@ -131,6 +133,7 @@ const toMapItems = <T extends { uuid?: string | null; name?: string | null; lati
|
|||||||
|
|
||||||
// Current selection items for hover highlighting on map
|
// Current selection items for hover highlighting on map
|
||||||
const currentSelectionItems = computed((): MapItemWithCoords[] => {
|
const currentSelectionItems = computed((): MapItemWithCoords[] => {
|
||||||
|
if (showQuoteResults.value) return []
|
||||||
if (selectMode.value === 'product') return [] // Products don't have coordinates
|
if (selectMode.value === 'product') return [] // Products don't have coordinates
|
||||||
if (selectMode.value === 'hub') return toMapItems(filteredHubs.value)
|
if (selectMode.value === 'hub') return toMapItems(filteredHubs.value)
|
||||||
if (selectMode.value === 'supplier') return toMapItems(filteredSuppliers.value)
|
if (selectMode.value === 'supplier') return toMapItems(filteredSuppliers.value)
|
||||||
@@ -340,7 +343,7 @@ watch(infoProduct, async (productUuid) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Related points for Info mode (shown on map) - show current entity + all related entities
|
// Related points for Info mode (shown on map) - show current entity + all related entities
|
||||||
const relatedPoints = computed(() => {
|
const infoRelatedPoints = computed(() => {
|
||||||
if (!infoId.value) return []
|
if (!infoId.value) return []
|
||||||
|
|
||||||
const points: Array<{
|
const points: Array<{
|
||||||
@@ -394,6 +397,50 @@ const relatedPoints = computed(() => {
|
|||||||
return points
|
return points
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Related points for Quote mode (shown on map)
|
||||||
|
const searchHubPoint = ref<MapItemWithCoords | null>(null)
|
||||||
|
|
||||||
|
const searchOfferPoints = computed(() =>
|
||||||
|
offers.value
|
||||||
|
.filter((offer) => offer.latitude != null && offer.longitude != null)
|
||||||
|
.map((offer) => ({
|
||||||
|
uuid: offer.uuid,
|
||||||
|
name: offer.productName || '',
|
||||||
|
latitude: Number(offer.latitude),
|
||||||
|
longitude: Number(offer.longitude),
|
||||||
|
type: 'offer' as const
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
|
const searchRelatedPoints = computed(() => {
|
||||||
|
const points: Array<{
|
||||||
|
uuid: string
|
||||||
|
name: string
|
||||||
|
latitude: number
|
||||||
|
longitude: number
|
||||||
|
type: 'hub' | 'supplier' | 'offer'
|
||||||
|
}> = []
|
||||||
|
|
||||||
|
if (searchHubPoint.value) {
|
||||||
|
points.push({
|
||||||
|
uuid: searchHubPoint.value.uuid,
|
||||||
|
name: searchHubPoint.value.name,
|
||||||
|
latitude: searchHubPoint.value.latitude,
|
||||||
|
longitude: searchHubPoint.value.longitude,
|
||||||
|
type: 'hub'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
searchOfferPoints.value.forEach((point) => points.push(point))
|
||||||
|
return points
|
||||||
|
})
|
||||||
|
|
||||||
|
const relatedPoints = computed(() => {
|
||||||
|
if (infoId.value) return infoRelatedPoints.value
|
||||||
|
if (showQuoteResults.value) return searchRelatedPoints.value
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
|
||||||
// Offers data for quote results
|
// Offers data for quote results
|
||||||
const offers = ref<QuoteOffer[]>([])
|
const offers = ref<QuoteOffer[]>([])
|
||||||
const quoteCalculations = ref<QuoteCalculation[]>([])
|
const quoteCalculations = ref<QuoteCalculation[]>([])
|
||||||
@@ -420,6 +467,13 @@ const isInfoLoading = computed(() =>
|
|||||||
infoLoading.value || isLoadingProducts.value || isLoadingHubs.value || isLoadingSuppliers.value || isLoadingOffers.value
|
infoLoading.value || isLoadingProducts.value || isLoadingHubs.value || isLoadingSuppliers.value || isLoadingOffers.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const mapInfoLoading = computed(() =>
|
||||||
|
isInfoLoading.value || (showQuoteResults.value && offersLoading.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const forceInfoMode = computed(() => showQuoteResults.value)
|
||||||
|
const hideViewToggle = computed(() => showQuoteResults.value)
|
||||||
|
|
||||||
// Show panel when selecting OR when showing info OR when showing quote results
|
// Show panel when selecting OR when showing info OR when showing quote results
|
||||||
const showPanel = computed(() => {
|
const showPanel = computed(() => {
|
||||||
return selectMode.value !== null || infoId.value !== null || showQuoteResults.value
|
return selectMode.value !== null || infoId.value !== null || showQuoteResults.value
|
||||||
@@ -581,6 +635,7 @@ const onSearch = async () => {
|
|||||||
|
|
||||||
offersLoading.value = true
|
offersLoading.value = true
|
||||||
showQuoteResults.value = true
|
showQuoteResults.value = true
|
||||||
|
searchHubPoint.value = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Prefer geo-based offers with routes when hub + product are selected
|
// Prefer geo-based offers with routes when hub + product are selected
|
||||||
@@ -588,6 +643,12 @@ const onSearch = async () => {
|
|||||||
const hubData = await execute(GetNodeDocument, { uuid: hubId.value }, 'public', 'geo')
|
const hubData = await execute(GetNodeDocument, { uuid: hubId.value }, 'public', 'geo')
|
||||||
const hub = hubData?.node
|
const hub = hubData?.node
|
||||||
if (hub?.latitude != null && hub?.longitude != null) {
|
if (hub?.latitude != null && hub?.longitude != null) {
|
||||||
|
searchHubPoint.value = {
|
||||||
|
uuid: hub.uuid,
|
||||||
|
name: hub.name || hub.uuid,
|
||||||
|
latitude: Number(hub.latitude),
|
||||||
|
longitude: Number(hub.longitude)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const calcData = await execute(
|
const calcData = await execute(
|
||||||
QuoteCalculationsDocument,
|
QuoteCalculationsDocument,
|
||||||
@@ -647,6 +708,7 @@ const onSearch = async () => {
|
|||||||
quoteCalculations.value = []
|
quoteCalculations.value = []
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
searchHubPoint.value = null
|
||||||
const vars: GetOffersQueryVariables = {}
|
const vars: GetOffersQueryVariables = {}
|
||||||
if (productId.value) vars.productUuid = productId.value
|
if (productId.value) vars.productUuid = productId.value
|
||||||
if (supplierId.value) vars.teamUuid = supplierId.value
|
if (supplierId.value) vars.teamUuid = supplierId.value
|
||||||
|
|||||||
Reference in New Issue
Block a user