{"version":3,"file":"static/js/73c0db6e045e714e2915.bundle.js","mappings":"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","sources":["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/is-valid-image.ts?b7db","webpack://bestseller.commerce.online/./src/themes/only/views/components/price.component.tsx?116a","webpack://bestseller.commerce.online/./src/themes/only/views/components/product.component.tsx?467e"],"sourcesContent":["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 if (coreContext.request.app.config.filterLegacyImageUrls) {\r\n const imageUrl = swatchProductImageUrls.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","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","/*!\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 { isValidImage } from '../../../../shared/functions/is-valid-image';\r\nimport { ProductSearchResultExpanded } from '../../../../shared/classes/ProductSearchResultExpanded';\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 if (coreContext.request.app.config.filterLegacyImageUrls) {\r\n const imageUrl = swatchProductImageUrls.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 return (\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"],"names":["_ref","children","condition","Otherwise","React","undefined","getDefaultSwatchSelected","coreContext","productData","_productData$Attribut","_attributeSwatches$fi","AttributeValues","dimensionToPreSelectInProductCard","app","config","attributeSwatches","find","attributeValue","_attributeValue$KeyNa","KeyName","toLocaleLowerCase","Swatches","ArrayExtensions","hasElements","item","IsDefault","updateProductUrl","productDetailsPageUrl","queryString","sourceUrl","URL","request","apiSettings","baseUrl","search","href","pathname","renderProductUnitOfMeasure","unitOfMeasure","className","renderLabel","name","price","rating","ratingAriaLabelText","reviewCount","ratingCountAriaLabelText","reviewCountArialableText","getReviewAriaLabel","getRatingAriaLabel","ratingAriaLabel","roundedRating","toFixed","format","renderPrice","context","typeName","id","basePrice","adjustedPrice","savingsText","freePriceText","originalPriceText","currentPriceText","isPriceMinMaxEnabled","priceResources","productPrice","BasePrice","AdjustedPrice","CustomerContextualPrice","PriceComponent","data","showDiscountBox","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","msdyn365Commerce","createComponentOverride","_objectSpread","component","_product$Name","_product$RecordId","_getProductImageUrlFr","_getProductPageUrlFro","ratingCountAriaLabel","allowBack","telemetryContent","quickViewButton","productComparisonButton","isEnabledProductDescription","inventoryLabel","dimensionAvailabilities","swatchItemAriaLabel","wishlist","wishlistInProductCard","product","productUrl","getProductPageUrlSync","Name","RecordId","Number","MIN_VALUE","productImageUrlFromSwatch","defaultSwatch","swatchProductImageUrls","ProductImageUrls","PrimaryImageUrl","filterLegacyImageUrls","isValidImage","generateImageUrl","getProductImageUrlFromDefaultSwatch","productPageUrlFromSwatch","SwatchValue","encodeURIComponent","getProductPageUrlFromDefaultSwatch","productPageUrl","setProductPageUrl","useState","productImageUrl","setProductImageUrl","selectedSwatchItems","Dictionary","enableStockCheck","updatePageAndImageUrl","swatchItem","dimensionType","setValue","StringExtensions","isNullOrWhitespace","value","productPageUrlWithSwatch","includes","newUrl","searchParams","delete","toString","swatchProductImageUrl","productImageUrls","newImageUrl","payLoad","getPayloadObject","attribute","getTelemetryAttributes","isUnitOfMeasureEnabled","unitOfMeasureDisplayType","onClick","onTelemetryClick","cultureFormatter","formatCurrency","Price","AverageRating","TotalRatings","ProductPrice","DefaultUnitOfMeasure","description","Description","AddToWishlistComponent","nameOfWishlist","addToWishlistButtonText","removeFromWishlistButtonText","ProductTypeValue","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","url","startsWith","getOriginalPrice","props","Math","max","TradeAgreementPrice","getActivePrice","showPriceRangeForMasterProduct","MinVariantPrice","shouldUseFreePriceText","currencyCode","_props$isPriceMinMaxE","_props$product","_props$product2","ProductType","Master","KitMaster","MaxVariantPrice","renderCurrentPrice","_props$priceResources2","priceClass","arguments","length","isMemberDiscount","maxVariantPrice","minVariantPrice","_props$priceResources","itemProp","priceRangeSeparator","memberPriceMessage","_props$data$price$Dis","DiscountLines","forEach","discount","_discount$OfferName","OfferName","toLowerCase","loyaltyDiscountIdentifier","isSalesAgreementPriceFeatureEnabled","SalesAgreementPrice","_props$data$price$Sal","_props$priceResources11","_props$priceResources12","isExpanded","setIsExpanded","toggle","classnames","Button","salesAgreementPricePrompt","tabIndex","_props$data$price$Att","_props$priceResources3","_props$priceResources4","_props$priceResources5","_props$priceResources6","_props$priceResources7","_props$priceResources8","firstPriceLine","AttainablePriceLines","salesAgreementExpirationDatePrompt","formatDate","EffectiveDate","ExpirationDate","salesAgreementCommittedQuantityPrompt","CommittedQuantity","salesAgreementRemainingQuantityPrompt","RemainingQuantity","renderSalesAgreementDetail","initialPrice","renderMemberPrice","originalSalesPrice","activeSalesPrice","showStrikethroughPricing","renderCurrentPriceWithOriginalPrice","_props$data$price","_props$data$price2","_props$priceResources9","_props$priceResources10","saleMessage","abs","renderDiscountBox"],"sourceRoot":""}