@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,
|
|
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
|
|
62
|
+
const defaultMarket = resolveCatalogDefaultMarket(markets, selectedMarketId);
|
|
63
|
+
const selectedMarket = selectedMarketId ? defaultMarket : undefined;
|
|
64
|
+
const localeMarket = selectedMarket ?? defaultMarket;
|
|
33
65
|
const localesQuery = useMarketLocales({
|
|
34
|
-
marketId:
|
|
66
|
+
marketId: localeMarket?.id,
|
|
35
67
|
active: true,
|
|
36
68
|
limit: 100,
|
|
37
|
-
enabled: Boolean(
|
|
69
|
+
enabled: Boolean(localeMarket?.id),
|
|
38
70
|
});
|
|
39
|
-
const localeOptions = useMemo(() =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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:
|
|
96
|
+
market: selectedMarketScope,
|
|
75
97
|
loadSlotAvailability: (productId) => loadProductSlotAvailability(baseUrl, fetcher, productId),
|
|
76
|
-
}), [baseUrl, fetcher, supplierMap, selectedLocale,
|
|
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.
|
|
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/
|
|
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"
|