feat(catalog): add loading states for InfoPanel tabs and filter map by active tab
All checks were successful
Build Docker Image / build (push) Successful in 3m35s

- Add separate loading states for products, hubs, suppliers, offers
- Show spinner on tabs while loading, disable tab during load
- Filter relatedPoints on map by current active tab
This commit is contained in:
Ruslan Bakiev
2026-01-26 17:49:59 +07:00
parent f680740f52
commit 3f56a2f117
3 changed files with 156 additions and 93 deletions

View File

@@ -287,7 +287,7 @@ export function useCatalogInfo() {
}
// Load offers for supplier after product selection
const loadOffersForSupplier = async (supplierUuid: string, productUuid: string) => {
const loadOffersForSupplier = async (_supplierUuid: string, productUuid: string) => {
try {
const supplier = entity.value
if (!supplier?.latitude || !supplier?.longitude) {
@@ -295,52 +295,61 @@ export function useCatalogInfo() {
return
}
// Find offers near supplier for this product
const offersData = await execute(
NearestOffersDocument,
{
lat: supplier.latitude,
lon: supplier.longitude,
productUuid,
radius: 500,
limit: 12
},
'public',
'geo'
)
isLoadingOffers.value = true
isLoadingHubs.value = true
relatedOffers.value = offersData?.nearestOffers || []
try {
// Find offers near supplier for this product
const offersData = await execute(
NearestOffersDocument,
{
lat: supplier.latitude,
lon: supplier.longitude,
productUuid,
radius: 500,
limit: 12
},
'public',
'geo'
)
// Load hubs near each offer and aggregate (limit to 12)
const allHubs = new Map<string, any>()
for (const offer of relatedOffers.value.slice(0, 3)) {
// Check first 3 offers
if (!offer.latitude || !offer.longitude) continue
relatedOffers.value = offersData?.nearestOffers || []
isLoadingOffers.value = false
try {
const hubsData = await execute(
NearestHubsDocument,
{
lat: offer.latitude,
lon: offer.longitude,
radius: 1000,
limit: 5
},
'public',
'geo'
)
hubsData?.nearestHubs?.forEach((hub: any) => {
if (!allHubs.has(hub.uuid)) {
allHubs.set(hub.uuid, hub)
}
})
} catch (e) {
console.warn('Error loading hubs for offer:', offer.uuid, e)
// Load hubs near each offer and aggregate (limit to 12)
const allHubs = new Map<string, any>()
for (const offer of relatedOffers.value.slice(0, 3)) {
// Check first 3 offers
if (!offer.latitude || !offer.longitude) continue
try {
const hubsData = await execute(
NearestHubsDocument,
{
lat: offer.latitude,
lon: offer.longitude,
radius: 1000,
limit: 5
},
'public',
'geo'
)
hubsData?.nearestHubs?.forEach((hub: any) => {
if (!allHubs.has(hub.uuid)) {
allHubs.set(hub.uuid, hub)
}
})
} catch (e) {
console.warn('Error loading hubs for offer:', offer.uuid, e)
}
if (allHubs.size >= 12) break
}
if (allHubs.size >= 12) break
relatedHubs.value = Array.from(allHubs.values()).slice(0, 12)
} finally {
isLoadingOffers.value = false
isLoadingHubs.value = false
}
relatedHubs.value = Array.from(allHubs.values()).slice(0, 12)
} catch (error) {
console.error('Error loading offers for supplier:', error)
}
@@ -396,6 +405,10 @@ export function useCatalogInfo() {
relatedOffers.value = []
selectedProduct.value = null
activeTab.value = 'products'
isLoadingProducts.value = false
isLoadingHubs.value = false
isLoadingSuppliers.value = false
isLoadingOffers.value = false
}
return {
@@ -408,6 +421,10 @@ export function useCatalogInfo() {
selectedProduct,
activeTab,
isLoading,
isLoadingProducts,
isLoadingHubs,
isLoadingSuppliers,
isLoadingOffers,
// Actions
loadInfo,