Refactor catalog layout: replace Teleport with provide/inject
All checks were successful
Build Docker Image / build (push) Successful in 4m1s

- Create useCatalogLayout composable for data transfer from pages to layout
- Layout now owns SearchBar and CatalogMap components directly
- Pages provide data via provideCatalogLayout()
- Fixes navigation glitches (multiple SearchBars) when switching tabs
- Support custom subNavItems for clientarea pages
- Unify 6 pages to use catalog layout:
  - catalog/offers, suppliers, hubs
  - clientarea/orders, addresses, offers
This commit is contained in:
Ruslan Bakiev
2026-01-15 10:49:40 +07:00
parent 4bd5b882e0
commit 7ea96a97b3
8 changed files with 828 additions and 387 deletions

View File

@@ -0,0 +1,71 @@
import type { Ref, ComputedRef, Component, VNode } from 'vue'
export interface CatalogFilter {
id: string
label: string
}
export interface CatalogMapItem {
uuid: string
name?: string
latitude: number
longitude: number
[key: string]: any
}
export interface CatalogHoveredItem {
latitude: number
longitude: number
}
export interface SubNavItem {
label: string
path: string
}
export interface CatalogLayoutData {
// SubNavigation (optional - if provided, overrides default catalog nav)
subNavItems?: SubNavItem[]
// SearchBar
searchQuery: Ref<string>
activeFilters: ComputedRef<CatalogFilter[]> | Ref<CatalogFilter[]>
displayedCount: ComputedRef<number> | Ref<number>
totalCount: ComputedRef<number> | Ref<number>
onSearch: () => void
onRemoveFilter: (id: string) => void
// Filter slot - can be a component, render function, or VNode
filterComponent?: Component | (() => VNode | VNode[])
// Header slot - optional component to render above the list (e.g. "Add" button)
headerComponent?: Component | (() => VNode | VNode[])
// Map
mapItems: ComputedRef<CatalogMapItem[]> | Ref<CatalogMapItem[]>
mapId: string
pointColor: string
hoveredItemId: Ref<string | undefined>
hoveredItem: ComputedRef<CatalogHoveredItem | null> | Ref<CatalogHoveredItem | null>
onMapSelect: (uuid: string) => void
onBoundsChange?: (bounds: any) => void
searchWithMap: Ref<boolean>
// Clustering (optional)
useServerClustering?: boolean
clusteredNodes?: ComputedRef<any[]> | Ref<any[]>
}
const CATALOG_LAYOUT_KEY = Symbol('catalogLayout')
/**
* Provide catalog layout data from page to layout
*/
export const provideCatalogLayout = (data: CatalogLayoutData) => {
provide(CATALOG_LAYOUT_KEY, data)
}
/**
* Inject catalog layout data in layout from page
*/
export const useCatalogLayoutData = (): CatalogLayoutData | undefined => {
return inject<CatalogLayoutData>(CATALOG_LAYOUT_KEY)
}