{"version":3,"file":"static/js/460f09e165042ce1f873.bundle.js","mappings":"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","sources":["webpack://bestseller.commerce.online/external var \"React\"?0d3b","webpack://bestseller.commerce.online/external var \"ReactDOM\"?853b","webpack://bestseller.commerce.online/./src/shared/functions/get-commercial-name.ts?6aba","webpack://bestseller.commerce.online/./src/shared/functions/is-valid-image.ts?b7db","webpack://bestseller.commerce.online/./src/shared/components/price.component.tsx?0789","webpack://bestseller.commerce.online/./src/components/common/Show/show.tsx?db40","webpack://bestseller.commerce.online/./src/shared/components/product.component.tsx?7636","webpack://bestseller.commerce.online/./src/shared/functions/get-affiliation.ts?82a6","webpack://bestseller.commerce.online/./lib/ext-product-collection/module-registration.js?6d96","webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.props.autogenerated.ts?ae75","webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.tsx?dacf","webpack://bestseller.commerce.online/./src/actions/get-price-for-product-search-result.ts?fd24","webpack://bestseller.commerce.online/./src/modules/ext-product-collection/ext-product-collection.view.tsx?2915"],"sourcesContent":["module.exports = React;","module.exports = ReactDOM;","/**\r\n * Centralised location for checkout generic data updates\r\n */\r\nimport { AttributeValue } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * Gets the CommercialName from a list of attributes - returns the product name if no commercial name attribute is present\r\n * @param attributes\r\n * @param productName\r\n * @param commercialStyleNameAttribute\r\n * @returns\r\n */\r\nexport const getCommercialName = (\r\n attributes: AttributeValue[] = [],\r\n productName: string = '',\r\n commercialStyleNameAttribute: string = 'CommercialStyleName'\r\n): string => {\r\n var styleName = attributes.find(x => x.Name === commercialStyleNameAttribute);\r\n var productBrand = productName?.split(' ')[0] ?? '';\r\n if (styleName?.TextValue) {\r\n return `${productBrand} ${styleName?.TextValue}`;\r\n }\r\n\r\n return productName;\r\n};\r\n","import { generateImageUrl, ICommerceApiSettings } from '@msdyn365-commerce/core';\r\n/**\r\n * Parses whether a URL is valid\r\n * @param url\r\n * @returns\r\n */\r\nexport const isValidImage = (url?: string): boolean => {\r\n if (url) {\r\n return url.startsWith('https') || url.startsWith('Products');\r\n } else {\r\n return false;\r\n }\r\n};\r\n\r\nexport async function validateUrlsAsync(\r\n urls: string[],\r\n apiSettings: ICommerceApiSettings,\r\n filterLegacy: boolean = false\r\n): Promise {\r\n var results: Promise[] = [];\r\n var isValid = false;\r\n for (const url of urls) {\r\n results.push(validateUrlAsync(url, apiSettings, filterLegacy));\r\n }\r\n await Promise.all(results).then(values => {\r\n //If any of the values are true, the image is valid\r\n isValid = values.some(value => value);\r\n });\r\n\r\n return isValid;\r\n}\r\n\r\nexport async function validateUrlAsync(url: string, apiSettings: ICommerceApiSettings, filterLegacy: boolean = false): Promise {\r\n //If we filter legacy images and the image is a legacy image, we know it is not valid\r\n if (filterLegacy && !isValidImage(url)) {\r\n return false;\r\n }\r\n\r\n const imageUrl = generateImageUrl(apiSettings, url);\r\n\r\n if (imageUrl === '') {\r\n return false;\r\n }\r\n\r\n return new Promise(resolve => {\r\n try {\r\n const http = new XMLHttpRequest();\r\n http.open('HEAD', imageUrl ?? '', true);\r\n\r\n http.addEventListener('load', () => {\r\n resolve(http.status === 200 || http.status === 201);\r\n });\r\n\r\n http.addEventListener('error', () => {\r\n resolve(false);\r\n });\r\n\r\n http.send();\r\n } catch {\r\n resolve(false);\r\n }\r\n });\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { IComponent, IComponentProps, msdyn365Commerce } from '@msdyn365-commerce/core';\r\nimport { ProductPrice, ProductType, SalesAgreementPriceLine, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { Button, format, ICollapseProps } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nconst defaultPrice: number = 0;\r\nconst freePrice: number = 0;\r\n\r\n/**\r\n * Interface for price component resources.\r\n * @param {string} priceRangeSeparator - The price range separator.\r\n */\r\nexport interface IPriceComponentResources {\r\n priceRangeSeparator?: string;\r\n salesAgreementPricePrompt?: string;\r\n salesAgreementExpirationDatePrompt?: string;\r\n salesAgreementCommittedQuantityPrompt?: string;\r\n salesAgreementRemainingQuantityPrompt?: string;\r\n memberPriceMessage?: string;\r\n saleMessage?: string;\r\n}\r\n\r\n/**\r\n * Interface for price component props.\r\n * @param {boolean} isPriceMinMaxEnabled - Whether the price range feature is enabled or not.\r\n * @param {IPriceComponentResources} priceResources - The price range resources.\r\n */\r\nexport interface IPriceComponentProps extends IComponentProps<{ price: ProductPrice }> {\r\n className?: string;\r\n product?: SimpleProduct;\r\n savingsText?: string;\r\n freePriceText?: string;\r\n originalPriceText?: string;\r\n currentPriceText?: string;\r\n isPriceMinMaxEnabled?: boolean;\r\n isSalesAgreementPriceFeatureEnabled?: boolean;\r\n salesAgreementLineId?: number;\r\n priceResources?: IPriceComponentResources;\r\n salesAgreementDetailCollapseProps?: ICollapseProps;\r\n currencyCode?: string;\r\n showDiscountBox?: boolean;\r\n salesAgreementDetailOnClick?(event: React.MouseEvent | React.KeyboardEvent): void;\r\n}\r\n\r\n/**\r\n * The interface of price component.\r\n */\r\nexport interface IPriceComponent extends IComponent {}\r\n\r\nconst priceComponentActions = {};\r\n\r\n/**\r\n * Get the original price from price component props.\r\n * @param props - The IPriceComponentProps.\r\n * @returns The original price.\r\n */\r\nconst getOriginalPrice = (props: IPriceComponentProps): number => {\r\n return Math.max(\r\n props.data.price.BasePrice || defaultPrice,\r\n props.data.price.TradeAgreementPrice || defaultPrice,\r\n props.data.price.AdjustedPrice || defaultPrice\r\n );\r\n};\r\n\r\nconst getActivePrice = (props: IPriceComponentProps): number => {\r\n if (showPriceRangeForMasterProduct(props) && props.data.price.MinVariantPrice !== undefined) {\r\n return props.data.price.MinVariantPrice;\r\n }\r\n\r\n if (props.data.price.CustomerContextualPrice !== undefined) {\r\n return props.data.price.CustomerContextualPrice;\r\n }\r\n\r\n return getOriginalPrice(props);\r\n};\r\n\r\n/**\r\n * Get the formatted currency.\r\n * @param props - The props.\r\n * @param price - The price.\r\n * @param shouldUseFreePriceText - The shouldUseFreePriceText.\r\n * @returns The formatted currency.\r\n */\r\nconst formatCurrency = (\r\n props: IPriceComponentProps,\r\n price: number | undefined,\r\n shouldUseFreePriceText: boolean | undefined,\r\n currencyCode?: string | undefined\r\n): string => {\r\n if (price === undefined) {\r\n return '';\r\n }\r\n\r\n if (shouldUseFreePriceText && price === freePrice && props.freePriceText) {\r\n return props.freePriceText;\r\n }\r\n\r\n return props.context.cultureFormatter.formatCurrency(price, currencyCode);\r\n};\r\n\r\nconst showPriceRangeForMasterProduct = (props: IPriceComponentProps): boolean => {\r\n return (\r\n (props.isPriceMinMaxEnabled ?? false) &&\r\n (props.product?.ProductTypeValue === ProductType.Master || props.product?.ProductTypeValue === ProductType.KitMaster) &&\r\n props.data.price.MinVariantPrice !== undefined &&\r\n props.data.price.MaxVariantPrice !== undefined\r\n );\r\n};\r\n\r\n/**\r\n * ShowStrikethroughPricing.\r\n * @param props - The props.\r\n * @returns True if showStrikethroughPricing, false otherwise.\r\n */\r\nconst showStrikethroughPricing = (props: IPriceComponentProps): boolean => {\r\n const originalSalesPrice = getOriginalPrice(props);\r\n const activeSalesPrice = showPriceRangeForMasterProduct(props)\r\n ? props.data.price.MinVariantPrice\r\n : props.data.price.CustomerContextualPrice;\r\n\r\n if (activeSalesPrice && originalSalesPrice) {\r\n return activeSalesPrice < originalSalesPrice;\r\n }\r\n\r\n return false;\r\n};\r\n\r\n/**\r\n * Render current price.\r\n * @param props - The props.\r\n * @returns The JSX.Element.\r\n */\r\nconst renderCurrentPrice = (\r\n props: IPriceComponentProps,\r\n priceClass: string = 'msc-price__actual',\r\n isMemberDiscount: boolean = false\r\n): JSX.Element => {\r\n const maxVariantPrice: string = formatCurrency(props, props.data.price.MaxVariantPrice, false, props.currencyCode);\r\n const minVariantPrice: string = formatCurrency(props, props.data.price.MinVariantPrice, false, props.currencyCode);\r\n if (\r\n props.isPriceMinMaxEnabled &&\r\n props.data.price.MaxVariantPrice &&\r\n props.data.price.MinVariantPrice &&\r\n props.data.price.MaxVariantPrice > props.data.price.MinVariantPrice\r\n ) {\r\n return (\r\n \r\n \r\n {minVariantPrice}\r\n \r\n \r\n {props.priceResources?.priceRangeSeparator}\r\n \r\n \r\n {maxVariantPrice}\r\n \r\n \r\n );\r\n }\r\n\r\n return (\r\n \r\n {isMemberDiscount && !props.showDiscountBox && `${props.priceResources?.memberPriceMessage} `}\r\n {formatCurrency(props, getActivePrice(props), true, props.currencyCode)}\r\n \r\n );\r\n};\r\n\r\n/**\r\n * Render active sales price with original sales price.\r\n * @param props - The props.\r\n * @returns The JSX.Element.\r\n */\r\nconst renderCurrentPriceWithOriginalPrice = (props: IPriceComponentProps): JSX.Element => {\r\n const initialPrice: string = formatCurrency(props, getOriginalPrice(props), true);\r\n return (\r\n <>\r\n \r\n {` `}\r\n {props.originalPriceText}\r\n {` `}\r\n {initialPrice}\r\n {` `}\r\n {props.currentPriceText}\r\n {` `}\r\n {renderCurrentPrice(props, 'msc-price__discount')}\r\n \r\n \r\n \r\n {props.savingsText && {props.savingsText}}\r\n \r\n );\r\n};\r\n\r\nconst renderSalesAgreementDetail = (props: IPriceComponentProps): JSX.Element => {\r\n // In most cases there should be only one sales agreement line.\r\n // If there are more than one, only the first one will be shown.\r\n const firstPriceLine: SalesAgreementPriceLine = (props.data.price.AttainablePriceLines ?? [])[0] as SalesAgreementPriceLine;\r\n return (\r\n

\r\n

\r\n {/* Available date */}\r\n {` · ${format(\r\n props.priceResources?.salesAgreementExpirationDatePrompt ?? '',\r\n props.context.cultureFormatter.formatDate(firstPriceLine.EffectiveDate as Date),\r\n props.context.cultureFormatter.formatDate(firstPriceLine.ExpirationDate as Date)\r\n )}`}\r\n

\r\n

\r\n {/* Quantity commitment */}\r\n {` · ${format(props.priceResources?.salesAgreementCommittedQuantityPrompt ?? '', firstPriceLine.CommittedQuantity)}`}\r\n

\r\n

\r\n {/* Remaining quantity to qualify */}\r\n {` · ${format(props.priceResources?.salesAgreementRemainingQuantityPrompt ?? '', firstPriceLine.RemainingQuantity)}`}\r\n

\r\n

\r\n );\r\n};\r\n\r\n/**\r\n * Render member price.\r\n * @param props - The props.\r\n * @returns The JSX.Element.\r\n */\r\nconst renderMemberPrice = (props: IPriceComponentProps): JSX.Element => {\r\n const initialPrice: string = formatCurrency(props, getOriginalPrice(props), true);\r\n //No strikethrough in member price\r\n return (\r\n <>\r\n \r\n {` `}\r\n {props.originalPriceText}\r\n {` `}\r\n {initialPrice}\r\n {` `}\r\n {props.currentPriceText}\r\n {` `}\r\n {renderCurrentPrice(props, 'msc-price__discount__member', true)}\r\n \r\n \r\n \r\n {props.savingsText && {props.savingsText}}\r\n \r\n );\r\n};\r\n\r\nfunction renderDiscountBox(props: IPriceComponentProps, isMemberDiscount: boolean) {\r\n var discount = 0;\r\n if (props.data.price.CustomerContextualPrice !== undefined && props.data.price.BasePrice !== undefined) {\r\n var diff = props.data.price.CustomerContextualPrice - props.data.price.BasePrice;\r\n discount = (diff / props.data.price.BasePrice) * 100;\r\n }\r\n if (props.data.price?.BasePrice !== props.data.price?.CustomerContextualPrice) {\r\n if (isMemberDiscount) {\r\n return (\r\n
\r\n

{`${props.priceResources?.memberPriceMessage} `}

\r\n
\r\n );\r\n } else {\r\n return (\r\n
\r\n

{`${props.priceResources?.saleMessage}${Math.abs(discount).toFixed(0)}%`}

\r\n
\r\n );\r\n }\r\n } else {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Price.\r\n * @param props - The props.\r\n * @returns The JSX.Element.\r\n */\r\nconst Price: React.FC = (props: IPriceComponentProps): JSX.Element | null => {\r\n // CustomerContextualPrice could be zero\r\n if (props.data.price.CustomerContextualPrice === undefined) {\r\n return null;\r\n }\r\n\r\n //TODO: Not a priority - but should be fixed\r\n var isMemberDiscount = false;\r\n props.data.price.DiscountLines?.forEach(discount => {\r\n if (discount.OfferName?.toLowerCase().includes(props.context.request.app.config.loyaltyDiscountIdentifier)) {\r\n isMemberDiscount = true;\r\n }\r\n });\r\n\r\n // Determine if contract price is avaiable/applied by:\r\n // isFeatureEnabled and SA price != 0, for PDP.\r\n // SA line id != 0, for cart line.\r\n if (props.isSalesAgreementPriceFeatureEnabled && props.data.price.SalesAgreementPrice !== 0) {\r\n const [isExpanded, setIsExpanded] = React.useState(false);\r\n const toggle = () => {\r\n setIsExpanded(!isExpanded);\r\n };\r\n return (\r\n \r\n \r\n

\r\n {formatCurrency(props, props.data.price.SalesAgreementPrice ?? props.data.price.CustomerContextualPrice, true)}\r\n

\r\n \r\n {props.priceResources?.salesAgreementPricePrompt}\r\n \r\n {isExpanded && renderSalesAgreementDetail(props)}\r\n
\r\n
\r\n );\r\n }\r\n\r\n return (\r\n
\r\n {isMemberDiscount ? (\r\n {renderMemberPrice(props)}\r\n ) : (\r\n \r\n {showStrikethroughPricing(props) ? renderCurrentPriceWithOriginalPrice(props) : renderCurrentPrice(props)}\r\n \r\n )}\r\n {props.showDiscountBox && renderDiscountBox(props, isMemberDiscount)}\r\n
\r\n );\r\n};\r\n\r\n/**\r\n * The PriceComponent.\r\n */\r\nexport const PriceComponent: React.FunctionComponent = msdyn365Commerce.createComponentOverride(\r\n 'Price',\r\n { component: Price, ...priceComponentActions }\r\n);\r\n\r\nexport default PriceComponent;\r\n","import React, { FC, PropsWithChildren } from 'react';\r\n\r\ntype ShowProps = {\r\n condition: boolean;\r\n Otherwise?: FC | JSX.Element;\r\n};\r\nexport const Show = ({ children, condition, Otherwise }: PropsWithChildren): JSX.Element => (\r\n <>{condition ? children : Otherwise !== undefined ? Otherwise : <>}\r\n);\r\n\r\nexport default Show;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport { ISwatchItem, ProductComponentSwatchComponent, RatingComponent, AddToWishlistComponent } from '@msdyn365-commerce/components';\r\nimport { PriceComponent, IPriceComponentResources } from './price.component';\r\nimport {\r\n getCatalogId,\r\n IAny,\r\n IComponent,\r\n IComponentProps,\r\n ICoreContext,\r\n IGeneric,\r\n IGridSettings,\r\n IImageData,\r\n IImageSettings,\r\n Image,\r\n msdyn365Commerce\r\n} from '@msdyn365-commerce/core';\r\nimport {\r\n AttributeSwatch,\r\n AttributeValue,\r\n CommerceList,\r\n ProductDimension,\r\n ProductPrice,\r\n ProductSearchResult\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n ArrayExtensions,\r\n convertDimensionTypeToProductDimensionType,\r\n Dictionary,\r\n DimensionTypes,\r\n generateImageUrl,\r\n getProductPageUrlSync,\r\n IDimensionsApp,\r\n StringExtensions,\r\n validateCatalogId\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n format,\r\n getPayloadObject,\r\n getTelemetryAttributes,\r\n ITelemetryContent,\r\n onTelemetryClick\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport React, { useState } from 'react';\r\nimport { ProductSearchResultExpanded } from '../classes/ProductSearchResultExpanded';\r\nimport { isValidImage } from '../functions/is-valid-image';\r\nimport Show from '../../components/common/Show/show';\r\n\r\nexport interface IProductComponentProps extends IComponentProps<{ product?: ProductSearchResultExpanded }> {\r\n className?: string;\r\n imageSettings?: IImageSettings;\r\n savingsText?: string;\r\n freePriceText?: string;\r\n originalPriceText?: string;\r\n currentPriceText?: string;\r\n ratingAriaLabel?: string;\r\n ratingCountAriaLabel?: string;\r\n allowBack?: boolean;\r\n telemetryContent?: ITelemetryContent;\r\n quickViewButton?: React.ReactNode;\r\n productComparisonButton?: React.ReactNode;\r\n isEnabledProductDescription?: boolean;\r\n isPriceMinMaxEnabled?: boolean;\r\n priceResources?: IPriceComponentResources;\r\n inventoryLabel?: string;\r\n dimensionAvailabilities?: IProductsDimensionsAvailabilities[];\r\n swatchItemAriaLabel?: string;\r\n wishlist?: CommerceList[];\r\n wishlistInProductCard?: boolean;\r\n}\r\n\r\nexport interface IProductComponent extends IComponent {}\r\n\r\nconst PriceComponentActions = {};\r\n\r\n/**\r\n * Gets the product page url from the default swatch selected.\r\n * @param productData - Product card to be rendered.\r\n * @returns The default color swatch selected if any.\r\n */\r\nfunction getDefaultSwatchSelected(coreContext: ICoreContext, productData?: ProductSearchResult): AttributeSwatch | null {\r\n if (!productData || !productData.AttributeValues) {\r\n return null;\r\n }\r\n\r\n const siteContext = coreContext as ICoreContext;\r\n const dimensionToPreSelectInProductCard = siteContext.app.config.dimensionToPreSelectInProductCard;\r\n\r\n const attributeSwatches = productData.AttributeValues.find(\r\n attributeValue => attributeValue.KeyName?.toLocaleLowerCase() === dimensionToPreSelectInProductCard\r\n )?.Swatches;\r\n\r\n if (!ArrayExtensions.hasElements(attributeSwatches)) {\r\n return null;\r\n }\r\n\r\n const defaultSwatch = attributeSwatches.find(item => item.IsDefault === true) ?? attributeSwatches[0];\r\n return defaultSwatch;\r\n}\r\n\r\n/**\r\n * Gets the product image from the default swatch selected.\r\n * @param coreContext - Context of the module using the component.\r\n * @param productData - Product card to be rendered.\r\n * @returns The product card image url.\r\n */\r\nfunction getProductImageUrlFromDefaultSwatch(coreContext: ICoreContext, productData?: ProductSearchResult): string | undefined {\r\n const defaultSwatch = getDefaultSwatchSelected(coreContext, productData);\r\n const swatchProductImageUrls = defaultSwatch?.ProductImageUrls;\r\n if (!ArrayExtensions.hasElements(swatchProductImageUrls)) {\r\n return productData?.PrimaryImageUrl;\r\n }\r\n\r\n // bs extension - place media library images first\r\n const isMediaLibraryImage = (item: string) => {\r\n return item && item.startsWith('Products');\r\n };\r\n\r\n if (coreContext.request.app.config.filterLegacyImageUrls) {\r\n const imageUrl = swatchProductImageUrls\r\n .sort((a, b) => Number(isMediaLibraryImage(b)) - Number(isMediaLibraryImage(a)))\r\n .find(item => {\r\n return isValidImage(item);\r\n });\r\n if (imageUrl) {\r\n return generateImageUrl(imageUrl, coreContext.request.apiSettings);\r\n }\r\n }\r\n\r\n return generateImageUrl(swatchProductImageUrls[0], coreContext.request.apiSettings);\r\n}\r\n\r\n/**\r\n * Updates the product url link to product details page.\r\n * @param productDetailsPageUrl - Product page url.\r\n * @param coreContext - Context of the module using the component.\r\n * @param queryString - Querystring to be added to the URL.\r\n * @returns The update product page url.\r\n */\r\nfunction updateProductUrl(productDetailsPageUrl: string, coreContext: ICoreContext, queryString: string): string {\r\n const sourceUrl = new URL(productDetailsPageUrl, coreContext.request.apiSettings.baseUrl);\r\n if (sourceUrl.search) {\r\n sourceUrl.search += `&${queryString}`;\r\n } else {\r\n sourceUrl.search += queryString;\r\n }\r\n\r\n const updatedUrl = new URL(sourceUrl.href);\r\n return updatedUrl.pathname + sourceUrl.search;\r\n}\r\n\r\n/**\r\n * Gets the react node for product unit of measure display.\r\n * @param unitOfMeasure - DefaultUnitOfMeasure property from product.\r\n * @returns The node representing markup for unit of measure component.\r\n */\r\nfunction renderProductUnitOfMeasure(unitOfMeasure?: string): JSX.Element | null {\r\n if (!unitOfMeasure) {\r\n return null;\r\n }\r\n return (\r\n
\r\n {unitOfMeasure}\r\n
\r\n );\r\n}\r\n\r\n/**\r\n * Gets the react node for product availability.\r\n * @param inventoryAvailabilityLabel - The product information.\r\n * @returns The node representing markup for product availability.\r\n */\r\nfunction renderProductAvailability(inventoryAvailabilityLabel: string | undefined): JSX.Element | null {\r\n if (!inventoryAvailabilityLabel || inventoryAvailabilityLabel === '') {\r\n return null;\r\n }\r\n\r\n return (\r\n
\r\n {inventoryAvailabilityLabel}\r\n
\r\n );\r\n}\r\n\r\n/**\r\n * Renders product comparison button similar to the quick view button.\r\n * @param productComparisonButton - React element of the button.\r\n * @param product - Current product info.\r\n * @param catalogId - Current catalog.\r\n * @returns React element for the specific product.\r\n */\r\nfunction renderProductComparisonButton(\r\n productComparisonButton: React.ReactNode,\r\n product: ProductSearchResult,\r\n catalogId: number\r\n): JSX.Element | undefined {\r\n validateCatalogId(catalogId);\r\n return React.cloneElement(productComparisonButton as React.ReactElement, { product, catalogId });\r\n}\r\n\r\n/**\r\n * Gets the product page url from the default swatch selected.\r\n * @param coreContext - Context of the module using the component.\r\n * @param productUrl - Product page url for the product card.\r\n * @param productData - Product card to be rendered.\r\n * @returns The product card image url.\r\n */\r\nfunction getProductPageUrlFromDefaultSwatch(\r\n coreContext: ICoreContext,\r\n productUrl: string,\r\n productData?: ProductSearchResult\r\n): string | undefined {\r\n const defaultSwatch = getDefaultSwatchSelected(coreContext, productData);\r\n if (!defaultSwatch?.SwatchValue) {\r\n return productUrl;\r\n }\r\n\r\n const siteContext = coreContext as ICoreContext;\r\n const dimensionToPreSelectInProductCard = siteContext.app.config.dimensionToPreSelectInProductCard;\r\n\r\n const queryStringEncoded = encodeURIComponent(defaultSwatch.SwatchValue);\r\n const queryString = `${dimensionToPreSelectInProductCard}=${queryStringEncoded}`;\r\n return updateProductUrl(productUrl, coreContext, queryString);\r\n}\r\n\r\nconst ProductCard: React.FC = ({\r\n data,\r\n context,\r\n imageSettings,\r\n savingsText,\r\n freePriceText,\r\n originalPriceText,\r\n currentPriceText,\r\n ratingAriaLabel,\r\n ratingCountAriaLabel,\r\n allowBack,\r\n typeName,\r\n id,\r\n telemetryContent,\r\n quickViewButton,\r\n productComparisonButton,\r\n isEnabledProductDescription,\r\n isPriceMinMaxEnabled,\r\n priceResources,\r\n inventoryLabel,\r\n dimensionAvailabilities,\r\n swatchItemAriaLabel,\r\n wishlist,\r\n wishlistInProductCard\r\n}) => {\r\n const product = data.product;\r\n\r\n let productUrl = getProductPageUrlSync(product?.Name ?? '', product?.RecordId ?? Number.MIN_VALUE, context.actionContext, undefined);\r\n if (allowBack) {\r\n productUrl = updateProductUrl(productUrl, context, 'back=true');\r\n }\r\n const productImageUrlFromSwatch = getProductImageUrlFromDefaultSwatch(context, product) ?? product?.PrimaryImageUrl;\r\n const productPageUrlFromSwatch = getProductPageUrlFromDefaultSwatch(context, productUrl, product) ?? productUrl;\r\n const [productPageUrl, setProductPageUrl] = useState(productPageUrlFromSwatch);\r\n const [productImageUrl, setProductImageUrl] = useState(productImageUrlFromSwatch);\r\n React.useEffect(() => {\r\n setProductPageUrl(productPageUrlFromSwatch);\r\n setProductImageUrl(productImageUrlFromSwatch);\r\n }, [productUrl, productPageUrlFromSwatch, productImageUrlFromSwatch]);\r\n const [selectedSwatchItems] = useState(new Dictionary());\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access -- app context is generic\r\n const enableStockCheck = context.app.config.enableStockCheck;\r\n\r\n const siteContext = context as ICoreContext;\r\n const dimensionToPreSelectInProductCard = siteContext.app.config.dimensionToPreSelectInProductCard;\r\n\r\n /**\r\n * Updates the product page and Image url based on swatch selected.\r\n * @param coreContext - Context of the caller.\r\n * @param swatchItem - Dimension swatch selected.\r\n */\r\n const updatePageAndImageUrl = React.useCallback(\r\n (coreContext: ICoreContext, swatchItem: ISwatchItem) => {\r\n const dimensionType = swatchItem.dimensionType;\r\n selectedSwatchItems.setValue(dimensionType, swatchItem);\r\n if (StringExtensions.isNullOrWhitespace(swatchItem.value)) {\r\n return;\r\n }\r\n const queryString = `${dimensionType}=${swatchItem.value}`;\r\n let productPageUrlWithSwatch = '';\r\n if (productPageUrl.includes(dimensionType)) {\r\n const newUrl = new URL(productPageUrl, coreContext.request.apiSettings.baseUrl);\r\n newUrl.searchParams.delete(dimensionType);\r\n productPageUrlWithSwatch = updateProductUrl(newUrl.toString(), context, queryString);\r\n } else {\r\n productPageUrlWithSwatch = updateProductUrl(productPageUrl, context, queryString);\r\n }\r\n setProductPageUrl(productPageUrlWithSwatch);\r\n if (dimensionType === dimensionToPreSelectInProductCard) {\r\n const swatchProductImageUrl = ArrayExtensions.hasElements(swatchItem.productImageUrls)\r\n ? swatchItem.productImageUrls[0]\r\n : undefined;\r\n const newImageUrl = generateImageUrl(swatchProductImageUrl, coreContext.request.apiSettings);\r\n setProductImageUrl(newImageUrl);\r\n }\r\n },\r\n [selectedSwatchItems, context, productPageUrl]\r\n );\r\n\r\n if (!product) {\r\n return null;\r\n }\r\n\r\n /**\r\n * Checks if rendering the particular dimensions is allowed for product card.\r\n * @param dimensionType - Dimension to be displayed.\r\n * @returns Updates the state with new product page url.\r\n */\r\n function shouldDisplayDimension(dimensionType: string): boolean {\r\n const dimensionsContext = context as ICoreContext;\r\n const dimensionsToDisplayOnProductCard = dimensionsContext.app.config.dimensionsInProductCard;\r\n return (\r\n ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) &&\r\n !dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) &&\r\n dimensionsToDisplayOnProductCard.includes(dimensionType.toLocaleLowerCase() as DimensionTypes)\r\n );\r\n }\r\n\r\n /**\r\n * Gets the react node for product dimension as swatch.\r\n * @param attributeValues - Attribute value property from product.\r\n * @returns The node representing markup for unit of measure component.\r\n */\r\n function renderProductDimensions(attributeValues?: AttributeValue[]): JSX.Element | null {\r\n if (!attributeValues) {\r\n return null;\r\n }\r\n\r\n return (\r\n
\r\n {attributeValues.map((item: AttributeValue) => {\r\n const dimensionTypeValue = item.KeyName?.toLocaleLowerCase() ?? '';\r\n if (!shouldDisplayDimension(dimensionTypeValue)) {\r\n return null;\r\n }\r\n\r\n const siteContext = context as ICoreContext;\r\n const dimensionToPreSelectInProductCard = siteContext.app.config.dimensionToPreSelectInProductCard;\r\n const dimensionType = dimensionTypeValue as DimensionTypes;\r\n const swatches =\r\n item.Swatches?.map(swatchItem => {\r\n return {\r\n itemId: `${item.RecordId ?? ''}-${dimensionTypeValue}-${swatchItem.SwatchValue ?? ''}`,\r\n value: swatchItem.SwatchValue ?? '',\r\n dimensionType,\r\n colorHexCode: swatchItem.SwatchColorHexCode,\r\n imageUrl: swatchItem.SwatchImageUrl,\r\n productImageUrls: swatchItem.ProductImageUrls,\r\n isDefault: swatchItem.IsDefault,\r\n swatchItemAriaLabel: swatchItemAriaLabel ? format(swatchItemAriaLabel, dimensionType) : '',\r\n isDisabled:\r\n enableStockCheck &&\r\n dimensionAvailabilities?.find(\r\n dimensionAvailability => dimensionAvailability.value === (swatchItem.SwatchValue ?? '')\r\n )?.isDisabled\r\n };\r\n }) ?? [];\r\n if (\r\n dimensionType === dimensionToPreSelectInProductCard &&\r\n ArrayExtensions.hasElements(swatches) &&\r\n !swatches.some(swatch => swatch.isDefault)\r\n ) {\r\n swatches[0].isDefault = true;\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n

+{product?.additionalSwatches}

\r\n
\r\n
\r\n );\r\n })}\r\n
\r\n );\r\n }\r\n\r\n function renderQuickView(quickview: React.ReactNode, item?: number): JSX.Element | undefined {\r\n if (quickview === null) {\r\n return undefined;\r\n }\r\n const selectedDimensions: ProductDimension[] = selectedSwatchItems.getValues().map(swatches => {\r\n return {\r\n DimensionTypeValue: convertDimensionTypeToProductDimensionType(swatches.dimensionType),\r\n DimensionValue: {\r\n RecordId: 0,\r\n Value: swatches.value\r\n }\r\n };\r\n });\r\n return React.cloneElement(quickview as React.ReactElement, { selectedProductId: item, selectedDimensions });\r\n }\r\n\r\n // Construct telemetry attribute to render\r\n const payLoad = getPayloadObject('click', telemetryContent!, '', product.RecordId.toString());\r\n\r\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- -- Do not need type check for appsettings\r\n const isUnitOfMeasureEnabled = context.app.config && context.app.config.unitOfMeasureDisplayType === 'buyboxAndBrowse';\r\n\r\n return (\r\n <>\r\n {isEnabledProductDescription ? (\r\n \r\n
\r\n
\r\n {renderProductPlacementImage(\r\n imageSettings,\r\n context.request.gridSettings,\r\n productImageUrl,\r\n product.PrimaryImageUrl,\r\n product.Name,\r\n context\r\n )}\r\n
\r\n
\r\n
{product.Name}
\r\n {renderPrice(\r\n context,\r\n typeName,\r\n id,\r\n product.BasePrice,\r\n product.Price,\r\n savingsText,\r\n freePriceText,\r\n originalPriceText,\r\n currentPriceText,\r\n isPriceMinMaxEnabled,\r\n priceResources,\r\n product.ProductPrice\r\n )}\r\n {isUnitOfMeasureEnabled && renderProductUnitOfMeasure(product.DefaultUnitOfMeasure)}\r\n {renderDescription(product.Description)}\r\n
\r\n {wishlistInProductCard && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n \r\n ) : (\r\n
\r\n \r\n
\r\n {renderProductPlacementImage(\r\n imageSettings,\r\n context.request.gridSettings,\r\n productImageUrl,\r\n product.PrimaryImageUrl,\r\n product.Name,\r\n context\r\n )}\r\n
\r\n
\r\n
{product.Name}
\r\n {renderPrice(\r\n context,\r\n typeName,\r\n id,\r\n product.BasePrice,\r\n product.Price,\r\n savingsText,\r\n freePriceText,\r\n originalPriceText,\r\n currentPriceText,\r\n undefined,\r\n priceResources,\r\n product.ProductPrice\r\n )}\r\n {isUnitOfMeasureEnabled && renderProductUnitOfMeasure(product.DefaultUnitOfMeasure)}\r\n
\r\n \r\n {wishlistInProductCard && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n )}\r\n {renderProductDimensions(product.AttributeValues)}\r\n {!context.app.config.hideRating &&\r\n renderRating(context, typeName, id, product.AverageRating, product.TotalRatings, ratingAriaLabel, ratingCountAriaLabel)}\r\n {renderProductAvailability(inventoryLabel)}\r\n {quickViewButton && renderQuickView(quickViewButton, product.RecordId)}\r\n {productComparisonButton && renderProductComparisonButton(productComparisonButton, product, getCatalogId(context.request))}\r\n \r\n );\r\n};\r\n\r\nfunction renderLabel(\r\n name?: string,\r\n price?: string,\r\n rating?: number,\r\n ratingAriaLabelText?: string,\r\n reviewCount?: number,\r\n ratingCountAriaLabelText?: string\r\n): string {\r\n const reviewCountArialableText = getReviewAriaLabel(reviewCount, ratingCountAriaLabelText ?? '');\r\n return `${name ?? ''} ${price ?? ''} ${getRatingAriaLabel(rating, ratingAriaLabelText)}${\r\n reviewCountArialableText ? ` ${reviewCountArialableText}` : ''\r\n }`;\r\n}\r\n\r\nfunction renderDescription(description?: string): JSX.Element | null {\r\n return

{description}

;\r\n}\r\n\r\nfunction getRatingAriaLabel(rating?: number, ratingAriaLabel?: string): string {\r\n if (rating && ratingAriaLabel) {\r\n const roundedRating = rating.toFixed(2);\r\n return format(ratingAriaLabel || '', roundedRating, '5');\r\n }\r\n return '';\r\n}\r\n\r\nfunction getReviewAriaLabel(reviewCount?: number, ratingCountAriaLabelText?: string): string {\r\n if (reviewCount && ratingCountAriaLabelText) {\r\n return format(ratingCountAriaLabelText || '', reviewCount);\r\n }\r\n return '';\r\n}\r\n\r\nfunction renderRating(\r\n coreContext: ICoreContext,\r\n moduleTypeName: string,\r\n moduleId: string,\r\n avgRating?: number,\r\n totalRatings?: number,\r\n ariaLabel?: string,\r\n ratingCountAriaLabel?: string\r\n): JSX.Element | null {\r\n if (!avgRating) {\r\n return null;\r\n }\r\n\r\n const numberRatings = totalRatings?.toString() || undefined;\r\n const ratingAriaLabelText = getRatingAriaLabel(avgRating, ariaLabel);\r\n const ratingCountAriaLabelText = getReviewAriaLabel(Number(numberRatings), ratingCountAriaLabel);\r\n\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction renderPrice(\r\n context: ICoreContext,\r\n typeName: string,\r\n id: string,\r\n basePrice?: number,\r\n adjustedPrice?: number,\r\n savingsText?: string,\r\n freePriceText?: string,\r\n originalPriceText?: string,\r\n currentPriceText?: string,\r\n isPriceMinMaxEnabled?: boolean,\r\n priceResources?: IPriceComponentResources,\r\n productPrice?: ProductPrice\r\n): JSX.Element | null {\r\n const price: ProductPrice =\r\n productPrice !== undefined\r\n ? productPrice\r\n : {\r\n BasePrice: basePrice,\r\n AdjustedPrice: adjustedPrice,\r\n CustomerContextualPrice: adjustedPrice\r\n };\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction renderProductPlacementImage(\r\n imageSettings?: IImageSettings,\r\n gridSettings?: IGridSettings,\r\n imageUrl?: string,\r\n fallbackImageUrl?: string,\r\n altText?: string,\r\n context?: ICoreContext>\r\n): JSX.Element | null {\r\n if (!imageUrl || !gridSettings || !imageSettings) {\r\n return null;\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment -- Site level config can be of any type.\r\n const contextConfig = context?.app.config?.placeholderImageName;\r\n const emptyPlaceHolderImage = contextConfig as string;\r\n let fallbackImageSource = fallbackImageUrl;\r\n if (emptyPlaceHolderImage && fallbackImageUrl) {\r\n fallbackImageSource = `${fallbackImageUrl},${emptyPlaceHolderImage}`;\r\n }\r\n const img: IImageData = {\r\n src: imageUrl,\r\n altText: altText ? altText : '',\r\n fallBackSrc: fallbackImageSource\r\n };\r\n const imageProps = {\r\n gridSettings,\r\n imageSettings\r\n };\r\n imageProps.imageSettings.cropFocalRegion = true;\r\n return (\r\n \r\n );\r\n}\r\n\r\nexport const ProductComponent: React.FunctionComponent = msdyn365Commerce.createComponentOverride<\r\n IProductComponent\r\n>('Product', { component: ProductCard, ...PriceComponentActions });\r\n\r\nexport default ProductComponent;\r\n","/**\r\n * Centralised location for checkout generic data updates\r\n */\r\nimport { AffiliationLoyaltyTier } from '@msdyn365-commerce/retail-proxy';\r\n\r\ninterface AffiliationId {\r\n locale: string;\r\n affiliationId: number;\r\n}\r\ninterface LoyaltyTierIds {\r\n locale: string;\r\n loyaltyTierIds: string;\r\n}\r\n\r\n/**\r\n * Generates the affiliationloyaltytiers for the current locale\r\n * @param locale\r\n * @param affiliationId\r\n * @param loyaltyTierIds\r\n * @returns AffiliationLoyaltyTier[]\r\n */\r\nexport const getAffiliation = (\r\n locale: string,\r\n affiliationIds: AffiliationId[],\r\n loyaltyTiersIds: LoyaltyTierIds[]\r\n): AffiliationLoyaltyTier[] => {\r\n var affiliation: AffiliationLoyaltyTier[] = [];\r\n\r\n const affiliationId = affiliationIds?.find(item => {\r\n return item.locale === locale;\r\n })?.affiliationId;\r\n\r\n const loyaltyTiers = loyaltyTiersIds.find(item => {\r\n return item.locale === locale;\r\n })?.loyaltyTierIds;\r\n\r\n const loyaltyTierIds = loyaltyTiers?.split('|') ?? [];\r\n loyaltyTierIds.forEach(tier => {\r\n affiliation.push({\r\n AffiliationId: Number(affiliationId),\r\n LoyaltyTierId: Number(tier)\r\n });\r\n });\r\n\r\n return affiliation;\r\n};\r\n","const binding = { modules: {}, dataActions: {} };\n\n const registerActionId = (actionPath) => {\n if (binding.dataActions[actionPath] &&\n binding.dataActions[actionPath].default &&\n binding.dataActions[actionPath].default.prototype &&\n binding.dataActions[actionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[actionPath].default.prototype.id] = binding.dataActions[actionPath];\n } else {\n Object.keys(binding.dataActions[actionPath] || {}).forEach(exportName => {\n if (binding.dataActions[actionPath][exportName] &&\n binding.dataActions[actionPath][exportName].prototype &&\n binding.dataActions[actionPath][exportName].prototype.Action) {\n binding.dataActions[binding.dataActions[actionPath][exportName].prototype.id] = binding.dataActions[actionPath][exportName];\n }\n })\n }\n };\n\n const registerSanitizedActionPath = (sanitizedActionPath, dataAction) => {\n if (process.env.NODE_ENV === 'development') {\n if (!dataAction.default) {\n throw new Error('Data action path does not have a default export');\n }\n if (!(dataAction.default.prototype.id && binding.dataActions[dataAction.default.prototype.id]) || !binding.dataActions[sanitizedActionPath]) {\n binding.dataActions[sanitizedActionPath] = dataAction;\n }\n } else {\n binding.dataActions[sanitizedActionPath] = dataAction;\n if (!binding.dataActions[sanitizedActionPath].default) {\n throw new Error('Data action path ' + sanitizedActionPath + ' does not have a default export');\n }\n binding.dataActions[sanitizedActionPath].default.prototype.RegistrationId = sanitizedActionPath;\n if (binding.dataActions[sanitizedActionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[sanitizedActionPath].default.prototype.id] = sanitizedActionPath;\n }\n }\n };\n \n\n (binding.modules['ext-product-collection'] = {\n c: () => require('partner/modules/ext-product-collection/ext-product-collection.tsx'),\n $type: 'containerModule',\n da: [{name:'featureState', path:'@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state', runOn: 0}],\n \n iNM: false,\n ns: '__local__',\n n: 'ext-product-collection',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/ext-product-collection'\n });\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state';\n let dataAction = require('@msdyn365-commerce-modules/retail-actions/dist/lib/get-feature-state');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };\n export const viewDictionary = {};\n viewDictionary['__local__|__local__|modules|ext-product-collection|ext-product-collection'] = {\n c: () => require('partner/modules/ext-product-collection/ext-product-collection.view.tsx'),\n cn: '__local__-__local__-ext-product-collection'\n };\nwindow.__bindings__ = window.__bindings__ || {};\nwindow.__bindings__.viewDictionary = {\n ...window.__bindings__.viewDictionary || {},\n ...viewDictionary\n };","/**\r\n * Copyright (c) Microsoft Corporation\r\n * All rights reserved. See License.txt in the project root for license information.\r\n * IExtProductCollection containerModule Interface Properties\r\n * THIS FILE IS AUTO-GENERATED - MANUAL MODIFICATIONS WILL BE LOST\r\n */\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport * as React from 'react';\r\n\r\nexport const enum layout {\r\n carousel = 'carousel',\r\n grid = 'grid'\r\n}\r\n\r\nexport interface IExtProductCollectionConfig extends Msdyn365.IModuleConfig {\r\n productCollection: Msdyn365.IProductList;\r\n heading?: IHeadingData;\r\n layout?: layout;\r\n allowBackNavigation?: boolean;\r\n imageSettings?: Msdyn365.IImageSettings;\r\n clientRender?: boolean;\r\n enableAffiliationBasedPricing?: boolean;\r\n shouldDisplaySeeAllButton?: boolean;\r\n className?: string;\r\n enableAvailabilityCheck?: boolean;\r\n}\r\n\r\nexport interface IExtProductCollectionResources {\r\n priceFree: string;\r\n priceRangeSeparator: string;\r\n ratingAriaLabel: string;\r\n flipperNext: string;\r\n flipperPrevious: string;\r\n originalPriceText: string;\r\n currentPriceText: string;\r\n ratingCountAriaLabel: string;\r\n ratingCountAriaLabelSingleUser: string;\r\n seeAllButtonText: string;\r\n memberPriceMessage: string;\r\n saleMessage: string;\r\n}\r\n\r\nexport const enum HeadingTag {\r\n h1 = 'h1',\r\n h2 = 'h2',\r\n h3 = 'h3',\r\n h4 = 'h4',\r\n h5 = 'h5',\r\n h6 = 'h6'\r\n}\r\n\r\nexport interface IHeadingData {\r\n text: string;\r\n tag?: HeadingTag;\r\n}\r\n\r\nexport interface IExtProductCollectionProps extends Msdyn365.IModule {\r\n resources: IExtProductCollectionResources;\r\n config: IExtProductCollectionConfig;\r\n slots: {\r\n quickview: React.ReactNode[];\r\n productComparisonButton: React.ReactNode[];\r\n };\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { getCatalogId, getUrlSync, ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductPrice, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n ArrayExtensions,\r\n DimensionAvailabilitiesForProductSearchResultInput,\r\n DimensionTypes,\r\n DimensionSwatchDisplayTypes,\r\n getDimensionAvailabilitiesForProductSearchResultAction,\r\n IDimensionsApp,\r\n ObjectExtensions,\r\n PriceForProductSearchResultInput,\r\n validateCatalogId\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n Button,\r\n getTelemetryObject,\r\n IComponentNodeProps,\r\n IModuleProps,\r\n INodeProps,\r\n ISingleSlideCarouselProps,\r\n ITelemetryContent,\r\n NodeTag,\r\n SingleSlideCarousel\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { IExtProductCollectionData } from './ext-product-collection.data';\r\nimport { IExtProductCollectionProps, layout } from './ext-product-collection.props.autogenerated';\r\n\r\nimport { ProductComponent } from '../../shared/components/product.component';\r\nimport { IPriceComponentResources } from '../../shared/components/price.component';\r\n\r\nexport interface IProductCollectionViewProps extends IExtProductCollectionProps {\r\n heading?: React.ReactNode;\r\n ProductCollectionContainer: IModuleProps;\r\n SingleSlideCarouselComponentProps: INodeProps;\r\n GridComponentProps: INodeProps;\r\n products: IProductComponentViewProps[];\r\n isCarousel: boolean;\r\n productPrices?: ProductPrice[];\r\n seeAllButton?: React.ReactNode;\r\n}\r\n\r\nexport interface IProductComponentViewProps {\r\n ProductContainer: INodeProps;\r\n productComponent: React.ReactNode;\r\n}\r\nexport interface IProductComponentState {\r\n products: ProductSearchResultExpanded[];\r\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\r\n productsFiltered: boolean;\r\n}\r\n\r\nimport { getCommercialName } from '../../shared/functions/get-commercial-name';\r\nimport { getPriceForProductSearchResultAction } from '../../actions/get-price-for-product-search-result';\r\nimport { ProductSearchResultExpanded } from '../../shared/classes/ProductSearchResultExpanded';\r\n\r\n/**\r\n * ProductCollection component.\r\n */\r\nclass ProductCollection extends React.PureComponent, IProductComponentState> {\r\n private readonly telemetryContent: ITelemetryContent;\r\n\r\n private readonly productPrices: ProductPrice[];\r\n\r\n constructor(props: IExtProductCollectionProps) {\r\n super(props);\r\n this.productPrices = [];\r\n this.state = {\r\n products: this.props.config.productCollection.products || [],\r\n productsFiltered: false\r\n };\r\n this.telemetryContent = getTelemetryObject(\r\n this.props.context.request.telemetryPageName!,\r\n this.props.friendlyName,\r\n this.props.telemetry\r\n );\r\n }\r\n\r\n public async componentDidMount(): Promise {\r\n if (this.props.config.enableAffiliationBasedPricing) {\r\n await this._getActivePrice();\r\n }\r\n }\r\n\r\n public async componentDidUpdate(): Promise {\r\n if (this.props.app.config.hideProductsWithoutImages) {\r\n document.querySelectorAll('.msc-empty_image').forEach(item => {\r\n var li = item.closest('li');\r\n if (li !== null) {\r\n //TOOD: should be information telemetry\r\n this.props.telemetry.warning('Product without image was filtered out', li.querySelector('a')?.href);\r\n li.style.display = 'none';\r\n }\r\n });\r\n }\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { heading, className, shouldDisplaySeeAllButton } = this.props.config;\r\n const { resources } = this.props;\r\n const recommendation = this.props.config.productCollection.recommendationListId;\r\n\r\n // Initialize state in case if the products were not found during initial module render\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises -- Initialize data if not there.\r\n this.initProductState(this.props.config.productCollection);\r\n\r\n const products = this.state.products;\r\n if (this.props.app.config?.useCommercialStyleName) {\r\n for (var product of products) {\r\n product.Name = getCommercialName(\r\n product.AttributeValues,\r\n product.Name,\r\n this.props.app.config?.commercialStyleNameAttribute\r\n );\r\n }\r\n }\r\n const isCarousel = this.props.config.layout ? this.props.config.layout === layout.carousel : true;\r\n const headingLabel = heading ? heading.text : '';\r\n const headingComponent = heading && (\r\n \r\n );\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- product check for safety.\r\n const updatedProducts = products?.map((item: ProductSearchResult, index: number) => {\r\n const getProductData = this._getProduct(item, index);\r\n return !ObjectExtensions.isNullOrUndefined(getProductData) ? getProductData : undefined;\r\n });\r\n\r\n const productCollectionViewProps = {\r\n ...this.props,\r\n heading: headingComponent,\r\n SingleSlideCarouselComponentProps: {\r\n tag: SingleSlideCarousel,\r\n className: '',\r\n flipperPrevLabel: `${headingLabel} ${resources.flipperPrevious}`,\r\n flipperNextLabel: `${headingLabel} ${resources.flipperNext}`,\r\n parentId: this.props.id,\r\n telemetryContent: this.telemetryContent\r\n } as IComponentNodeProps,\r\n ProductCollectionContainer: {\r\n moduleProps: this.props,\r\n className: classnames('ms-product-collection', className)\r\n },\r\n GridComponentProps: {\r\n tag: 'ul' as NodeTag,\r\n className: 'ms-product-collection__items'\r\n },\r\n isCarousel,\r\n\r\n products:\r\n ArrayExtensions.hasElements(updatedProducts) &&\r\n updatedProducts.filter(item => {\r\n return item !== undefined;\r\n }),\r\n productPrices: this.productPrices,\r\n seeAllButton:\r\n recommendation && shouldDisplaySeeAllButton && ArrayExtensions.hasElements(updatedProducts)\r\n ? this._getSeeAllButton(recommendation, headingLabel)\r\n : undefined\r\n };\r\n return this.props.renderView(productCollectionViewProps) as React.ReactElement;\r\n }\r\n\r\n public handleHeadingChange = (event: Msdyn365.ContentEditableEvent) => (this.props.config.heading!.text = event.target.value);\r\n\r\n /**\r\n * Get products dimension availabilities.\r\n * @param products - Products.\r\n * @returns Promise.\r\n */\r\n private readonly _getProductsDimensionsAvailabilities = async (products: ProductSearchResult[]): Promise => {\r\n if (!this.props.config.enableAvailabilityCheck) {\r\n return;\r\n }\r\n\r\n const context = this.props.context as ICoreContext;\r\n const dimensionsToDisplayOnProductCard = context.app.config.dimensionsInProductCard;\r\n const dimensionsToDisplayAsSwatch = context.app.config.dimensionsAsSwatchType;\r\n const validProducts = ArrayExtensions.validValues(products);\r\n if (\r\n ArrayExtensions.hasElements(validProducts) &&\r\n ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) &&\r\n !dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) &&\r\n ArrayExtensions.hasElements(dimensionsToDisplayAsSwatch) &&\r\n !dimensionsToDisplayAsSwatch.includes(DimensionTypes.none)\r\n ) {\r\n const productsDimensionAvailabilities = await getDimensionAvailabilitiesForProductSearchResultAction(\r\n new DimensionAvailabilitiesForProductSearchResultInput(\r\n validProducts,\r\n this.props.context as ICoreContext,\r\n DimensionSwatchDisplayTypes.productCard\r\n ),\r\n this.props.context.actionContext\r\n );\r\n\r\n if (ArrayExtensions.hasElements(productsDimensionAvailabilities)) {\r\n this.setState({ productsDimensionAvailabilities });\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Helper method to initialize products state.\r\n * @param productCollection - List of products.\r\n */\r\n private readonly initProductState = async (productCollection: Msdyn365.IProductList) => {\r\n let products = this.state.products;\r\n const productCollectionProducts = productCollection.products;\r\n if (!ArrayExtensions.hasElements(products) && ArrayExtensions.hasElements(productCollectionProducts)) {\r\n products = productCollectionProducts;\r\n this.setState({ products });\r\n } else if (\r\n // If the products have been manually filtered, they are allowed to be different\r\n ArrayExtensions.hasElements(products) &&\r\n ArrayExtensions.hasElements(productCollectionProducts) &&\r\n !ArrayExtensions.equals(products, productCollectionProducts) &&\r\n !this.state.productsFiltered\r\n ) {\r\n products = productCollectionProducts;\r\n this.setState({ products });\r\n } else if (productCollectionProducts === undefined && ArrayExtensions.hasElements(this.state.products)) {\r\n products = [];\r\n this.setState({ products: products });\r\n }\r\n\r\n if (Msdyn365.msdyn365Commerce.isBrowser && !ArrayExtensions.hasElements(this.state.productsDimensionAvailabilities)) {\r\n await this._getProductsDimensionsAvailabilities(products);\r\n }\r\n };\r\n\r\n private readonly _getProduct = (product: ProductSearchResultExpanded, index: number): IProductComponentViewProps | null => {\r\n if (!product || !product.Name) {\r\n this.props.telemetry.trace('[product-collection] Product or product name is null');\r\n return null;\r\n }\r\n const telemetryContent = getTelemetryObject(\r\n this.props.context.request.telemetryPageName!,\r\n this.props.friendlyName,\r\n this.props.telemetry\r\n );\r\n const { imageSettings, allowBackNavigation } = this.props.config;\r\n\r\n // BS - default image settings for mobile\r\n if (imageSettings && !imageSettings?.viewports) {\r\n imageSettings.viewports = {\r\n xs: { q: 'w=295&h=393&m=6', w: 0, h: 0 }\r\n };\r\n }\r\n const resources = this.props.resources;\r\n const breaCrumbType = this.props.context.app.config.breadcrumbType;\r\n const allowBack = allowBackNavigation && (breaCrumbType === 'back' || breaCrumbType === 'categoryAndBack');\r\n const quickviewSlot =\r\n this.props.slots && this.props.slots.quickview && this.props.slots.quickview.length > 0 ? this.props.slots.quickview[0] : null;\r\n const productComparisonButtonSlot = ArrayExtensions.hasElements(this.props.slots.productComparisonButton)\r\n ? this.props.slots.productComparisonButton[0]\r\n : null;\r\n\r\n const reviewCount = 1;\r\n const reviewTotalRatings = Number(product.TotalRatings);\r\n const reviewCountAriaLabelValue =\r\n reviewTotalRatings > reviewCount ? resources.ratingCountAriaLabel : resources.ratingCountAriaLabelSingleUser;\r\n const isPriceMinMaxEnabled = this.props.data.featureState.result?.find(\r\n featureState => featureState.Name === 'Dynamics.AX.Application.RetailSearchPriceRangeFeature'\r\n );\r\n const priceResources: IPriceComponentResources = {\r\n priceRangeSeparator: resources.priceRangeSeparator,\r\n memberPriceMessage: resources.memberPriceMessage,\r\n saleMessage: resources.saleMessage\r\n };\r\n return {\r\n ProductContainer: {\r\n tag: 'li' as NodeTag,\r\n className: 'ms-product-collection__item',\r\n role: 'listitem',\r\n key: index\r\n },\r\n productComponent: (\r\n \r\n ArrayExtensions.hasElements(dimensionAvailability) &&\r\n dimensionAvailability[0].masterProductId === (product.MasterProductId ?? product.RecordId)\r\n )}\r\n />\r\n )\r\n };\r\n };\r\n\r\n /**\r\n * Get the active price for products.\r\n */\r\n private readonly _getActivePrice = async (): Promise => {\r\n const productsList = this.state.products;\r\n //Uses custom action\r\n const products = await getPriceForProductSearchResultAction(\r\n new PriceForProductSearchResultInput(productsList),\r\n this.props.context.actionContext\r\n );\r\n if (Msdyn365.msdyn365Commerce.isBrowser) {\r\n await this._getProductsDimensionsAvailabilities(products);\r\n }\r\n\r\n this.setState({ products });\r\n };\r\n\r\n /**\r\n * Get the see all button.\r\n * @param recommendation - Recommendation.\r\n * @param headingLabel - Heading label.\r\n * @returns IProductComponentSeeAllViewProps - Product component see all view props.\r\n */\r\n private readonly _getSeeAllButton = (recommendation: string, headingLabel: string): React.ReactNode => {\r\n if (!Msdyn365.msdyn365Commerce.isBrowser) {\r\n return null;\r\n }\r\n\r\n const catalogId = getCatalogId(this.props.context.request);\r\n validateCatalogId(catalogId);\r\n const searchPageLink = getUrlSync('search', this.props.context.actionContext);\r\n if (!searchPageLink) {\r\n return null;\r\n }\r\n\r\n const url = new URL(searchPageLink, window.location.href);\r\n url.searchParams.set('recommendation', recommendation);\r\n url.searchParams.set('title', headingLabel);\r\n url.searchParams.set('catalogid', `${catalogId}`);\r\n\r\n return (\r\n \r\n {this.props.resources.seeAllButtonText}\r\n \r\n );\r\n };\r\n}\r\n\r\nexport default ProductCollection;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { CacheType, createObservableDataAction, getCatalogId, IAction, IActionContext, IActionInput } from '@msdyn365-commerce/core';\r\nimport {\r\n ProductPrice,\r\n ProductsDataActions,\r\n ProductSearchResult,\r\n ProjectionDomain,\r\n AffiliationLoyaltyTier\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { ArrayExtensions, QueryResultSettingsProxy } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ProductSearchResultExpanded } from '../shared/classes/ProductSearchResultExpanded';\r\nimport { getAffiliation } from '../shared/functions/get-affiliation';\r\nimport { ProductResultWithSwatchLimit } from '../modules/ext-search-result-container/actions/get-full-products-by-collection';\r\n\r\n/**\r\n * Input class for the GetPriceForProductSearchResult Data Action.\r\n */\r\nexport class PriceForProductSearchResultInput implements IActionInput {\r\n public products: ProductSearchResultExpanded[];\r\n\r\n public constructor(products: ProductSearchResult[]) {\r\n this.products = products;\r\n }\r\n\r\n /**\r\n * Get the cache key.\r\n * @returns The cache key.\r\n */\r\n public getCacheKey = (): string => `PriceForProductSearchResult-${JSON.stringify(this.products)}`;\r\n\r\n /**\r\n * Get the cache object type.\r\n * @returns The cache object type.\r\n */\r\n public getCacheObjectType = (): string => 'ProductSearchResult';\r\n\r\n /**\r\n * Define the data cache type.\r\n * @returns The cache type.\r\n */\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * The createInput method for the GetPriceForProductSearchResultDataAction.\r\n * @param products -- The product search result.\r\n * @returns The input.\r\n */\r\nexport const createActivePriceForProductSearchResultInput = (products: ProductSearchResultExpanded[]): PriceForProductSearchResultInput => {\r\n return new PriceForProductSearchResultInput(products);\r\n};\r\n\r\n/**\r\n * The Action Method for the GetPriceForProductSearchResult Data Action\r\n * Gets the active price for product search result via the getActivePrice RetailServer API.\r\n * @param input -- The data input.\r\n * @param context -- The action context.\r\n * @returns The product search result updated with price.\r\n */\r\nexport async function getPriceForProductSearchResultAction(\r\n input: PriceForProductSearchResultInput,\r\n context: IActionContext\r\n): Promise {\r\n let productRecIds: number[];\r\n if (ArrayExtensions.hasElements(input.products)) {\r\n productRecIds = input.products.map(product => product.RecordId);\r\n //Remove duplicate ids from variant splitting\r\n productRecIds = productRecIds.filter((item, index, array) => array.indexOf(item) === index);\r\n } else {\r\n return Promise.resolve([]);\r\n }\r\n\r\n const catalogId = getCatalogId(context.requestContext);\r\n\r\n const projectDomain: ProjectionDomain = { ChannelId: +context.requestContext.apiSettings.channelId, CatalogId: catalogId };\r\n const priceZero = 0;\r\n\r\n var affiliation: AffiliationLoyaltyTier[] = getAffiliation(\r\n context.requestContext.locale,\r\n context.requestContext.app.config.affiliationIds,\r\n context.requestContext.app.config.loyaltyTierIds\r\n );\r\n\r\n try {\r\n const productPrices: ProductPrice[] = await ProductsDataActions.getActivePricesAsync(\r\n { callerContext: context, queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context) },\r\n projectDomain,\r\n productRecIds,\r\n new Date(),\r\n null,\r\n affiliation,\r\n true,\r\n false,\r\n true\r\n );\r\n\r\n const productResults: ProductSearchResultExpanded[] = input.products.map(product => {\r\n const activePrice = productPrices.find(price => price.ProductId === product.RecordId);\r\n if (activePrice) {\r\n product.Price = activePrice.CustomerContextualPrice ?? product.Price;\r\n product.BasePrice = Math.max(\r\n activePrice.BasePrice ?? priceZero,\r\n activePrice.TradeAgreementPrice ?? priceZero,\r\n activePrice.AdjustedPrice ?? priceZero\r\n );\r\n product.ProductPrice = activePrice;\r\n }\r\n return product;\r\n });\r\n\r\n return Promise.resolve(productResults);\r\n } catch (error) {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- existing error type.\r\n if (error instanceof Error) {\r\n context.telemetry.exception(error);\r\n context.telemetry.debug('[getPriceForProductSearchResultAction]Error executing action');\r\n context.telemetry.debug(error.message);\r\n }\r\n throw new Error('[getPriceForProductSearchResultAction]Error executing action');\r\n }\r\n}\r\n\r\n/**\r\n * The getPriceForProductSearchResult data action.\r\n */\r\nexport const getPriceForProductSearchResultDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-price-for-product-search-result',\r\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- existing pattern.\r\n action: >getPriceForProductSearchResultAction,\r\n input: createActivePriceForProductSearchResultInput\r\n});\r\n\r\nexport default getPriceForProductSearchResultDataAction;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { INodeProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { IProductCollectionViewProps, IProductComponentViewProps } from './ext-product-collection';\r\n\r\nconst ProductCollectionView: React.FC = props => {\r\n const {\r\n heading,\r\n ProductCollectionContainer,\r\n products,\r\n SingleSlideCarouselComponentProps,\r\n GridComponentProps,\r\n isCarousel,\r\n seeAllButton\r\n } = props;\r\n\r\n if (products) {\r\n return (\r\n \r\n {heading}\r\n {seeAllButton}\r\n {isCarousel ? _renderCarousel(SingleSlideCarouselComponentProps, products) : _renderGrid(GridComponentProps, products)}\r\n \r\n );\r\n }\r\n //props.context.telemetry.error('Product collection content is empty, module wont render.');\r\n return null;\r\n};\r\n\r\nconst _renderCarousel = (carouselContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return {items && items.map(_renderProduct)};\r\n};\r\n\r\nconst _renderGrid = (gridContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return {items && items.map(_renderProduct)};\r\n};\r\n\r\nconst _renderProduct = (product: IProductComponentViewProps): JSX.Element => {\r\n const { ProductContainer, productComponent } = product;\r\n\r\n return {productComponent};\r\n};\r\n\r\nexport default ProductCollectionView;\r\n"],"names":["module","exports","React","ReactDOM","getCommercialName","_productName$split$","attributes","arguments","length","undefined","productName","commercialStyleNameAttribute","styleName","find","x","Name","productBrand","split","TextValue","isValidImage","url","startsWith","getOriginalPrice","props","Math","max","data","price","BasePrice","TradeAgreementPrice","AdjustedPrice","getActivePrice","showPriceRangeForMasterProduct","MinVariantPrice","CustomerContextualPrice","formatCurrency","shouldUseFreePriceText","currencyCode","freePriceText","context","cultureFormatter","_props$isPriceMinMaxE","_props$product","_props$product2","isPriceMinMaxEnabled","product","ProductTypeValue","ProductType","Master","KitMaster","MaxVariantPrice","renderCurrentPrice","_props$priceResources2","priceClass","isMemberDiscount","maxVariantPrice","minVariantPrice","_props$priceResources","className","itemProp","priceResources","priceRangeSeparator","showDiscountBox","memberPriceMessage","PriceComponent","msdyn365Commerce","createComponentOverride","_objectSpread","component","_props$data$price$Dis","DiscountLines","forEach","discount","_discount$OfferName","OfferName","toLowerCase","includes","request","app","config","loyaltyDiscountIdentifier","isSalesAgreementPriceFeatureEnabled","SalesAgreementPrice","_props$data$price$Sal","_props$priceResources11","_props$priceResources12","isExpanded","setIsExpanded","toggle","classnames","Button","salesAgreementPricePrompt","onClick","tabIndex","_props$data$price$Att","_props$priceResources3","_props$priceResources4","_props$priceResources5","_props$priceResources6","_props$priceResources7","_props$priceResources8","firstPriceLine","AttainablePriceLines","format","salesAgreementExpirationDatePrompt","formatDate","EffectiveDate","ExpirationDate","salesAgreementCommittedQuantityPrompt","CommittedQuantity","salesAgreementRemainingQuantityPrompt","RemainingQuantity","renderSalesAgreementDetail","initialPrice","originalPriceText","currentPriceText","savingsText","renderMemberPrice","originalSalesPrice","activeSalesPrice","showStrikethroughPricing","renderCurrentPriceWithOriginalPrice","_props$data$price","_props$data$price2","_props$priceResources9","_props$priceResources10","saleMessage","abs","toFixed","renderDiscountBox","_ref","children","condition","Otherwise","getDefaultSwatchSelected","coreContext","productData","_productData$Attribut","_attributeSwatches$fi","AttributeValues","dimensionToPreSelectInProductCard","attributeSwatches","attributeValue","_attributeValue$KeyNa","KeyName","toLocaleLowerCase","Swatches","ArrayExtensions","hasElements","item","IsDefault","updateProductUrl","productDetailsPageUrl","queryString","sourceUrl","URL","apiSettings","baseUrl","search","href","pathname","renderProductUnitOfMeasure","unitOfMeasure","renderLabel","name","rating","ratingAriaLabelText","reviewCount","ratingCountAriaLabelText","reviewCountArialableText","getReviewAriaLabel","getRatingAriaLabel","ratingAriaLabel","roundedRating","renderPrice","typeName","id","basePrice","adjustedPrice","productPrice","renderProductPlacementImage","imageSettings","gridSettings","imageUrl","fallbackImageUrl","altText","_context$app$config","contextConfig","placeholderImageName","fallbackImageSource","img","src","fallBackSrc","imageProps","cropFocalRegion","Image","Object","assign","requestContext","actionContext","loadFailureBehavior","bypassHideOnFailure","ProductComponent","_product$Name","_product$RecordId","_getProductImageUrlFr","_getProductPageUrlFro","ratingCountAriaLabel","allowBack","telemetryContent","quickViewButton","productComparisonButton","isEnabledProductDescription","inventoryLabel","dimensionAvailabilities","swatchItemAriaLabel","wishlist","wishlistInProductCard","productUrl","getProductPageUrlSync","RecordId","Number","MIN_VALUE","productImageUrlFromSwatch","defaultSwatch","swatchProductImageUrls","ProductImageUrls","PrimaryImageUrl","isMediaLibraryImage","filterLegacyImageUrls","sort","a","b","generateImageUrl","getProductImageUrlFromDefaultSwatch","productPageUrlFromSwatch","SwatchValue","encodeURIComponent","getProductPageUrlFromDefaultSwatch","productPageUrl","setProductPageUrl","useState","productImageUrl","setProductImageUrl","selectedSwatchItems","Dictionary","enableStockCheck","updatePageAndImageUrl","swatchItem","dimensionType","setValue","StringExtensions","isNullOrWhitespace","value","productPageUrlWithSwatch","newUrl","searchParams","delete","toString","swatchProductImageUrl","productImageUrls","newImageUrl","payLoad","getPayloadObject","attribute","getTelemetryAttributes","isUnitOfMeasureEnabled","unitOfMeasureDisplayType","onTelemetryClick","Price","AverageRating","TotalRatings","ProductPrice","DefaultUnitOfMeasure","description","Description","AddToWishlistComponent","nameOfWishlist","addToWishlistButtonText","removeFromWishlistButtonText","wishlists","attributeValues","map","_item$KeyName$toLocal","_item$KeyName","_item$Swatches$map","_item$Swatches","dimensionTypeValue","dimensionsToDisplayOnProductCard","dimensionsInProductCard","DimensionTypes","none","shouldDisplayDimension","swatches","_item$RecordId","_swatchItem$SwatchVal","_swatchItem$SwatchVal2","_dimensionAvailabilit","itemId","colorHexCode","SwatchColorHexCode","SwatchImageUrl","isDefault","isDisabled","dimensionAvailability","_swatchItem$SwatchVal3","some","swatch","key","ProductComponentSwatchComponent","onSelectDimension","Show","additionalSwatches","hideRating","moduleTypeName","moduleId","avgRating","totalRatings","ariaLabel","numberRatings","RatingComponent","ratingCount","readOnly","renderRating","inventoryAvailabilityLabel","quickview","selectedDimensions","getValues","DimensionTypeValue","convertDimensionTypeToProductDimensionType","DimensionValue","Value","selectedProductId","renderQuickView","catalogId","validateCatalogId","renderProductComparisonButton","getCatalogId","getAffiliation","locale","affiliationIds","loyaltyTiersIds","_affiliationIds$find","_loyaltyTiersIds$find","_loyaltyTiers$split","affiliation","affiliationId","loyaltyTiers","loyaltyTierIds","tier","push","AffiliationId","LoyaltyTierId","binding","modules","dataActions","c","require","$type","da","path","runOn","iNM","ns","n","p","pdp","md","registerSanitizedActionPath","sanitizedActionPath","dataAction","default","Error","prototype","RegistrationId","window","__bindings__","viewDictionary","cn","layout","HeadingTag","ProductCollection","constructor","super","handleHeadingChange","event","this","heading","text","target","_getProductsDimensionsAvailabilities","async","enableAvailabilityCheck","dimensionsToDisplayAsSwatch","dimensionsAsSwatchType","validProducts","validValues","products","productsDimensionAvailabilities","getDimensionAvailabilitiesForProductSearchResultAction","DimensionAvailabilitiesForProductSearchResultInput","DimensionSwatchDisplayTypes","productCard","setState","initProductState","state","productCollectionProducts","productCollection","equals","productsFiltered","Msdyn365","isBrowser","_getProduct","index","_this$props$data$feat","_this$state$productsD","telemetry","trace","getTelemetryObject","telemetryPageName","friendlyName","allowBackNavigation","viewports","xs","q","w","h","resources","breaCrumbType","breadcrumbType","quickviewSlot","slots","productComparisonButtonSlot","reviewCountAriaLabelValue","ratingCountAriaLabelSingleUser","featureState","result","ProductContainer","tag","role","productComponent","priceFree","IsEnabled","_product$MasterProduc","masterProductId","MasterProductId","_getActivePrice","productsList","getPriceForProductSearchResultAction","PriceForProductSearchResultInput","_getSeeAllButton","recommendation","headingLabel","searchPageLink","getUrlSync","location","set","title","seeAllButtonText","productPrices","enableAffiliationBasedPricing","hideProductsWithoutImages","document","querySelectorAll","_li$querySelector","li","closest","warning","querySelector","style","display","render","_this$props$app$confi","shouldDisplaySeeAllButton","recommendationListId","useCommercialStyleName","_this$props$app$confi2","isCarousel","carousel","headingComponent","editProps","onEdit","updatedProducts","getProductData","ObjectExtensions","isNullOrUndefined","productCollectionViewProps","SingleSlideCarouselComponentProps","SingleSlideCarousel","flipperPrevLabel","flipperPrevious","flipperNextLabel","flipperNext","parentId","ProductCollectionContainer","moduleProps","GridComponentProps","filter","seeAllButton","renderView","getCacheKey","JSON","stringify","getCacheObjectType","dataCacheType","input","productRecIds","Promise","resolve","array","indexOf","projectDomain","ChannelId","channelId","CatalogId","ProductsDataActions","callerContext","queryResultSettings","QueryResultSettingsProxy","getPagingFromInputDataOrDefaultValue","Date","productResults","activePrice","ProductId","_activePrice$Customer","_activePrice$BasePric","_activePrice$TradeAgr","_activePrice$Adjusted","error","exception","debug","message","createObservableDataAction","action","_renderCarousel","carouselContainer","items","Node","_renderProduct","_renderGrid","gridContainer","Module"],"sourceRoot":""}