All checks were successful
Build Docker Image / build (push) Successful in 4m14s
- Remove currentMapBounds from watch - it changes on every map move - Watch only filterByBounds and urlBounds (URL-based state) - Add early return in setBoundsFilter if bounds haven't changed This fixes the issue where the list was reloading on every map movement even when the 'filter by bounds' checkbox was OFF.
135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import { SuppliersListDocument, NearestSuppliersDocument } from '~/composables/graphql/public/geo-generated'
|
|
|
|
const PAGE_SIZE = 24
|
|
|
|
// Shared state across list and map views
|
|
const items = ref<any[]>([])
|
|
const total = ref(0)
|
|
const isLoading = ref(false)
|
|
const isLoadingMore = ref(false)
|
|
const isInitialized = ref(false)
|
|
const filterProductUuid = ref<string | null>(null)
|
|
const filterBounds = ref<{ west: number; south: number; east: number; north: number } | null>(null)
|
|
|
|
export function useCatalogSuppliers() {
|
|
const { execute } = useGraphQL()
|
|
|
|
const itemsWithCoords = computed(() =>
|
|
items.value.filter(s => s.latitude && s.longitude)
|
|
)
|
|
|
|
const canLoadMore = computed(() => items.value.length < total.value)
|
|
|
|
const fetchPage = async (offset: number, replace = false) => {
|
|
if (replace) isLoading.value = true
|
|
try {
|
|
// If filtering by product, use nearestSuppliers with global search
|
|
// (center point 0,0 with very large radius to cover entire globe)
|
|
if (filterProductUuid.value) {
|
|
const data = await execute(
|
|
NearestSuppliersDocument,
|
|
{
|
|
lat: 0,
|
|
lon: 0,
|
|
radius: 20000, // 20000 km radius covers entire Earth
|
|
productUuid: filterProductUuid.value,
|
|
limit: 500 // Increased limit for global search
|
|
},
|
|
'public',
|
|
'geo'
|
|
)
|
|
items.value = data?.nearestSuppliers || []
|
|
total.value = items.value.length
|
|
isInitialized.value = true
|
|
return
|
|
}
|
|
|
|
// Default: fetch all suppliers from GEO (graph-based)
|
|
const data = await execute(
|
|
SuppliersListDocument,
|
|
{
|
|
limit: PAGE_SIZE,
|
|
offset,
|
|
...(filterBounds.value && {
|
|
west: filterBounds.value.west,
|
|
south: filterBounds.value.south,
|
|
east: filterBounds.value.east,
|
|
north: filterBounds.value.north
|
|
})
|
|
},
|
|
'public',
|
|
'geo'
|
|
)
|
|
const next = data?.suppliersList || []
|
|
|
|
items.value = replace ? next : items.value.concat(next)
|
|
// suppliersList doesn't return total count, estimate from fetched items
|
|
if (replace) {
|
|
total.value = next.length < PAGE_SIZE ? next.length : next.length + PAGE_SIZE
|
|
} else if (next.length < PAGE_SIZE) {
|
|
total.value = items.value.length
|
|
}
|
|
isInitialized.value = true
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
const loadMore = async () => {
|
|
if (isLoadingMore.value) return
|
|
isLoadingMore.value = true
|
|
try {
|
|
await fetchPage(items.value.length)
|
|
} finally {
|
|
isLoadingMore.value = false
|
|
}
|
|
}
|
|
|
|
// Initialize data if not already loaded
|
|
const init = async () => {
|
|
if (!isInitialized.value && items.value.length === 0) {
|
|
await fetchPage(0, true)
|
|
}
|
|
}
|
|
|
|
const setProductFilter = (uuid: string | null) => {
|
|
if (filterProductUuid.value === uuid) return // Early return if unchanged
|
|
filterProductUuid.value = uuid
|
|
if (isInitialized.value) {
|
|
fetchPage(0, true)
|
|
}
|
|
}
|
|
|
|
const setBoundsFilter = (bounds: { west: number; south: number; east: number; north: number } | null) => {
|
|
// Early return if bounds haven't changed
|
|
const prev = filterBounds.value
|
|
const same = prev === bounds || (
|
|
prev && bounds &&
|
|
prev.west === bounds.west &&
|
|
prev.south === bounds.south &&
|
|
prev.east === bounds.east &&
|
|
prev.north === bounds.north
|
|
)
|
|
if (same) return
|
|
|
|
filterBounds.value = bounds
|
|
if (isInitialized.value) {
|
|
fetchPage(0, true)
|
|
}
|
|
}
|
|
|
|
return {
|
|
items,
|
|
total,
|
|
isLoading,
|
|
isLoadingMore,
|
|
itemsWithCoords,
|
|
canLoadMore,
|
|
fetchPage,
|
|
loadMore,
|
|
init,
|
|
setProductFilter,
|
|
setBoundsFilter
|
|
}
|
|
}
|