@voyant-travel/catalog-react 0.120.0 → 0.120.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,20 @@
1
1
  import type { CatalogVerticalPageId } from "../catalog-surfaces.js";
2
2
  import type { CatalogSearchHit, CatalogSearchParams } from "../index.js";
3
+ interface CatalogMarket {
4
+ id: string;
5
+ name: string;
6
+ code: string;
7
+ defaultLanguageTag: string;
8
+ }
9
+ export declare function resolveCatalogDefaultMarket(markets: ReadonlyArray<CatalogMarket>, selectedMarketId?: string): CatalogMarket | undefined;
10
+ export declare function resolveCatalogLocaleOptions(market: CatalogMarket | undefined, locales: ReadonlyArray<{
11
+ languageTag: string;
12
+ }>): string[];
13
+ export declare function resolveCatalogSelectedLocale(requestedLocale: string | undefined, localeOptions: ReadonlyArray<string>, market: CatalogMarket | undefined): string;
14
+ export declare function resolveCatalogScope(search: Pick<CatalogSearchParams, "locale" | "market">, localeOptions: ReadonlyArray<string>, market: CatalogMarket | undefined): {
15
+ locale: string;
16
+ market: string | undefined;
17
+ };
3
18
  export interface CatalogVerticalHostProps {
4
19
  vertical: CatalogVerticalPageId;
5
20
  search: CatalogSearchParams;
@@ -42,4 +57,5 @@ export interface CatalogVerticalHostProps {
42
57
  * destination keys declared in `./index.tsx` (packaged-admin RFC §4.7).
43
58
  */
44
59
  export declare function CatalogVerticalHost({ vertical, search, onSearchChange, embedded, lockedFacets, lockedRanges, onOpenDetail, }: CatalogVerticalHostProps): import("react/jsx-runtime").JSX.Element;
60
+ export {};
45
61
  //# sourceMappingURL=catalog-vertical-host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-vertical-host.d.ts","sourceRoot":"","sources":["../../src/admin/catalog-vertical-host.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAgBxE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,MAAM,EAAE,mBAAmB,CAAA;IAC3B,cAAc,EAAE,CACd,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,mBAAmB,EAC3D,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAA;IACT;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAA;IACrD;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC/C;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,cAAc,EACd,QAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,EAAE,wBAAwB,2CAuP1B"}
1
+ {"version":3,"file":"catalog-vertical-host.d.ts","sourceRoot":"","sources":["../../src/admin/catalog-vertical-host.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAgBxE,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,EACrC,gBAAgB,CAAC,EAAE,MAAM,GACxB,aAAa,GAAG,SAAS,CAM3B;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,aAAa,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9C,MAAM,EAAE,CASV;AAED,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,MAAM,EAAE,aAAa,GAAG,SAAS,GAChC,MAAM,CAKR;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,QAAQ,CAAC,EACtD,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EACpC,MAAM,EAAE,aAAa,GAAG,SAAS;;;EAMlC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,MAAM,EAAE,mBAAmB,CAAA;IAC3B,cAAc,EAAE,CACd,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,mBAAmB,EAC3D,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAA;IACT;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAA;IACrD;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC/C;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,cAAc,EACd,QAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,EAAE,wBAAwB,2CAmP1B"}
@@ -12,6 +12,35 @@ import { useCatalogUiMessagesOrDefault } from "../i18n/index.js";
12
12
  import { createCatalogEnrichmentFetchers, fetchCatalogSlots, useVoyantCatalogContext, } from "../index.js";
13
13
  const DEFAULT_MARKET_VALUE = "__default__";
14
14
  const DEFAULT_CATALOG_LOCALE = "en-GB";
15
+ export function resolveCatalogDefaultMarket(markets, selectedMarketId) {
16
+ return (markets.find((market) => market.id === selectedMarketId) ??
17
+ markets.find((market) => market.code === "default") ??
18
+ markets[0]);
19
+ }
20
+ export function resolveCatalogLocaleOptions(market, locales) {
21
+ const tags = new Set();
22
+ if (market) {
23
+ tags.add(market.defaultLanguageTag);
24
+ for (const locale of locales)
25
+ tags.add(locale.languageTag);
26
+ }
27
+ else {
28
+ tags.add(DEFAULT_CATALOG_LOCALE);
29
+ }
30
+ return Array.from(tags).sort((left, right) => left.localeCompare(right));
31
+ }
32
+ export function resolveCatalogSelectedLocale(requestedLocale, localeOptions, market) {
33
+ const fallbackLocale = market?.defaultLanguageTag ?? DEFAULT_CATALOG_LOCALE;
34
+ return requestedLocale && localeOptions.includes(requestedLocale)
35
+ ? requestedLocale
36
+ : fallbackLocale;
37
+ }
38
+ export function resolveCatalogScope(search, localeOptions, market) {
39
+ return {
40
+ locale: resolveCatalogSelectedLocale(search.locale, localeOptions, market),
41
+ market: search.market ?? market?.id,
42
+ };
43
+ }
15
44
  /**
16
45
  * The indexed catalog browse grid bound to its data wiring (markets, locales,
17
46
  * suppliers, product tag mutations, slot availability) — the packaged admin
@@ -28,28 +57,21 @@ export function CatalogVerticalHost({ vertical, search, onSearchChange, embedded
28
57
  const catalogMessages = useCatalogUiMessagesOrDefault().catalogPage;
29
58
  const suppliersQuery = useSuppliers({ limit: 100 });
30
59
  const marketsQuery = useMarkets({ status: "active", limit: 100 });
60
+ const markets = marketsQuery.data?.data ?? [];
31
61
  const selectedMarketId = search.market;
32
- const selectedMarket = (marketsQuery.data?.data ?? []).find((market) => market.id === selectedMarketId);
62
+ const defaultMarket = resolveCatalogDefaultMarket(markets, selectedMarketId);
63
+ const selectedMarket = selectedMarketId ? defaultMarket : undefined;
64
+ const localeMarket = selectedMarket ?? defaultMarket;
33
65
  const localesQuery = useMarketLocales({
34
- marketId: selectedMarketId,
66
+ marketId: localeMarket?.id,
35
67
  active: true,
36
68
  limit: 100,
37
- enabled: Boolean(selectedMarketId),
69
+ enabled: Boolean(localeMarket?.id),
38
70
  });
39
- const localeOptions = useMemo(() => {
40
- const tags = new Set();
41
- if (selectedMarket) {
42
- tags.add(selectedMarket.defaultLanguageTag);
43
- for (const locale of localesQuery.data?.data ?? [])
44
- tags.add(locale.languageTag);
45
- }
46
- else {
47
- tags.add(DEFAULT_CATALOG_LOCALE);
48
- }
49
- return Array.from(tags).sort((left, right) => left.localeCompare(right));
50
- }, [localesQuery.data, selectedMarket]);
51
- const fallbackLocale = selectedMarket?.defaultLanguageTag ?? DEFAULT_CATALOG_LOCALE;
52
- const selectedLocale = search.locale && localeOptions.includes(search.locale) ? search.locale : fallbackLocale;
71
+ const localeOptions = useMemo(() => resolveCatalogLocaleOptions(localeMarket, localesQuery.data?.data ?? []), [localesQuery.data, localeMarket]);
72
+ const catalogScope = resolveCatalogScope(search, localeOptions, localeMarket);
73
+ const selectedLocale = catalogScope.locale;
74
+ const selectedMarketScope = catalogScope.market;
53
75
  const supplierMap = useMemo(() => {
54
76
  const m = new Map();
55
77
  for (const s of suppliersQuery.data?.data ?? [])
@@ -71,9 +93,9 @@ export function CatalogVerticalHost({ vertical, search, onSearchChange, embedded
71
93
  },
72
94
  formatSupplier: (id) => supplierMap.get(String(id)) ?? String(id),
73
95
  locale: selectedLocale,
74
- market: selectedMarketId,
96
+ market: selectedMarketScope,
75
97
  loadSlotAvailability: (productId) => loadProductSlotAvailability(baseUrl, fetcher, productId),
76
- }), [baseUrl, fetcher, supplierMap, selectedLocale, selectedMarketId]);
98
+ }), [baseUrl, fetcher, supplierMap, selectedLocale, selectedMarketScope]);
77
99
  // Merge the always-on locked facets/ranges with the user's URL-driven filters.
78
100
  // Memoized so locked surfaces hand a STABLE `filters` object to the tab panel:
79
101
  // a fresh object every render reads as "selections changed" and resets back to
@@ -86,13 +108,14 @@ export function CatalogVerticalHost({ vertical, search, onSearchChange, embedded
86
108
  ? {
87
109
  ...search,
88
110
  locale: selectedLocale,
111
+ market: selectedMarketScope,
89
112
  filters: {
90
113
  ...search.filters,
91
114
  facets: { ...(search.filters?.facets ?? {}), ...(lockedFacets ?? {}) },
92
115
  ranges: { ...(search.filters?.ranges ?? {}), ...(lockedRanges ?? {}) },
93
116
  },
94
117
  }
95
- : { ...search, locale: selectedLocale }, [search, selectedLocale, lockedFacetsKey, lockedRangesKey]);
118
+ : { ...search, locale: selectedLocale, market: selectedMarketScope }, [search, selectedLocale, selectedMarketScope, lockedFacetsKey, lockedRangesKey]);
96
119
  return (_jsx(CatalogUiPage, { vertical: vertical, search: effectiveSearch, formatSupplier: formatSupplier, hideSearchInput: embedded, className: embedded ? "px-0 py-0 lg:px-0" : undefined, title:
97
120
  // `false` (not `undefined`) so catalog-ui's `title ?? default` does NOT
98
121
  // fall back to its generic "Catalog" header — the embedding surface
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/catalog-react",
3
- "version": "0.120.0",
3
+ "version": "0.120.2",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -78,9 +78,9 @@
78
78
  "zod": "^4.0.0",
79
79
  "@voyant-travel/admin": "^0.111.4",
80
80
  "@voyant-travel/commerce-react": "^0.4.0",
81
+ "@voyant-travel/ui": "^0.106.2",
81
82
  "@voyant-travel/inventory-react": "^0.4.0",
82
- "@voyant-travel/distribution-react": "^0.112.0",
83
- "@voyant-travel/ui": "^0.106.2"
83
+ "@voyant-travel/distribution-react": "^0.112.0"
84
84
  },
85
85
  "peerDependenciesMeta": {
86
86
  "@tanstack/react-table": {
@@ -122,11 +122,11 @@
122
122
  "typescript": "^6.0.2",
123
123
  "vitest": "^4.1.2",
124
124
  "zod": "^4.3.6",
125
- "@voyant-travel/admin": "^0.111.4",
126
125
  "@voyant-travel/i18n": "^0.106.1",
127
- "@voyant-travel/commerce-react": "^0.4.0",
126
+ "@voyant-travel/admin": "^0.111.4",
128
127
  "@voyant-travel/inventory-react": "^0.4.0",
129
128
  "@voyant-travel/react": "^0.104.1",
129
+ "@voyant-travel/commerce-react": "^0.4.0",
130
130
  "@voyant-travel/distribution-react": "^0.112.0",
131
131
  "@voyant-travel/ui": "^0.106.2",
132
132
  "@voyant-travel/voyant-typescript-config": "^0.1.0"