@propeller-commerce/propeller-v2-react-ui 0.20.1 → 0.22.0
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.
- package/CHANGELOG.md +101 -0
- package/dist/index.cjs +108 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +592 -525
- package/dist/index.d.ts +592 -525
- package/dist/index.js +110 -55
- package/dist/index.js.map +1 -1
- package/dist/pure.cjs +6 -14
- package/dist/pure.cjs.map +1 -1
- package/dist/pure.d.cts +12 -0
- package/dist/pure.d.ts +12 -0
- package/dist/pure.js +7 -15
- package/dist/pure.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { getLabel, getLocalizedValue, formatPrice, localeForLanguage, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl,
|
|
2
|
+
import { getLabel, getLocalizedValue, formatPrice, localeForLanguage, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl, createServices, isCheckoutAllowed, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, buildInventoryFilter, findPurchaserPac, isOverAuthorizationLimit, MIN_STOCK_THRESHOLD, getNettedBonusItems, getLanguageString, collectAttributeValues, getCountryName, resolveLanguageEntry, getLanguageUri } from '@propeller-commerce/propeller-v2-core-ui';
|
|
3
3
|
export * from '@propeller-commerce/propeller-v2-core-ui';
|
|
4
4
|
import * as React6 from 'react';
|
|
5
|
-
import { createContext, useState, useRef, useCallback, useMemo, useContext
|
|
5
|
+
import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext } from 'react';
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { ProductStatus, ProductSortField, SortOrder, CrossupsellType, CartStatus, CartAddressType, Gender, YesNo, AddressType, MagicTokenService, PaymentStatuses, OrderSearchFields, OrderItemClass, ProductSearchableField, machineService, PurchaseRole, AttributeType, OrderSortField, OrderType, BundleCondition, OrderDiscountType } from '@propeller-commerce/propeller-sdk-v2';
|
|
8
8
|
import { clsx } from 'clsx';
|
|
@@ -747,10 +747,29 @@ function useCart(options) {
|
|
|
747
747
|
const [loading, setLoading] = useState(false);
|
|
748
748
|
const [error, setError] = useState(null);
|
|
749
749
|
const notesTimers = useRef({});
|
|
750
|
-
|
|
751
|
-
(
|
|
752
|
-
|
|
753
|
-
|
|
750
|
+
useEffect(() => {
|
|
751
|
+
if (!graphqlClient || !cartId || cart) return;
|
|
752
|
+
let cancelled = false;
|
|
753
|
+
(async () => {
|
|
754
|
+
try {
|
|
755
|
+
const fetched = await createServices(graphqlClient).cart.getCart({
|
|
756
|
+
cartId,
|
|
757
|
+
imageSearchFilters: imageSearchFilters(),
|
|
758
|
+
imageVariantFilters: imageVariantFilters(),
|
|
759
|
+
language
|
|
760
|
+
});
|
|
761
|
+
if (!cancelled && fetched) setCart(fetched);
|
|
762
|
+
} catch {
|
|
763
|
+
}
|
|
764
|
+
})();
|
|
765
|
+
return () => {
|
|
766
|
+
cancelled = true;
|
|
767
|
+
};
|
|
768
|
+
}, [graphqlClient, cartId, cart, language, imageSearchFilters, imageVariantFilters]);
|
|
769
|
+
const checkoutAllowed = useMemo(() => {
|
|
770
|
+
if (cartId && !cart) return false;
|
|
771
|
+
return isCheckoutAllowed(user, resolvedCompanyId, cart);
|
|
772
|
+
}, [user, resolvedCompanyId, cart, cartId]);
|
|
754
773
|
function getMinQuantity(product) {
|
|
755
774
|
const min = product?.minimumQuantity;
|
|
756
775
|
return min && min > 0 ? min : 1;
|
|
@@ -1571,7 +1590,8 @@ var INFRA_KEYS = [
|
|
|
1571
1590
|
"includeTax",
|
|
1572
1591
|
"currency",
|
|
1573
1592
|
"configuration",
|
|
1574
|
-
"portalMode"
|
|
1593
|
+
"portalMode",
|
|
1594
|
+
"isAuthenticated"
|
|
1575
1595
|
];
|
|
1576
1596
|
function useInfraProps(props) {
|
|
1577
1597
|
const ctx = usePropellerContext();
|
|
@@ -2248,10 +2268,11 @@ function useProductSearch(options) {
|
|
|
2248
2268
|
const isLoading = !isControlled && internalLoading;
|
|
2249
2269
|
function filterByLanguage(products, lang) {
|
|
2250
2270
|
if (!lang) return products;
|
|
2271
|
+
const target = lang.toUpperCase();
|
|
2251
2272
|
return products.filter((p) => {
|
|
2252
2273
|
const names = p.names || p.names || [];
|
|
2253
2274
|
if (!names || names.length === 0) return true;
|
|
2254
|
-
return names.some((n) => n.language ===
|
|
2275
|
+
return names.some((n) => (n.language || "").toUpperCase() === target);
|
|
2255
2276
|
});
|
|
2256
2277
|
}
|
|
2257
2278
|
const fetchProducts = useCallback(async () => {
|
|
@@ -2756,7 +2777,8 @@ function useSpareParts(options) {
|
|
|
2756
2777
|
const [childMachines, setChildMachines] = useState([]);
|
|
2757
2778
|
const [itemsFound, setItemsFound] = useState(0);
|
|
2758
2779
|
const [internalLoading, setInternalLoading] = useState(false);
|
|
2759
|
-
const [
|
|
2780
|
+
const [internalPage, setInternalPage] = useState(1);
|
|
2781
|
+
const currentPage = options.page ?? internalPage;
|
|
2760
2782
|
const [totalPages, setTotalPages] = useState(1);
|
|
2761
2783
|
const fetchIdRef = useRef(0);
|
|
2762
2784
|
const displayParts = useMemo(
|
|
@@ -2905,7 +2927,7 @@ function useSpareParts(options) {
|
|
|
2905
2927
|
userKey
|
|
2906
2928
|
]);
|
|
2907
2929
|
const goToPage = useCallback((page) => {
|
|
2908
|
-
|
|
2930
|
+
setInternalPage((prev) => {
|
|
2909
2931
|
if (page >= 1 && (totalPages <= 1 || page <= totalPages)) return page;
|
|
2910
2932
|
return prev;
|
|
2911
2933
|
});
|
|
@@ -2924,9 +2946,9 @@ function useSpareParts(options) {
|
|
|
2924
2946
|
var inflightFetches4 = /* @__PURE__ */ new Set();
|
|
2925
2947
|
var ROOT_MACHINE_FIELDS = `
|
|
2926
2948
|
id
|
|
2927
|
-
name
|
|
2928
|
-
description
|
|
2929
|
-
slug
|
|
2949
|
+
name { language value }
|
|
2950
|
+
description { language value }
|
|
2951
|
+
slug { language value }
|
|
2930
2952
|
media {
|
|
2931
2953
|
images {
|
|
2932
2954
|
items { imageVariants(input: $imageVariantFilters) { url } }
|
|
@@ -4207,7 +4229,7 @@ function AccountIconAndMenu(rawProps) {
|
|
|
4207
4229
|
onClick: (event) => handleIconClick(),
|
|
4208
4230
|
"aria-label": getLabel(props.labels, "accountLabel", "Account"),
|
|
4209
4231
|
"data-open": menuOpen ? "true" : "false",
|
|
4210
|
-
className: cn(`propeller-account-menu__trigger inline-flex items-center gap-2 px-3 py-2 rounded-control text-sm font-medium transition-colors text-
|
|
4232
|
+
className: cn(`propeller-account-menu__trigger inline-flex items-center gap-2 px-3 py-2 rounded-control text-sm font-medium transition-colors text-inherit${props.iconClassName ? " " + props.iconClassName : ""}`),
|
|
4211
4233
|
children: [
|
|
4212
4234
|
/* @__PURE__ */ jsx(
|
|
4213
4235
|
"svg",
|
|
@@ -7619,7 +7641,8 @@ function CartIconAndSidebar(rawProps) {
|
|
|
7619
7641
|
] });
|
|
7620
7642
|
}
|
|
7621
7643
|
var CartIconAndSidebar_default = CartIconAndSidebar;
|
|
7622
|
-
function CartOverview(
|
|
7644
|
+
function CartOverview(rawProps) {
|
|
7645
|
+
const props = useInfraProps(rawProps);
|
|
7623
7646
|
const [reference, setReference] = useState("");
|
|
7624
7647
|
const [notes, setNotes] = useState("");
|
|
7625
7648
|
const [termsAccepted, setTermsAccepted] = useState(false);
|
|
@@ -7629,6 +7652,7 @@ function CartOverview(props) {
|
|
|
7629
7652
|
const showReference = props.showReference !== false;
|
|
7630
7653
|
const showTermsAndConditions = props.showTermsAndConditions !== false;
|
|
7631
7654
|
const showPurchaseButton = props.showPurchaseButton !== false;
|
|
7655
|
+
const overLimit = isOverAuthorizationLimit(props.user, props.companyId, props.cart);
|
|
7632
7656
|
const invoiceAddress = props.cart?.invoiceAddress;
|
|
7633
7657
|
const deliveryAddress = props.cart?.deliveryAddress;
|
|
7634
7658
|
const getCountryName$1 = (code) => getCountryName(code, props.countries);
|
|
@@ -7768,7 +7792,12 @@ function CartOverview(props) {
|
|
|
7768
7792
|
] });
|
|
7769
7793
|
})() })
|
|
7770
7794
|
] }) : null,
|
|
7771
|
-
showPurchaseButton ? /* @__PURE__ */
|
|
7795
|
+
showPurchaseButton && overLimit ? /* @__PURE__ */ jsx("p", { className: "propeller-cart-overview__authorization-required text-sm text-muted-foreground mt-2", children: getLabel(
|
|
7796
|
+
props.labels,
|
|
7797
|
+
"authorizationRequired",
|
|
7798
|
+
"This order exceeds your authorization limit. Request authorization from the cart to continue."
|
|
7799
|
+
) }) : null,
|
|
7800
|
+
showPurchaseButton && !overLimit ? /* @__PURE__ */ jsxs(
|
|
7772
7801
|
"button",
|
|
7773
7802
|
{
|
|
7774
7803
|
type: "button",
|
|
@@ -8143,6 +8172,7 @@ var RESOLVE_SPEC = {
|
|
|
8143
8172
|
currency: { infra: "currency", default: "\u20AC" },
|
|
8144
8173
|
user: { infra: "user", default: null },
|
|
8145
8174
|
portalMode: { infra: "portalMode" },
|
|
8175
|
+
isAuthenticated: { infra: "isAuthenticated" },
|
|
8146
8176
|
columns: { grid: "columns", default: 3 },
|
|
8147
8177
|
showPrice: { grid: "showPrice" },
|
|
8148
8178
|
showStock: { grid: "showStock" },
|
|
@@ -8186,7 +8216,7 @@ function ClusterCard(rawProps) {
|
|
|
8186
8216
|
const textLabelValues = resolveAttributeValues(cluster, props.textLabels).map((value) => ({
|
|
8187
8217
|
value
|
|
8188
8218
|
}));
|
|
8189
|
-
const contentHidden = isContentHidden(props.portalMode, props.user);
|
|
8219
|
+
const contentHidden = isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
8190
8220
|
const defaultProductInventory = contentHidden ? void 0 : cluster?.defaultProduct?.inventory;
|
|
8191
8221
|
const useTax = props.includeTax !== void 0 ? !!props.includeTax : false;
|
|
8192
8222
|
const priceObj = contentHidden ? void 0 : cluster?.defaultProduct?.price;
|
|
@@ -8529,6 +8559,7 @@ function getMachineImageUrl(machine) {
|
|
|
8529
8559
|
}
|
|
8530
8560
|
function MachineCard(props) {
|
|
8531
8561
|
const { machine, href, language } = props;
|
|
8562
|
+
const Wrapper = href ? "a" : "div";
|
|
8532
8563
|
const showImage = props.showImage ?? true;
|
|
8533
8564
|
const showDescription = props.showDescription ?? false;
|
|
8534
8565
|
const name = getLocalizedValue(machine.name, language);
|
|
@@ -8540,10 +8571,9 @@ function MachineCard(props) {
|
|
|
8540
8571
|
{
|
|
8541
8572
|
className: cn(`propeller-machine-card group relative flex h-full flex-col overflow-hidden rounded-lg border border-border bg-background ${props.className ?? ""}`),
|
|
8542
8573
|
children: /* @__PURE__ */ jsxs(
|
|
8543
|
-
|
|
8574
|
+
Wrapper,
|
|
8544
8575
|
{
|
|
8545
|
-
href,
|
|
8546
|
-
onClick: handleClick,
|
|
8576
|
+
...href ? { href, onClick: handleClick } : {},
|
|
8547
8577
|
className: "flex h-full flex-col focus:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
8548
8578
|
children: [
|
|
8549
8579
|
showImage && /* @__PURE__ */ jsx("div", { className: "propeller-machine-card__image aspect-square w-full overflow-hidden bg-background-subtle", children: imageUrl ? /* @__PURE__ */ jsx(
|
|
@@ -8613,7 +8643,7 @@ function LoginToOrderButton(props) {
|
|
|
8613
8643
|
var LoginToOrderButton_default = LoginToOrderButton;
|
|
8614
8644
|
function ProductPriceDisplay(props) {
|
|
8615
8645
|
function isHidden2() {
|
|
8616
|
-
return isContentHidden(props.portalMode, props.user);
|
|
8646
|
+
return isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
8617
8647
|
}
|
|
8618
8648
|
function formatPrice17(value) {
|
|
8619
8649
|
if (value === null || value === void 0) return "";
|
|
@@ -8705,6 +8735,7 @@ var RESOLVE_SPEC2 = {
|
|
|
8705
8735
|
language: { infra: "language", default: "NL" },
|
|
8706
8736
|
includeTax: { infra: "includeTax" },
|
|
8707
8737
|
portalMode: { infra: "portalMode" },
|
|
8738
|
+
isAuthenticated: { infra: "isAuthenticated" },
|
|
8708
8739
|
configuration: { infra: "configuration" },
|
|
8709
8740
|
// Same entry ClusterCard has always had. Without it a shop priced in
|
|
8710
8741
|
// anything but euros had no route to the cards at all: the grid resolved the
|
|
@@ -8763,7 +8794,7 @@ function ProductCardRoot(rawProps) {
|
|
|
8763
8794
|
const language = props.language || "NL";
|
|
8764
8795
|
const product = props.product;
|
|
8765
8796
|
const isRow = props.columns === 1;
|
|
8766
|
-
const contentHidden = isContentHidden(props.portalMode, props.user);
|
|
8797
|
+
const contentHidden = isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
8767
8798
|
const showStock = !!props.showStock && !contentHidden;
|
|
8768
8799
|
const showCta = props.allowAddToCart !== false || contentHidden;
|
|
8769
8800
|
const name = getProductName(product, language);
|
|
@@ -9060,6 +9091,7 @@ function ProductCardPrice(props) {
|
|
|
9060
9091
|
currency: resolved.currency,
|
|
9061
9092
|
language: resolved.language,
|
|
9062
9093
|
portalMode: resolved.portalMode,
|
|
9094
|
+
isAuthenticated: resolved.isAuthenticated,
|
|
9063
9095
|
user: resolved.user,
|
|
9064
9096
|
showLoginPrompt: false
|
|
9065
9097
|
}
|
|
@@ -9067,7 +9099,7 @@ function ProductCardPrice(props) {
|
|
|
9067
9099
|
}
|
|
9068
9100
|
function ProductCardAddToCart(props) {
|
|
9069
9101
|
const { product, resolved } = useProductCard();
|
|
9070
|
-
if (isContentHidden(resolved.portalMode, resolved.user)) {
|
|
9102
|
+
if (isContentHidden(resolved.portalMode, resolved.user, resolved.isAuthenticated)) {
|
|
9071
9103
|
return /* @__PURE__ */ jsx(
|
|
9072
9104
|
LoginToOrderButton_default,
|
|
9073
9105
|
{
|
|
@@ -9088,9 +9120,13 @@ function ProductCardAddToCart(props) {
|
|
|
9088
9120
|
allowIncrDecr: resolved.allowIncrDecr,
|
|
9089
9121
|
showModal: resolved.showModal,
|
|
9090
9122
|
enableStockValidation: resolved.enableStockValidation,
|
|
9123
|
+
onAddToCart: resolved.onAddToCart,
|
|
9091
9124
|
afterAddToCart: resolved.afterAddToCart,
|
|
9092
9125
|
onProceedToCheckout: resolved.onProceedToCheckout,
|
|
9093
9126
|
onRequestQuoteClick: resolved.onRequestQuoteClick,
|
|
9127
|
+
createCart: resolved.createCart,
|
|
9128
|
+
onCartCreated: resolved.onCartCreated,
|
|
9129
|
+
includeTax: resolved.includeTax,
|
|
9094
9130
|
labels: resolved.addToCartLabels
|
|
9095
9131
|
}
|
|
9096
9132
|
);
|
|
@@ -9213,7 +9249,7 @@ function ProductGrid(rawProps) {
|
|
|
9213
9249
|
}
|
|
9214
9250
|
function showAddToCart() {
|
|
9215
9251
|
const allow = props.allowAddToCart !== false;
|
|
9216
|
-
return !isContentHidden(props.portalMode, props.user) && allow;
|
|
9252
|
+
return !isContentHidden(props.portalMode, props.user, props.isAuthenticated) && allow;
|
|
9217
9253
|
}
|
|
9218
9254
|
function getSkeletonItems() {
|
|
9219
9255
|
const cols = props.columns || 3;
|
|
@@ -9491,7 +9527,7 @@ function GridFilters(rawProps) {
|
|
|
9491
9527
|
}
|
|
9492
9528
|
function showAvailability() {
|
|
9493
9529
|
if (!props.showAvailabilityFilter) return false;
|
|
9494
|
-
return !isContentHidden(props.portalMode, props.user);
|
|
9530
|
+
return !isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
9495
9531
|
}
|
|
9496
9532
|
function getFilterName(filter) {
|
|
9497
9533
|
return filter?.attributeDescription?.name || "";
|
|
@@ -10046,7 +10082,7 @@ function GridToolbar(rawProps) {
|
|
|
10046
10082
|
return badges;
|
|
10047
10083
|
}
|
|
10048
10084
|
function isPriceSortDisabled() {
|
|
10049
|
-
return isContentHidden(props.portalMode, props.user);
|
|
10085
|
+
return isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
10050
10086
|
}
|
|
10051
10087
|
function getAvailabilityLabel() {
|
|
10052
10088
|
const qty = props.minStock;
|
|
@@ -10448,7 +10484,7 @@ function MachineGrid(rawProps) {
|
|
|
10448
10484
|
// node query threads through useSpareParts.
|
|
10449
10485
|
imageVariantFilters: configuration?.imageVariantFiltersMedium
|
|
10450
10486
|
});
|
|
10451
|
-
const { displayParts, childMachines, isLoading: partsLoading, currentPage, totalPages
|
|
10487
|
+
const { displayParts, childMachines, isLoading: partsLoading, currentPage, totalPages } = useSpareParts({
|
|
10452
10488
|
graphqlClient: props.graphqlClient,
|
|
10453
10489
|
// Idle at the root (no slug).
|
|
10454
10490
|
slug: isRoot ? void 0 : currentSlug,
|
|
@@ -10464,6 +10500,10 @@ function MachineGrid(rawProps) {
|
|
|
10464
10500
|
sortField,
|
|
10465
10501
|
sortOrder,
|
|
10466
10502
|
pageSize: offset,
|
|
10503
|
+
// The hook takes the controlled page directly now. It used to own its own
|
|
10504
|
+
// counter, so the only way to drive it from URL state was the effect
|
|
10505
|
+
// below — undiscoverable unless you read this file (PWP-995b).
|
|
10506
|
+
page: listing.page,
|
|
10467
10507
|
configuration: rawProps.configuration ?? props.configuration,
|
|
10468
10508
|
onFiltersChange: setGridFilters,
|
|
10469
10509
|
onPriceBoundsChange: (min, max) => {
|
|
@@ -10473,9 +10513,6 @@ function MachineGrid(rawProps) {
|
|
|
10473
10513
|
onItemsFoundChange: setItemsFound,
|
|
10474
10514
|
onMachineChange: setMachine
|
|
10475
10515
|
});
|
|
10476
|
-
useEffect(() => {
|
|
10477
|
-
goToPage(listing.page);
|
|
10478
|
-
}, [listing.page, goToPage]);
|
|
10479
10516
|
const machineName = machine ? getLocalizedValue(machine.name, machineLanguage) : slugToLabel(currentSlug);
|
|
10480
10517
|
const partProducts = useMemo(
|
|
10481
10518
|
() => displayParts.map((p) => p.product).filter(Boolean),
|
|
@@ -10532,11 +10569,10 @@ function MachineGrid(rawProps) {
|
|
|
10532
10569
|
);
|
|
10533
10570
|
const childSlugHref = (child) => {
|
|
10534
10571
|
const slug = getLocalizedValue(child.slug, machineLanguage);
|
|
10535
|
-
|
|
10536
|
-
return `${currentPath}/${slug}`;
|
|
10572
|
+
return slug ? `${currentPath}/${slug}` : void 0;
|
|
10537
10573
|
};
|
|
10538
10574
|
if (isRoot) {
|
|
10539
|
-
const cards = rootMachines.map((m) => ({ machine: m, href: childSlugHref(m) }))
|
|
10575
|
+
const cards = rootMachines.map((m) => ({ machine: m, href: childSlugHref(m) }));
|
|
10540
10576
|
return /* @__PURE__ */ jsxs("div", { className: rawProps.className, children: [
|
|
10541
10577
|
/* @__PURE__ */ jsx("h1", { className: "propeller-grid-title mb-6 text-2xl font-semibold", children: rawProps.rootTitle ?? "Machines" }),
|
|
10542
10578
|
rootLoading ? /* @__PURE__ */ jsx("p", { className: "py-12 text-center text-foreground-subtle", children: getLabel(rawProps.machineCardLabels, "loading", "Loading\u2026") }) : cards.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-12 text-center text-foreground-subtle", children: getLabel(rawProps.machineCardLabels, "noMachines", "No machines found.") }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children: cards.map(({ machine: m, href }) => /* @__PURE__ */ jsx(
|
|
@@ -10568,7 +10604,6 @@ function MachineGrid(rawProps) {
|
|
|
10568
10604
|
/* @__PURE__ */ jsx("h1", { className: "propeller-grid-title mb-6 text-2xl font-semibold", children: machineName }),
|
|
10569
10605
|
childMachines.length > 0 && /* @__PURE__ */ jsx("div", { className: "propeller-machine-children mb-8 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children: childMachines.map((child) => {
|
|
10570
10606
|
const href = childSlugHref(child);
|
|
10571
|
-
if (!href) return null;
|
|
10572
10607
|
return /* @__PURE__ */ jsx(
|
|
10573
10608
|
MachineCard,
|
|
10574
10609
|
{
|
|
@@ -10646,6 +10681,12 @@ function MachineGrid(rawProps) {
|
|
|
10646
10681
|
columns: viewMode === "list" ? 1 : 3,
|
|
10647
10682
|
showAvailability: rawProps.showAvailability ?? false,
|
|
10648
10683
|
showStock: rawProps.showStock ?? true,
|
|
10684
|
+
productCardComponent: rawProps.productCardComponent,
|
|
10685
|
+
productCardLabels: rawProps.productCardLabels,
|
|
10686
|
+
addToCartLabels: rawProps.addToCartLabels,
|
|
10687
|
+
stockLabels: rawProps.stockLabels,
|
|
10688
|
+
priceLabels: rawProps.priceLabels,
|
|
10689
|
+
labels: rawProps.labels,
|
|
10649
10690
|
belowName: (product) => {
|
|
10650
10691
|
const qty = quantityBySku.get(product.sku);
|
|
10651
10692
|
if (!qty) return null;
|
|
@@ -10894,7 +10935,7 @@ function ClusterOptions(rawProps) {
|
|
|
10894
10935
|
const language = props.language;
|
|
10895
10936
|
const options = props.options || [];
|
|
10896
10937
|
const sel = selectedProductIds;
|
|
10897
|
-
const hidePrices = isContentHidden(props.portalMode, props.user);
|
|
10938
|
+
const hidePrices = isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
10898
10939
|
return options.filter((option) => option.hidden !== YesNo.Y).map((option) => {
|
|
10899
10940
|
const idStr = option.id.toString();
|
|
10900
10941
|
const selectedProductId = sel[idStr] || "";
|
|
@@ -11078,7 +11119,11 @@ function CompanySwitcher(props) {
|
|
|
11078
11119
|
type: "button",
|
|
11079
11120
|
"aria-haspopup": "listbox",
|
|
11080
11121
|
"aria-label": getLabel(props.labels, "switchCompanyAriaLabel", "Switch company"),
|
|
11081
|
-
className:
|
|
11122
|
+
className: cn(
|
|
11123
|
+
// `text-inherit`: this sits in the host's header, which may be dark or
|
|
11124
|
+
// light. See the note on AccountIconAndMenu's trigger.
|
|
11125
|
+
`propeller-company-switcher__trigger flex items-center gap-2 rounded-md px-3 py-1.5 text-sm font-medium transition-colors text-inherit${props.triggerClassName ? " " + props.triggerClassName : ""}`
|
|
11126
|
+
),
|
|
11082
11127
|
onClick: (event) => toggleDropdown(),
|
|
11083
11128
|
"aria-expanded": isOpen,
|
|
11084
11129
|
children: [
|
|
@@ -15053,7 +15098,7 @@ function PriceToggle(props) {
|
|
|
15053
15098
|
var PriceToggle_default = PriceToggle;
|
|
15054
15099
|
function ProductBulkPrices(props) {
|
|
15055
15100
|
const includeTax = !!props.includeTax;
|
|
15056
|
-
const isHidden2 = isContentHidden(props.portalMode, props.user);
|
|
15101
|
+
const isHidden2 = isContentHidden(props.portalMode, props.user, props.isAuthenticated);
|
|
15057
15102
|
function getTierQuantity(tier) {
|
|
15058
15103
|
const discount = tier.discount;
|
|
15059
15104
|
return discount?.quantityFrom ?? tier.quantity ?? null;
|
|
@@ -15600,14 +15645,10 @@ function ProductDownloads(props) {
|
|
|
15600
15645
|
const hasItems = items.length > 0;
|
|
15601
15646
|
const lang = props.language || "NL";
|
|
15602
15647
|
function getDocumentUrl(doc) {
|
|
15603
|
-
|
|
15604
|
-
const match = docs.find((d) => d.language === lang);
|
|
15605
|
-
return match?.originalUrl || docs?.[0]?.originalUrl || "";
|
|
15648
|
+
return resolveLanguageEntry(doc.documents, lang)?.originalUrl || "";
|
|
15606
15649
|
}
|
|
15607
15650
|
function getDocumentName(doc) {
|
|
15608
|
-
|
|
15609
|
-
const match = alts.find((a) => a.language === lang);
|
|
15610
|
-
return match?.value || alts?.[0]?.value || "Download";
|
|
15651
|
+
return getLanguageString(doc.alt, lang, "Download");
|
|
15611
15652
|
}
|
|
15612
15653
|
return /* @__PURE__ */ jsxs("div", { className: cn(`propeller-product-downloads ${props.className || ""}`), children: [
|
|
15613
15654
|
hasItems ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-downloads__title text-base font-semibold text-foreground mb-3", children: getLabel(props.labels, "title", "Downloads") }) : null,
|
|
@@ -15813,12 +15854,14 @@ function ProductGallery(props) {
|
|
|
15813
15854
|
var ProductGallery_default = ProductGallery;
|
|
15814
15855
|
function pickImageUrl(mediaItems, target) {
|
|
15815
15856
|
if (!mediaItems || mediaItems.length === 0) return null;
|
|
15857
|
+
const targetUpper = (target || "").toUpperCase();
|
|
15858
|
+
const langMatches = (value) => (value || "").toUpperCase() === targetUpper;
|
|
15816
15859
|
for (const m of mediaItems) {
|
|
15817
|
-
const match = m.imageVariants?.find((v) => v.language
|
|
15860
|
+
const match = m.imageVariants?.find((v) => langMatches(v.language) && v.url);
|
|
15818
15861
|
if (match?.url) return match.url;
|
|
15819
15862
|
}
|
|
15820
15863
|
for (const m of mediaItems) {
|
|
15821
|
-
const match = m.images?.find((i) => i.language
|
|
15864
|
+
const match = m.images?.find((i) => langMatches(i.language) && i.originalUrl);
|
|
15822
15865
|
if (match?.originalUrl) return match.originalUrl;
|
|
15823
15866
|
}
|
|
15824
15867
|
for (const m of mediaItems) {
|
|
@@ -16146,6 +16189,7 @@ function ProductInfoPrice(props = {}) {
|
|
|
16146
16189
|
currency: derived.currency,
|
|
16147
16190
|
taxZone: derived.taxZone,
|
|
16148
16191
|
portalMode: derived.portalMode,
|
|
16192
|
+
isAuthenticated: resolved.isAuthenticated,
|
|
16149
16193
|
user: derived.user,
|
|
16150
16194
|
labels: derived.labels,
|
|
16151
16195
|
className: props.className
|
|
@@ -16155,7 +16199,7 @@ function ProductInfoPrice(props = {}) {
|
|
|
16155
16199
|
function ProductInfoStock(props = {}) {
|
|
16156
16200
|
const { product, resolved, derived } = useProductInfoContext();
|
|
16157
16201
|
if (!product.inventory) return null;
|
|
16158
|
-
if (isContentHidden(derived.portalMode, resolved.user)) return null;
|
|
16202
|
+
if (isContentHidden(derived.portalMode, resolved.user, resolved.isAuthenticated)) return null;
|
|
16159
16203
|
const Injected = resolved.stockComponent;
|
|
16160
16204
|
if (Injected) {
|
|
16161
16205
|
return /* @__PURE__ */ jsx(
|
|
@@ -16182,7 +16226,7 @@ function ProductInfoStock(props = {}) {
|
|
|
16182
16226
|
}
|
|
16183
16227
|
function ProductInfoAddToCart(props = {}) {
|
|
16184
16228
|
const { product, resolved, derived } = useProductInfoContext();
|
|
16185
|
-
if (isContentHidden(derived.portalMode, resolved.user)) {
|
|
16229
|
+
if (isContentHidden(derived.portalMode, resolved.user, resolved.isAuthenticated)) {
|
|
16186
16230
|
return /* @__PURE__ */ jsx(
|
|
16187
16231
|
LoginToOrderButton_default,
|
|
16188
16232
|
{
|
|
@@ -16194,7 +16238,18 @@ function ProductInfoAddToCart(props = {}) {
|
|
|
16194
16238
|
}
|
|
16195
16239
|
const Injected = resolved.addToCartComponent;
|
|
16196
16240
|
if (Injected) {
|
|
16197
|
-
return /* @__PURE__ */ jsx(
|
|
16241
|
+
return /* @__PURE__ */ jsx(
|
|
16242
|
+
Injected,
|
|
16243
|
+
{
|
|
16244
|
+
product,
|
|
16245
|
+
cartId: resolved.cartId,
|
|
16246
|
+
createCart: resolved.createCart,
|
|
16247
|
+
onCartCreated: resolved.onCartCreated,
|
|
16248
|
+
includeTax: derived.useTax,
|
|
16249
|
+
labels: derived.labels,
|
|
16250
|
+
className: props.className
|
|
16251
|
+
}
|
|
16252
|
+
);
|
|
16198
16253
|
}
|
|
16199
16254
|
return /* @__PURE__ */ jsx(
|
|
16200
16255
|
AddToCart_default,
|
|
@@ -16203,6 +16258,9 @@ function ProductInfoAddToCart(props = {}) {
|
|
|
16203
16258
|
user: derived.user,
|
|
16204
16259
|
currency: derived.currency,
|
|
16205
16260
|
product,
|
|
16261
|
+
cartId: resolved.cartId,
|
|
16262
|
+
createCart: resolved.createCart,
|
|
16263
|
+
onCartCreated: resolved.onCartCreated,
|
|
16206
16264
|
configuration: resolved.configuration,
|
|
16207
16265
|
companyId: resolved.companyId,
|
|
16208
16266
|
includeTax: derived.useTax,
|
|
@@ -16256,6 +16314,7 @@ function ProductInfoBulkPrices(props = {}) {
|
|
|
16256
16314
|
bulkPrices: product.bulkPrices,
|
|
16257
16315
|
includeTax: derived.useTax,
|
|
16258
16316
|
portalMode: derived.portalMode,
|
|
16317
|
+
isAuthenticated: resolved.isAuthenticated,
|
|
16259
16318
|
user: derived.user,
|
|
16260
16319
|
taxZone: derived.taxZone,
|
|
16261
16320
|
currency: derived.currency,
|
|
@@ -16418,7 +16477,7 @@ function ProductSlider(rawProps) {
|
|
|
16418
16477
|
}
|
|
16419
16478
|
function showAddToCart() {
|
|
16420
16479
|
const allow = props.allowAddToCart !== false;
|
|
16421
|
-
return !isContentHidden(props.portalMode, props.user) && allow;
|
|
16480
|
+
return !isContentHidden(props.portalMode, props.user, props.isAuthenticated) && allow;
|
|
16422
16481
|
}
|
|
16423
16482
|
function isCluster(item) {
|
|
16424
16483
|
return "clusterId" in item && !("productId" in item);
|
|
@@ -16722,14 +16781,10 @@ function ProductVideos(props) {
|
|
|
16722
16781
|
const hasItems = items.length > 0;
|
|
16723
16782
|
const lang = props.language || "NL";
|
|
16724
16783
|
function getVideoUri(video) {
|
|
16725
|
-
|
|
16726
|
-
const match = vids.find((v) => v.language === lang);
|
|
16727
|
-
return match?.uri || vids?.[0]?.uri || "";
|
|
16784
|
+
return getLanguageUri(video.videos, lang, "");
|
|
16728
16785
|
}
|
|
16729
16786
|
function getVideoTitle(video) {
|
|
16730
|
-
|
|
16731
|
-
const match = alts.find((a) => a.language === lang);
|
|
16732
|
-
return match?.value || alts?.[0]?.value || "Video";
|
|
16787
|
+
return getLanguageString(video.alt, lang, "Video");
|
|
16733
16788
|
}
|
|
16734
16789
|
function isEmbeddable(uri) {
|
|
16735
16790
|
return uri.includes("youtube.com") || uri.includes("youtu.be") || uri.includes("vimeo.com");
|