{"version":3,"file":"static/js/e2c17a1433264601b89e.bundle.js","mappings":"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","sources":["webpack://Msdyn365.Commerce.Online/./src/actions/get-organization-customer.ts?79c2","webpack://Msdyn365.Commerce.Online/./src/actions/get-product-unit-of-measure-options.action.ts?bc1e","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/base-collection-action.ts?11e2","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-cached-price-for-product-search-results.ts?029f","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-full-products-by-collection.ts?8637","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-mapped-search-configuration.ts?6b32","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-refiners-for-collection.ts?5d9b","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-inventory-refiners.ts?275a","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/refiner-utils.ts?04ba","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/url-utils.ts?6503","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/choice-summary.tsx?f410","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/error-message.tsx?3c52","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/feature-search-result-item.tsx?eefa","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/link.tsx?b255","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/modal.tsx?c4c9","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/product-search-result-items.tsx?573e","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/separator.tsx?f88a","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/title.tsx?e5ce","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/range-refine-item.tsx?1286","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/refine-item.tsx?7edb","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/refine-submenu.tsx?776f","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/utilities.ts?c7b3","webpack://Msdyn365.Commerce.Online/./src/shared-utils/attributes/on-buy-access-validator.ts?4b31","webpack://Msdyn365.Commerce.Online/./src/shared-utils/cookie-utilities.ts?6237"],"sourcesContent":["import { createObservableDataAction, IActionContext, IAction, ICreateActionContext, IGeneric, IAny, ICommerceApiSettings } from '@msdyn365-commerce/core';\r\nimport { CacheType, callActionOrExecute, Customer, DataServiceQuery, IActionInput, IDataServiceRequest } from \"@msdyn365-commerce/retail-proxy\";\r\nimport * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\n\r\nexport class GetOrganizationCustomerInput implements IActionInput {\r\n private readonly user: string | undefined;\r\n private readonly query: DataServiceQuery;\r\n\r\n constructor(apiSettings: ICommerceApiSettings, user: string) {\r\n this.user = user;\r\n\r\n this.query = new DataServiceQuery();\r\n }\r\n\r\n public getDataServiceRequest = (): IDataServiceRequest => {\r\n return this.query.createDataServiceRequestForOperation(\r\n 'GetOrganizationCustomer',\r\n false,\r\n Entities.CustomerClass,\r\n 'false',\r\n {\r\n bypassCache: 'get',\r\n returnEntity: 'Entities.CustomerClass'\r\n },\r\n {}\r\n );\r\n };\r\n\r\n public shouldCacheOutput = (): boolean => false;\r\n\r\n public getCacheKey = () => `OrganizationCustomer-${this.user}`;\r\n public getCacheObjectType = () => 'OrganizationCustomer';\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext>): GetOrganizationCustomerInput => {\r\n const { user } = inputData.requestContext;\r\n return new GetOrganizationCustomerInput(inputData.requestContext.apiSettings, user.customerAccountNumber ?? \"\");\r\n};\r\n\r\nexport const getOrganizationCustomerAction = async (input: GetOrganizationCustomerInput, ctx: IActionContext): Promise => {\r\n if (!ctx.requestContext.user.isAuthenticated) {\r\n return {};\r\n }\r\n var customer = await callActionOrExecute(input.getDataServiceRequest(), ctx);\r\n return customer;\r\n};\r\n\r\nexport const getOrganizationCustomer = createObservableDataAction({\r\n id: 'src/actions/get-organization-customer',\r\n action: >getOrganizationCustomerAction,\r\n input: createInput\r\n});\r\n\r\nexport default getOrganizationCustomer;\r\n","import { callActionOrExecute, DataServiceQuery, IContext, IDataServiceRequest, IQueryResultSettings } from \"@msdyn365-commerce/retail-proxy\";\r\nimport * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\nimport * as Types from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\nfunction getProductUnitOfMeasureOptionsQuery(): DataServiceQuery {\r\n return new DataServiceQuery();\r\n}\r\n\r\n\r\nexport function getProductUnitOfMeasureOptionsInput(\r\n queryResultSettings: IQueryResultSettings, productIds:\r\n number[]\r\n): IDataServiceRequest {\r\n const query = getProductUnitOfMeasureOptionsQuery().resultSettings(queryResultSettings);\r\n query.top(10000);\r\n return query.createDataServiceRequestForOperation(\r\n 'GetProductUnitOfMeasureOptions',\r\n true, Entities.UnitOfMeasureConversionClass,\r\n 'true',\r\n { bypassCache: 'none', returnEntity: 'Entities.UnitOfMeasureConversion' },\r\n {\r\n productIds: productIds\r\n }\r\n );\r\n}\r\n\r\nexport async function getProductUnitOfMeasureOptionsAsync(context: IContext, productIds: number[]): Promise {\r\n const request = getProductUnitOfMeasureOptionsInput(\r\n context.queryResultSettings || {}, productIds);\r\n const conversions = await callActionOrExecute(request, context.callerContext);\r\n return conversions;\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 { CacheType, getCatalogId, IActionInput, IAny, ICommerceApiSettings, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport {\r\n convertToString,\r\n ChannelInventoryConfiguration,\r\n IQueryResultSettings,\r\n ProductRefinerValue,\r\n SortColumn\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { generateCacheKey, QueryResultSettingsProxy } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { toJS } from 'mobx';\r\n\r\nimport { hydrateRefinersFromUrl } from './url-utils';\r\n\r\n/**\r\n * Export listPageType.\r\n */\r\nexport type listPageType = 'Category' | 'Search' | 'Unknown';\r\n\r\n/**\r\n * Get include attributes from config.\r\n * @param inputData - ICreateActionContext.\r\n * @returns Boolean.\r\n */\r\nfunction getIncludeAttributes(inputData: ICreateActionContext, IGeneric>): boolean {\r\n if (inputData && inputData.config && inputData.config.includeAttributes !== undefined && inputData.config.includeAttributes === true) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Get updateRefinerPanel from config.\r\n * @param inputData - ICreateActionContext.\r\n * @returns Boolean.\r\n */\r\nfunction getUpdateRefinerPanel(inputData: ICreateActionContext, IGeneric>): boolean {\r\n return !!inputData.config?.updateRefinerPanel;\r\n}\r\n\r\n/**\r\n * BaseCollection Action Input.\r\n */\r\nexport class BaseCollectionInput implements IActionInput {\r\n public pageType: listPageType;\r\n\r\n public category: number | undefined;\r\n\r\n public searchText: string | undefined;\r\n\r\n public refiners: ProductRefinerValue[];\r\n\r\n public queryResultSettings: IQueryResultSettings;\r\n\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n public includeAttributes: boolean | undefined;\r\n\r\n public locale?: string;\r\n\r\n public isUpdateRefinerPanel?: boolean;\r\n\r\n public catalogId?: number;\r\n\r\n public channelInventoryConfiguration?: ChannelInventoryConfiguration;\r\n\r\n public inventoryRefiner?: IProductRefinerHierarchy;\r\n\r\n public constructor(\r\n pageType: listPageType,\r\n apiSettings: ICommerceApiSettings,\r\n queryResultSettings: IQueryResultSettings,\r\n refiners: ProductRefinerValue[],\r\n category: number | undefined,\r\n searchText: string | undefined,\r\n includeAttributes: boolean | undefined,\r\n isUpdateRefinerPanel?: boolean | undefined,\r\n locale?: string,\r\n catalogId?: number,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration,\r\n inventoryRefiner?: IProductRefinerHierarchy\r\n ) {\r\n this.pageType = pageType;\r\n this.apiSettings = apiSettings;\r\n this.category = category;\r\n this.searchText = searchText;\r\n this.queryResultSettings = queryResultSettings;\r\n this.refiners = refiners;\r\n this.includeAttributes = includeAttributes;\r\n this.isUpdateRefinerPanel = isUpdateRefinerPanel;\r\n this.locale = locale;\r\n this.catalogId = catalogId ?? 0;\r\n this.channelInventoryConfiguration = channelInventoryConfiguration;\r\n this.inventoryRefiner = inventoryRefiner;\r\n }\r\n\r\n public getCacheKey = () => {\r\n const queryResultSettings = {\r\n ...this.queryResultSettings.Paging,\r\n ...toJS(this.queryResultSettings.Sorting)\r\n };\r\n\r\n const cacheKey = generateCacheKey(\r\n this.apiSettings,\r\n { key: 'PageType', value: this.pageType },\r\n { key: 'Category', value: this.category },\r\n { key: 'SearchText', value: this.searchText },\r\n { key: 'CatalogId', value: this.catalogId },\r\n {\r\n key: 'Refiners',\r\n value: this.refiners.map(\r\n refiner =>\r\n `RefinerRecordId:${refiner.RefinerRecordId}-LeftValueBoundString:${refiner.LeftValueBoundString ||\r\n ''}-RightValueBoundString:${refiner.RightValueBoundString || ''}`\r\n )\r\n },\r\n { key: 'QueryResultSettings', value: convertToString(queryResultSettings) },\r\n { key: 'Locale', value: this.locale }\r\n );\r\n return cacheKey;\r\n };\r\n\r\n public getCacheObjectType = () => 'CollectionActionResult';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n// TODO: Create a data model here or import one to capture the response of the action\r\nexport interface IGetFullProductsByCollectionData {\r\n text: string;\r\n}\r\n\r\nexport type CollectionClassConstructor = new (\r\n pageType: listPageType,\r\n apiSettings: ICommerceApiSettings,\r\n queryResultSettings: IQueryResultSettings,\r\n refiners: ProductRefinerValue[],\r\n category: number | undefined,\r\n searchText: string | undefined,\r\n includeAttributes: boolean | undefined,\r\n isUpdateRefinerPanel?: boolean | undefined,\r\n locale?: string,\r\n catalogId?: number,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration,\r\n inventoryRefiner?: IProductRefinerHierarchy\r\n) => BaseCollectionInput;\r\n\r\n/**\r\n * TODO: Use this function to create the input required to make the action call.\r\n * @param args\r\n * @param inputClassConstuctor\r\n */\r\nexport const createBaseCollectionInput = (\r\n args: ICreateActionContext,\r\n inputClassConstuctor: CollectionClassConstructor\r\n): BaseCollectionInput => {\r\n const pageType =\r\n args.requestContext.urlTokens.pageType === 'Category' || (args.requestContext.query && args.requestContext.query.categoryId)\r\n ? 'Category'\r\n : 'Search';\r\n\r\n const queryResultSettings = QueryResultSettingsProxy.fromInputData(args).QueryResultSettings;\r\n const queryRefiners = hydrateRefinersFromUrl(args.requestContext);\r\n const includeAttributes = getIncludeAttributes(args);\r\n const isUpdateRefinerPanel = getUpdateRefinerPanel(args);\r\n const catalogId = getCatalogId(args.requestContext);\r\n\r\n if (args.requestContext.query && args.requestContext.query.sorting) {\r\n queryResultSettings.Sorting = { Columns: JSON.parse(decodeURIComponent(args.requestContext.query.sorting)) };\r\n }\r\n\r\n if (pageType === 'Category') {\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n +(args.requestContext.urlTokens.itemId || (args.requestContext.query && args.requestContext.query.categoryId) || 0),\r\n args.requestContext.query?.q,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.q && !args.requestContext.query.recommendation) {\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n undefined,\r\n args.requestContext.query.q,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.recommendation) {\r\n let searchText = '';\r\n if (args.requestContext.query.productId) {\r\n searchText = JSON.stringify({\r\n ProductId: args.requestContext.query.productId,\r\n Recommendation: args.requestContext.query.recommendation,\r\n SearchText: args.requestContext.query.q\r\n });\r\n } else {\r\n searchText = JSON.stringify({ Recommendation: args.requestContext.query.recommendation, SearchText: args.requestContext.query.q });\r\n }\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n undefined,\r\n searchText,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n }\r\n\r\n throw new Error('[getFullProductsForCollection]Unable to create input');\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 { CacheType, createObservableDataAction, getCatalogId, IAction, IActionContext, IActionInput } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResult, ProjectionDomain } from '@msdyn365-commerce/retail-proxy';\r\nimport { ArrayExtensions, QueryResultSettingsProxy } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ProductSearchResultExt } from '../components';\r\nimport { getActivePricesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getDiscountBadge } from '../../../shared-utils/badge-utils';\r\n\r\n/**\r\n * Input class for the GetCachedPriceForProductSearchResult Data Action.\r\n */\r\nexport class CachedPriceForProductSearchResultInput implements IActionInput {\r\n public products: ProductSearchResultExt[];\r\n\r\n public constructor(products: ProductSearchResult[] | ProductSearchResultExt[]) {\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 => `CachedPriceForProductSearchResult-${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 GetCachedPriceForProductSearchResultDataAction.\r\n * @param products -- The product search result.\r\n * @returns The input.\r\n */\r\nexport const createCachedActivePriceForProductSearchResultInput = (products: ProductSearchResult[] | ProductSearchResultExt[]): CachedPriceForProductSearchResultInput => {\r\n return new CachedPriceForProductSearchResultInput(products);\r\n};\r\n\r\n/**\r\n * The Action Method for the GetCachedPriceForProductSearchResult 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 getCachedPriceForProductSearchResultAction(\r\n input: CachedPriceForProductSearchResultInput,\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 } 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 try {\r\n const productPrices = await getActivePricesAsync({ callerContext: context, queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context) },\r\n projectDomain,\r\n productRecIds,\r\n new Date(),\r\n null,\r\n null,\r\n true,\r\n false,\r\n false);\r\n\r\n const productResults = input.products.map(product => {\r\n const activePrice = productPrices.find(price => price.ProductId === product.RecordId);\r\n if (activePrice) {\r\n product.Badge = getDiscountBadge(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 product.PrefetchedPrice = true;\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 context.telemetry.exception(error);\r\n context.telemetry.debug('[getCachedPriceForProductSearchResultAction]Error executing action');\r\n throw new Error('[getCachedPriceForProductSearchResultAction]Error executing action');\r\n }\r\n}\r\n\r\n/**\r\n * The getPriceForProductSearchResult data action.\r\n */\r\nexport const getCachedPriceForProductSearchResultDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-cached-price-for-product-search-result',\r\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- existing pattern.\r\n action: >getCachedPriceForProductSearchResultAction,\r\n input: createCachedActivePriceForProductSearchResultInput\r\n});\r\n\r\nexport default getCachedPriceForProductSearchResultDataAction;\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 {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { AsyncResult, ChannelInventoryConfiguration, ProductSearchCriteria, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getInventoryConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport {\r\n ArrayExtensions,\r\n generateProductImageUrl,\r\n InventoryLevels\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport { getInventorySortableRefinerValue } from '.';\r\nimport { addAlcoholRefiner as addAlcoholRefinerAsync, addAllAttributeRefiners, addOrUpdateZeroPriceRefiner, shouldFilterAlcohol } from './refiner-utils';\r\nimport getCachedPriceForProductSearchResultDataAction, { CachedPriceForProductSearchResultInput } from './get-cached-price-for-product-search-results';\r\nimport { ProductSearchResultExt } from '../components';\r\n\r\n/**\r\n * GetFullProductsByCollection Action Input.\r\n */\r\nexport class GetFullProductsByCollectionInput extends BaseCollectionInput implements IActionInput {\r\n /**\r\n * The cache object type.\r\n * @returns The cache object type.\r\n */\r\n public getCacheObjectType = (): string => 'FullProductSearchResult';\r\n\r\n /**\r\n * The data cache type.\r\n * @returns The data cache type.\r\n */\r\n public dataCacheType = (): CacheType => {\r\n // return 'none';\r\n if (\r\n this.pageType !== 'Category' ||\r\n (this.refiners && this.refiners.length > 0) ||\r\n (this.queryResultSettings &&\r\n this.queryResultSettings.Sorting &&\r\n this.queryResultSettings.Sorting.Columns &&\r\n this.queryResultSettings.Sorting.Columns.length > 0)\r\n ) {\r\n return 'request';\r\n }\r\n return 'application';\r\n };\r\n}\r\n\r\n/**\r\n * This setting defines inventory filtering options.\r\n */\r\nexport enum ProductListInventoryFilteringOptions {\r\n /**\r\n * Filter out all products out of stock.\r\n */\r\n HideOOS = 'hideOOS',\r\n\r\n /**\r\n * Sort products by availability, OOS goes last.\r\n */\r\n SortOOS = 'sortOOS',\r\n\r\n /**\r\n * No filtering selected.\r\n */\r\n Default = 'default'\r\n}\r\n\r\n/**\r\n * The full product search result with count interface.\r\n */\r\nexport interface IFullProductsSearchResultsWithCount {\r\n products: ProductSearchResultExt[];\r\n count: number;\r\n channelInventoryConfigurationId?: number;\r\n inventoryAwareSortableAttributeId?: number;\r\n}\r\n\r\n/**\r\n * CreateInput function which creates and actionInput used to fetch products for a list page.\r\n * @param args - The API arguments.\r\n * @returns IActionInput - The action input.\r\n */\r\nconst createInput = (args: ICreateActionContext<{ itemsPerPage: number; includedAttributes: boolean | undefined }>): IActionInput => {\r\n const input = createBaseCollectionInput(args, GetFullProductsByCollectionInput);\r\n\r\n // Set Top\r\n if (input.queryResultSettings.Paging && args.config) {\r\n input.queryResultSettings.Paging.Top = args.config.itemsPerPage || 1;\r\n }\r\n\r\n // Set Skip\r\n if (input.queryResultSettings.Paging && args.requestContext.query && args.requestContext.query.skip) {\r\n input.queryResultSettings.Paging.Skip = +args.requestContext.query.skip;\r\n }\r\n\r\n input.queryResultSettings.count = true;\r\n\r\n return input;\r\n};\r\n\r\n/**\r\n * Returns list of products based on inventory information.\r\n * @param productSearchResults - The products.\r\n * @param context - The context.\r\n * @param metadataCount - The metadata count.\r\n * @param channelInventoryConfiguration - The channel inventory configuration.\r\n * @returns List of product based on the inventory information.\r\n */\r\nexport async function returnProducts(\r\n productSearchResults: ProductSearchResult[],\r\n context: IActionContext,\r\n metadataCount: number | undefined,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration\r\n): Promise {\r\n const defaultProductCount: number = 0;\r\n\r\n const productSearchResultsWithImages = productSearchResults.map(productSearchResult => {\r\n const newImageUrl = generateProductImageUrl(productSearchResult, context.requestContext.apiSettings);\r\n\r\n if (newImageUrl) {\r\n productSearchResult.PrimaryImageUrl = newImageUrl;\r\n }\r\n\r\n return productSearchResult;\r\n });\r\n\r\n // If inventory level is threshold or inventory check is disabled then return the list of products without the inventory configuration\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\r\n if (\r\n context.requestContext.app.config.inventoryLevel === InventoryLevels.threshold ||\r\n context.requestContext.app.config.enableStockCheck === false\r\n ) {\r\n return {\r\n products: productSearchResultsWithImages,\r\n count: metadataCount ?? defaultProductCount\r\n };\r\n }\r\n\r\n const mappedProducts = productSearchResultsWithImages.map(productSearchResult => {\r\n if (ArrayExtensions.hasElements(productSearchResult.AttributeValues)) {\r\n for (const element of productSearchResult.AttributeValues) {\r\n if (\r\n channelInventoryConfiguration &&\r\n element.RecordId !== undefined &&\r\n element.RecordId === channelInventoryConfiguration.InventoryProductAttributeRecordId &&\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\r\n context.requestContext.app.config.inventoryRanges !== 'all' &&\r\n element.TextValue !== channelInventoryConfiguration.InventoryOutOfStockAttributeValueText\r\n ) {\r\n // If same RecordId then it means that is the Inventory attribute\r\n // Based on the inventory range (and filtering options), the inventory label will be displayed\r\n // If Inventory range is 'All' then in stock and out of stock labels are shown, else only OOS\r\n // if the text value is different that the channelInventoryConfiguration.InventoryOutOfStockAttributeValueText then is in stock\r\n element.TextValue = '';\r\n }\r\n }\r\n }\r\n\r\n return productSearchResult;\r\n });\r\n\r\n return {\r\n products: mappedProducts,\r\n count: metadataCount ?? defaultProductCount,\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- check config.\r\n channelInventoryConfigurationId: channelInventoryConfiguration\r\n ? channelInventoryConfiguration.InventoryProductAttributeRecordId\r\n : undefined,\r\n inventoryAwareSortableAttributeId: channelInventoryConfiguration\r\n ? channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId\r\n : undefined\r\n };\r\n}\r\n\r\n/**\r\n * Action function to fetch products for a list page.\r\n * @param input - The input.\r\n * @param context - The context.\r\n * @returns IFullProductsSearchResultsWithCount - The full product search result with count.\r\n */\r\n// eslint-disable-next-line complexity -- ignore the complexity.\r\nasync function action(input: GetFullProductsByCollectionInput, context: IActionContext): Promise {\r\n let promise: AsyncResult;\r\n let channelInventoryConfigurationPromise: AsyncResult;\r\n let searchProductId;\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: context.requestContext.apiSettings.channelId, CatalogId: input.catalogId };\r\n // Decouple searchCriteriaInput.Refinement from input.refiners to avoid input.refiners being modified below\r\n searchCriteriaInput.Refinement = JSON.parse(JSON.stringify(input.refiners.slice()));\r\n searchCriteriaInput.IncludeAttributes = input.includeAttributes;\r\n searchCriteriaInput.SkipVariantExpansion = true;\r\n searchCriteriaInput.SearchCondition = input.searchText;\r\n const defaultNumber: number = 0;\r\n\r\n // Fix mobx arrays that got turned to objects\r\n for (let index = 0; index < searchCriteriaInput.Refinement!.length; index++) {\r\n const element = searchCriteriaInput.Refinement![index];\r\n\r\n if (element.ExtensionProperties && typeof element.ExtensionProperties === 'object') {\r\n element.ExtensionProperties = JSON.parse(JSON.stringify(input.refiners[index].ExtensionProperties?.slice()));\r\n }\r\n }\r\n\r\n searchCriteriaInput.Refinement = addOrUpdateZeroPriceRefiner(context, searchCriteriaInput.Refinement);\r\n\r\n if (shouldFilterAlcohol(context)) {\r\n await addAlcoholRefinerAsync(context, searchCriteriaInput);\r\n }\r\n\r\n await addAllAttributeRefiners(context, searchCriteriaInput);\r\n\r\n if (input.channelInventoryConfiguration) {\r\n channelInventoryConfigurationPromise = AsyncResult.resolve(input.channelInventoryConfiguration);\r\n } else {\r\n channelInventoryConfigurationPromise = getInventoryConfigurationAsync({ callerContext: context });\r\n }\r\n const channelInventoryConfiguration = await channelInventoryConfigurationPromise;\r\n\r\n // Replace InventoryProductAttribute with boolean refiner.\r\n // Because the value of InventoryProductAttribute is different from language to language since it's string type.\r\n // The cached old inventory refiner value may be hit when customer switch language which will lead to \"no products found\" issue.\r\n const inventoryRefiner = searchCriteriaInput.Refinement.find(\r\n refiner => refiner.RefinerRecordId === channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n if (inventoryRefiner) {\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement.filter(\r\n refiner => refiner.RefinerRecordId !== channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n\r\n const isInStockRefiner =\r\n inventoryRefiner.LeftValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText &&\r\n inventoryRefiner.RightValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText;\r\n const inventoryRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStockRefiner);\r\n\r\n const isInventoryRefinerValueExist = searchCriteriaInput.Refinement.some(\r\n refiner => refiner.RefinerRecordId === inventoryRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryRefinerValueExist && inventoryRefinerValue) {\r\n searchCriteriaInput.Refinement.push(inventoryRefinerValue);\r\n }\r\n }\r\n\r\n if (context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n const isInStock = true;\r\n const inventoryInStockRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStock);\r\n\r\n const isInventoryInStockRefinerValueExist = searchCriteriaInput.Refinement.some(\r\n refiner => refiner.RefinerRecordId === inventoryInStockRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryInStockRefinerValueExist && inventoryInStockRefinerValue) {\r\n searchCriteriaInput.Refinement.push(inventoryInStockRefinerValue);\r\n }\r\n }\r\n\r\n if (context.requestContext.app.config?.prioritySortingAttribute) {\r\n const prioritySortingAttribute = context.requestContext.app.config.prioritySortingAttribute as string;\r\n\r\n // Check if the priority sorting attribute only has digits. If not skip this\r\n if (prioritySortingAttribute.match(/^\\d+$/)) {\r\n input.queryResultSettings.Sorting = input.queryResultSettings.Sorting ?? {};\r\n input.queryResultSettings.Sorting.Columns = input.queryResultSettings.Sorting.Columns ?? [];\r\n const priorityColumnName = `Attr_${prioritySortingAttribute}`;\r\n const isPriorityAttributeExist = input.queryResultSettings.Sorting.Columns.some(column => column.ColumnName === priorityColumnName);\r\n if (!isPriorityAttributeExist) {\r\n input.queryResultSettings.Sorting.Columns.push({\r\n ColumnName: priorityColumnName,\r\n IsDescending: true\r\n });\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- app configs are of generic type\r\n if (\r\n context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.SortOOS &&\r\n channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId\r\n ) {\r\n input.queryResultSettings.Sorting = input.queryResultSettings.Sorting ?? {};\r\n input.queryResultSettings.Sorting.Columns = input.queryResultSettings.Sorting.Columns ?? [];\r\n const sortColumnName = `Attr_${channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId}`;\r\n const isSortAttributeExist = input.queryResultSettings.Sorting.Columns.some(column => column.ColumnName === sortColumnName);\r\n if (!isSortAttributeExist) {\r\n input.queryResultSettings.Sorting.Columns.push({\r\n ColumnName: sortColumnName,\r\n IsDescending: true\r\n });\r\n }\r\n }\r\n\r\n if (input.pageType === 'Category' || context.requestContext.query?.categoryId) {\r\n if (input.category) {\r\n searchCriteriaInput.CategoryIds = [input.category || defaultNumber];\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Category Page Detected, but no global categoryId found');\r\n }\r\n } else if (input.searchText && context.requestContext.query?.q && !context.requestContext.query.recommendation) {\r\n searchCriteriaInput.SearchCondition = input.searchText;\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n } else if (input.searchText && context.requestContext.query && context.requestContext.query.recommendation) {\r\n const searchObject = JSON.parse(input.searchText);\r\n if (context.requestContext.query.productId) {\r\n searchProductId = Number(searchObject.ProductId);\r\n }\r\n if (Number.isNaN(searchProductId)) {\r\n throw new Error('Failed to cast search product id into a number.');\r\n } else if (\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Existing code\r\n !searchObject.Recommendation\r\n ) {\r\n throw new Error('Failed to retrieve the Recommendation.');\r\n } else {\r\n searchCriteriaInput.SearchCondition = searchObject.SearchText;\r\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\r\n if (searchProductId) {\r\n searchCriteriaInput.Ids = [searchProductId || defaultNumber];\r\n }\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n }\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found');\r\n }\r\n\r\n let productSearchResults = await promise as ProductSearchResultExt[];\r\n\r\n // Reset non-active prices\r\n productSearchResults.forEach(x => {\r\n x.Price = 0;\r\n x.BasePrice = 0;\r\n x.MaxVariantPrice = 0;\r\n x.MinVariantPrice = 0;\r\n x.PrefetchedPrice = false;\r\n });\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n try {\r\n const input = new CachedPriceForProductSearchResultInput(productSearchResults);\r\n const cached = await getCachedPriceForProductSearchResultDataAction(input, context);\r\n productSearchResults = cached;\r\n } catch (error) {\r\n // Do nothing, error is already logged in above function\r\n }\r\n }\r\n\r\n return returnProducts(productSearchResults, context, promise.metadata.count, channelInventoryConfiguration);\r\n}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-full-products-by-collection',\r\n action: action as IAction,\r\n input: createInput\r\n});\r\n\r\nexport default actionDataAction;\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 {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { SortColumn } from '@msdyn365-commerce/retail-proxy';\r\nimport { getSearchConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n// TODO: import from commerce entities when available\r\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Name change will require many modifications\r\ninterface SearchConfiguration {\r\n ProductSortColumns?: SortColumn[];\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Name change will require many modifications\r\nexport interface MappedSearchConfiguration {\r\n key: string;\r\n sortColumn: SortColumn;\r\n}\r\n\r\nexport const sortOptions = {\r\n sortByOptionRelevanceDesc: 'Ranking-Desc',\r\n sortByOptionRatingAsc: 'AverageRating-Asc',\r\n sortByOptionRatingDesc: 'AverageRating-Desc',\r\n sortByOptionNameAsc: 'Name-Asc',\r\n sortByOptionNameDesc: 'Name-Desc',\r\n sortByOptionPriceAsc: 'Price-Asc',\r\n sortByOptionPriceDesc: 'Price-Desc',\r\n sortByOptionBestSelling: 'BestSelling',\r\n sortByOptionNewScore: 'NewScore',\r\n sortByOptionTrendingScore: 'TrendingScore'\r\n};\r\n\r\n/**\r\n * ActionInput class for the get-mapped-search-configuration Data Action.\r\n */\r\nexport class MappedSearchInput implements IActionInput {\r\n private readonly apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings) {\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey('MappedSearchInput', this.apiSettings);\r\n\r\n public getCacheObjectType = () => 'MappedSearchInput';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n/**\r\n * Get a mapped search configuration that is easy to use for sorting.\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getMappedSearchConfiguration(input: MappedSearchInput, ctx: IActionContext): Promise {\r\n return getSearchConfigurationAsync({ callerContext: ctx }).then((searchConfiguration: SearchConfiguration) => {\r\n return (searchConfiguration.ProductSortColumns || [])\r\n .map((sortColumn: SortColumn) => {\r\n let key = '';\r\n if (sortColumn.ColumnName) {\r\n switch (sortColumn.ColumnName.toUpperCase()) {\r\n case 'NAME':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionNameDesc : sortOptions.sortByOptionNameAsc;\r\n break;\r\n case 'PRICE':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionPriceDesc : sortOptions.sortByOptionPriceAsc;\r\n break;\r\n case 'AVERAGERATING':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionRatingDesc : sortOptions.sortByOptionRatingAsc;\r\n break;\r\n case 'RANKING':\r\n key = sortOptions.sortByOptionRelevanceDesc;\r\n break;\r\n case 'BESTSELLINGSCORE':\r\n key = sortOptions.sortByOptionBestSelling;\r\n break;\r\n case 'NEWSCORE':\r\n key = sortOptions.sortByOptionNewScore;\r\n break;\r\n case 'TRENDINGSCORE':\r\n key = sortOptions.sortByOptionTrendingScore;\r\n break;\r\n default:\r\n }\r\n } else {\r\n ctx.telemetry.warning('[get-mapped-search-configuration] unknown search option');\r\n }\r\n if (key) {\r\n return {\r\n key,\r\n sortColumn\r\n };\r\n }\r\n return undefined;\r\n })\r\n .filter(Boolean);\r\n });\r\n}\r\n\r\nexport const createInput = (inputData: ICreateActionContext>): IActionInput => {\r\n return new MappedSearchInput(inputData.requestContext.apiSettings);\r\n};\r\n\r\nexport const getMappedSearchConfigurationDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-mapped-search-configuration',\r\n action: >getMappedSearchConfiguration,\r\n input: createInput\r\n});\r\n\r\nexport default getMappedSearchConfigurationDataAction;\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, ICreateActionContext } from '@msdyn365-commerce/core';\r\nimport { AsyncResult, ChannelInventoryConfiguration, ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { getInventoryConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\n\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\r\nimport { getInventorySortableRefinerValue, ProductListInventoryFilteringOptions } from '.';\r\nimport { addOrUpdateZeroPriceRefiner, getAlcoholRefiners, getAllAttributeRefiners, shouldFilterAlcohol } from './refiner-utils';\r\n\r\n/**\r\n * Default Category/Product Id Values.\r\n */\r\nenum DefaultValues {\r\n defaultCategoryIdValue = 0,\r\n defaultProductIdValue = 0\r\n}\r\n\r\n/**\r\n * Refiners-by-Collection Input action.\r\n */\r\nexport class RefinersByCollectionInput extends BaseCollectionInput implements IActionInput {\r\n public getCacheObjectType = () => 'ProductRefiner';\r\n\r\n public dataCacheType = () => {\r\n return 'none';\r\n // @ts-ignore\r\n if (\r\n this.pageType !== 'Category' ||\r\n (this.refiners && this.refiners.length > 0) ||\r\n (this.queryResultSettings &&\r\n this.queryResultSettings.Sorting &&\r\n this.queryResultSettings.Sorting!.Columns &&\r\n this.queryResultSettings.Sorting!.Columns!.length > 0)\r\n ) {\r\n return 'request';\r\n }\r\n return 'application';\r\n };\r\n}\r\n\r\n/**\r\n * Create input method which creates an ActionInput for fetching list page refiners.\r\n * @param args\r\n */\r\nconst createInput = (args: ICreateActionContext): IActionInput => {\r\n return createBaseCollectionInput(args, RefinersByCollectionInput);\r\n};\r\n\r\n/**\r\n * Action method which fetches refiners for the given list page.\r\n * @param input\r\n * @param context\r\n */\r\nexport async function getRefinersForCollectionDataAction(input: RefinersByCollectionInput, context: IActionContext): Promise {\r\n let searchProductId;\r\n // Decouple refiners from input.refiners to avoid input.refiners being modified below\r\n let refiners: ProductRefinerValue[] = [...input.refiners] || [];\r\n\r\n let channelInventoryConfigurationPromise: AsyncResult;\r\n if (input.channelInventoryConfiguration) {\r\n channelInventoryConfigurationPromise = AsyncResult.resolve(input.channelInventoryConfiguration);\r\n } else {\r\n channelInventoryConfigurationPromise = getInventoryConfigurationAsync({ callerContext: context });\r\n }\r\n const channelInventoryConfiguration = await channelInventoryConfigurationPromise;\r\n\r\n // Replace InventoryProductAttribute with boolean refiner.\r\n // Because the value of InventoryProductAttribute is different from language to language since it's string type.\r\n // The cached old inventory refiner value may be hit when customer switch language which will lead to \"no products found\" issue.\r\n const inventoryRefiner = refiners.find(\r\n refiner => refiner.RefinerRecordId === channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n if (inventoryRefiner) {\r\n refiners = refiners.filter(refiner => refiner.RefinerRecordId !== channelInventoryConfiguration?.InventoryProductAttributeRecordId);\r\n\r\n const isInStockRefiner =\r\n inventoryRefiner.LeftValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText &&\r\n inventoryRefiner.RightValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText;\r\n const inventoryRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStockRefiner);\r\n\r\n const isInventoryRefinerValueExist = refiners.some(refiner => refiner.RefinerRecordId === inventoryRefinerValue?.RefinerRecordId);\r\n if (!isInventoryRefinerValueExist && inventoryRefinerValue) {\r\n refiners.push(inventoryRefinerValue);\r\n }\r\n }\r\n\r\n if (context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n const isInStock = true;\r\n const inventoryInStockRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStock);\r\n\r\n const isInventoryInStockRefinerValueExist = refiners.some(\r\n refiner => refiner.RefinerRecordId === inventoryInStockRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryInStockRefinerValueExist && inventoryInStockRefinerValue) {\r\n refiners.push(inventoryInStockRefinerValue);\r\n }\r\n }\r\n\r\n const alcoholFilter = shouldFilterAlcohol(context);\r\n const attributeRefiners = await getAllAttributeRefiners(context);\r\n\r\n // Either 'refiners' or 'defaultRefiners' will be used on 'isUpdateRefinerPanel'. But either way it should always\r\n // contain the zero price filter and alcohol refiner.\r\n refiners = addOrUpdateZeroPriceRefiner(context, refiners)\r\n .concat(alcoholFilter ? await getAlcoholRefiners(context) : [])\r\n .concat(attributeRefiners);\r\n const defaultRefiners = addOrUpdateZeroPriceRefiner(context)\r\n .concat(alcoholFilter ? await getAlcoholRefiners(context) : [])\r\n .concat(attributeRefiners);\r\n\r\n if (input.pageType === 'Category') {\r\n if (input.category) {\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n return getProductRefinerHierarchy(\r\n {\r\n CategoryIds: [input.category || DefaultValues.defaultCategoryIdValue],\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? refiners : defaultRefiners,\r\n SearchCondition: input.searchText\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n }\r\n throw new Error('[GetRefinersForCollection]Category Page Detected, but no global categoryId found');\r\n } else {\r\n if (input.searchText && context.requestContext.query && context.requestContext.query.q && !context.requestContext.query.recommendation) {\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n return getProductRefinerHierarchy(\r\n {\r\n SearchCondition: input.searchText,\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? refiners : defaultRefiners\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n }\r\n if (input.searchText && context.requestContext.query && context.requestContext.query.recommendation) {\r\n const searchObject = JSON.parse(input.searchText);\r\n if (context.requestContext.query.productId) {\r\n searchProductId = Number(searchObject.ProductId);\r\n }\r\n if (Number.isNaN(searchProductId)) {\r\n throw new Error('Failed to cast search product id into a number.');\r\n } else if (!searchObject.Recommendation) {\r\n throw new Error('Failed to retrieve the Recommendation.');\r\n } else {\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n searchCriteriaInput.Context = {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n };\r\n searchCriteriaInput.SearchCondition = searchObject.SearchText;\r\n searchCriteriaInput.Refinement = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\r\n if (searchProductId) {\r\n searchCriteriaInput.Ids = [searchProductId || DefaultValues.defaultProductIdValue];\r\n }\r\n return getProductRefinerHierarchy(searchCriteriaInput, input.queryResultSettings, context);\r\n }\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found');\r\n }\r\n }\r\n}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-refiners-for-collection',\r\n action: >getRefinersForCollectionDataAction,\r\n input: createInput\r\n});\r\n\r\nexport default actionDataAction;\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { CacheType, createObservableDataAction, IAction, IActionContext, IActionInput } from '@msdyn365-commerce/core';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport {\r\n AttributeDataType,\r\n ChannelInventoryConfiguration,\r\n ProductRefinerSource,\r\n ProductRefinerValue\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { BaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\r\n\r\n/**\r\n * Returns inventory in stock sortable refiner value.\r\n * @param channelInventoryConfiguration - The channelInventoryConfiguration.\r\n * @param isInStock - The flag indicating whether is getting in-stock refiner or out-of-stock refiner.\r\n * @returns Refiners.\r\n */\r\nexport const getInventorySortableRefinerValue = (\r\n channelInventoryConfiguration: ChannelInventoryConfiguration,\r\n isInStock: boolean\r\n): ProductRefinerValue | undefined => {\r\n if (channelInventoryConfiguration && channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId) {\r\n return {\r\n RefinerRecordId: channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId,\r\n DataTypeValue: AttributeDataType.TrueFalse,\r\n LeftValueBoundString: isInStock ? 'true' : 'false',\r\n RightValueBoundString: isInStock ? 'true' : 'false',\r\n UnitText: '',\r\n RowNumber: 0,\r\n Count: 0,\r\n ExtensionProperties: [],\r\n RefinerSourceValue: ProductRefinerSource.Attribute\r\n };\r\n }\r\n return undefined;\r\n};\r\n\r\n/**\r\n * InventoryInStockRefinerValue Input action.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nexport class InventoryInStockRefinerValueInput extends BaseCollectionInput implements IActionInput {\r\n public inventoryProductAttributeRecordId: number;\r\n\r\n public constructor(input: BaseCollectionInput, inventoryProductAttributeRecordId: number = 0) {\r\n super(\r\n input.pageType,\r\n input.apiSettings,\r\n {\r\n count: true\r\n },\r\n\r\n // Parameter - refiners\r\n [],\r\n\r\n // Parameter - category\r\n undefined,\r\n\r\n // Parameter - searchText\r\n '',\r\n\r\n // Parameter - includeAttributes\r\n false,\r\n\r\n // Parameter - isUpdateRefinerPanel\r\n false,\r\n\r\n // Parameter - locale\r\n undefined,\r\n input.catalogId,\r\n input.channelInventoryConfiguration,\r\n input.inventoryRefiner\r\n );\r\n\r\n this.inventoryProductAttributeRecordId =\r\n inventoryProductAttributeRecordId || input.channelInventoryConfiguration?.InventoryProductAttributeRecordId || 0;\r\n }\r\n\r\n /**\r\n * GetCacheKey.\r\n * @returns - Returns string.\r\n */\r\n public getCacheKey = (): string => buildCacheKey('RefinerList', this.apiSettings);\r\n\r\n /**\r\n * GetCacheObjectType.\r\n * @returns - Returns string.\r\n */\r\n public getCacheObjectType = (): string => 'RefinerList';\r\n\r\n /**\r\n * DataCacheType.\r\n * @returns - CacheType string.\r\n */\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * Action method returns inventory in stock refiners.\r\n * @param input - InventoryInStockRefinerValueInput.\r\n * @param context - IActionContext.\r\n * @returns - Promise.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nasync function action(input: InventoryInStockRefinerValueInput, context: IActionContext): Promise {\r\n const refiners = await getProductRefinerHierarchy(\r\n {\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n }\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n\r\n // InventoryProductAttributeRecordId may be 0, and recId of default refiner Category/Price/Rating is always 0 by design. In this case, we should not return refiner\r\n // Why recId of default refiner Category/Price/Rating is 0: see GetChannelProductRefiners.sql\r\n return (\r\n (input.channelInventoryConfiguration?.InventoryProductAttributeRecordId !== 0 &&\r\n refiners.find(refiner => refiner.RecordId === input.channelInventoryConfiguration?.InventoryProductAttributeRecordId)) ||\r\n // keep legacy logic to avoid break existing customers usage from this file\r\n (input.inventoryProductAttributeRecordId !== 0 &&\r\n refiners.find(refiner => refiner.RecordId === input.inventoryProductAttributeRecordId)) ||\r\n null\r\n );\r\n}\r\n\r\n/**\r\n * Action.\r\n * @param id - Id.\r\n * @param action - Action.\r\n * @returns - Results.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-inventory-refiners',\r\n action: action as IAction\r\n});\r\n\r\nexport default actionDataAction;\r\n","import { IActionContext } from '@msdyn365-commerce/core';\r\nimport { AttributeDataType, CustomerAttribute, ProductRefinerSource, ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\n// @ts-ignore\r\nimport { getCustomer, GetCustomerInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport getOrganizationCustomer, { GetOrganizationCustomerInput } from '../../../actions/get-organization-customer';\r\n\r\n// Pre populated with ids from STAGE for local development\r\nconst AlcoholGroupAttributeId = 5637155076;\r\n\r\nfunction isGodmodeEnabled(context: IActionContext): boolean {\r\n const godmode = context.requestContext.url.requestUrl.searchParams.get('godmode')?.toLowerCase();\r\n\r\n return godmode === '1' || godmode === 'true';\r\n}\r\n\r\nexport function shouldFilterAlcohol(context: IActionContext): boolean {\r\n const doAlcoholFiltering = context.requestContext.url.requestUrl.searchParams.get('alcohol')?.toLowerCase() !== 'false';\r\n const alcoholRefinerRecordId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n return doAlcoholFiltering && !isNaN(alcoholRefinerRecordId) && alcoholRefinerRecordId > 0;\r\n}\r\n\r\nexport async function getAlcoholRefiners(context: IActionContext): Promise {\r\n let alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n alcoholGroupAttributeId = AlcoholGroupAttributeId;\r\n }\r\n\r\n const result: ProductRefinerValue[] = [];\r\n const alcoholRefiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: alcoholGroupAttributeId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(alcoholRefiner);\r\n\r\n try {\r\n let alcoholLicenseValue = 0;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n // Get Customer attributes\r\n // const customer = await getCustomer(new GetCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber), context);\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber!), context);\r\n const alcoholLicense = Number(customer.Attributes?.find(x => x.RecordId === alcoholGroupAttributeId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(alcoholLicense)) {\r\n // Throw NaN error\r\n console.warn('Alcohol license value is missing or not a number.');\r\n } else {\r\n alcoholLicenseValue = alcoholLicense;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n alcoholLicenseValue = 3;\r\n }\r\n\r\n // TODO: Verify we can do ranges like this on text attributes\r\n // If we can do range on text attributes use this:\r\n //alcoholRefiner.RightValueBoundString = alcoholLicense?.AttributeValue?.StringValue ?? '0';\r\n\r\n // Add a refiner for each alcohol group\r\n Array(alcoholLicenseValue).fill(0).forEach((_, index) => {\r\n result.push({\r\n ...alcoholRefiner,\r\n LeftValueBoundString: (index + 1).toString(),\r\n RightValueBoundString: (index + 1).toString()\r\n });\r\n });\r\n } catch (error) {\r\n console.warn('Failed to get customer attributes for alcohol license or parse value of attribute. No alcohol license applied to search.', error);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport async function addAlcoholRefiner(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n let alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n alcoholGroupAttributeId = AlcoholGroupAttributeId;\r\n }\r\n\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === alcoholGroupAttributeId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== alcoholGroupAttributeId);\r\n }\r\n\r\n const refiners = await getAlcoholRefiners(context);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n\r\n return Promise.resolve();\r\n}\r\n\r\nexport function addOrUpdateZeroPriceRefiner(context: IActionContext, refiners?: ProductRefinerValue[]): ProductRefinerValue[] {\r\n // Check criteria for allowing user to see zero price products. Example:\r\n // - Has ?godmode=true in url\r\n const allowZeroPriceProducts = isGodmodeEnabled(context);\r\n\r\n if (!allowZeroPriceProducts) {\r\n const result = refiners ? [...refiners] : [];\r\n\r\n // Make sure we don't show zero price products\r\n const priceRefiner = result.find(x => x.RefinerRecordId === 0);\r\n\r\n if (priceRefiner) {\r\n // There is a price refiner, make sure it has a min value of 0.01 or more\r\n if (!priceRefiner.LeftValueBoundString || Number(priceRefiner.LeftValueBoundString) < 0.01) {\r\n priceRefiner.LeftValueBoundString = '0.01';\r\n }\r\n } else {\r\n // No price refiner, add one\r\n result.push({\r\n '@odata.type': '#Microsoft.Dynamics.Commerce.Runtime.DataModel.ProductRefinerValue',\r\n Count: 0,\r\n DataTypeValue: 1,\r\n LeftValueBoundString: '0.01',\r\n ExtensionProperties: [],\r\n RefinerRecordId: 0,\r\n RefinerSourceValue: 3,\r\n RightValueBoundString: '1000000000',\r\n RowNumber: 0,\r\n UnitText: context.requestContext.channel?.Currency\r\n } as any);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return refiners || [];\r\n}\r\n\r\nexport async function getAttributeRefiners(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, attributeRecordId: number, friendlyName?: string): Promise {\r\n const result: ProductRefinerValue[] = [];\r\n const refiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: attributeRecordId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(refiner);\r\n\r\n try {\r\n let attributeValue = 0;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const attribute = Number(customerAttributes?.find(x => x.RecordId === attributeRecordId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(attribute)) {\r\n // Throw NaN error\r\n if (friendlyName) {\r\n console.warn(`${friendlyName} attribute value is missing or not a number.`);\r\n } else {\r\n console.warn(`Attribute with record id ${attributeRecordId} is missing a value or not a number.`);\r\n }\r\n } else {\r\n attributeValue = attribute;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n attributeValue = 1;\r\n }\r\n\r\n if (attributeValue !== 0) {\r\n result.push({\r\n ...refiner,\r\n LeftValueBoundString: attributeValue.toString(),\r\n RightValueBoundString: attributeValue.toString()\r\n });\r\n }\r\n } catch (error) {\r\n if (friendlyName) {\r\n console.warn(`Failed to get ${friendlyName} customer attribute or parse value of attribute. No filter applied to search.`, error);\r\n } else {\r\n console.warn(`Failed to get customer attribute (record id: ${attributeRecordId}) or parse value of attribute. No filter applied to search.`, error);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport async function getForsvaretRefiner(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined): Promise {\r\n const forsvaretAttributeId = context.requestContext.app.config?.forsvaretAttributeRecordId;\r\n\r\n if (!forsvaretAttributeId || !context.requestContext.user.isAuthenticated) {\r\n return;\r\n }\r\n\r\n try {\r\n const attribute = customerAttributes?.find(x => x.RecordId === Number(forsvaretAttributeId))?.AttributeValue?.IntegerValue;\r\n\r\n if (!attribute || isNaN(attribute) || attribute === 0) {\r\n return;\r\n }\r\n\r\n return {\r\n DataTypeValue: AttributeDataType.Integer,\r\n LeftValueBoundString: attribute.toString(),\r\n RefinerRecordId: Number(forsvaretAttributeId),\r\n RefinerSourceValue: ProductRefinerSource.Attribute,\r\n RightValueBoundString: attribute.toString(),\r\n UnitText: ''\r\n };\r\n } catch (error) {\r\n console.error('Failed to get forsvaret attribute', error);\r\n return;\r\n }\r\n}\r\n\r\nexport async function addAttributeRefiner(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, searchCriteriaInput: ProductSearchCriteria, attributeRecordId: number): Promise {\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === attributeRecordId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== attributeRecordId);\r\n }\r\n\r\n const refiners = await getAttributeRefiners(context, customerAttributes, attributeRecordId);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n}\r\n\r\nexport async function addAttributeRefinerKeepExisting(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, searchCriteriaInput: ProductSearchCriteria, attributeRecordId: number): Promise {\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === attributeRecordId)) {\r\n return;\r\n }\r\n\r\n const refiners = await getAttributeRefiners(context, customerAttributes, attributeRecordId);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n}\r\n\r\nexport async function addAllAttributeRefiners(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return;\r\n }\r\n\r\n let customerAttributes: CustomerAttribute[] | undefined = [];\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n customerAttributes = customer.Attributes;\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.tobaccoRefinerRecordId,\r\n context.requestContext.app.config?.cocacolaRefinerRecordId,\r\n context.requestContext.app.config?.bamaRefinerRecordId,\r\n context.requestContext.app.config?.dutyFreeSugarRefinerRecordId,\r\n context.requestContext.app.config?.norturaRefinerRecordId\r\n ];\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n await addAttributeRefiner(context, customerAttributes, searchCriteriaInput, id);\r\n }\r\n }\r\n\r\n const transitRefiner = Number(context.requestContext.app.config?.transitRefinerRecordId);\r\n\r\n if (!isNaN(transitRefiner) && transitRefiner > 0) {\r\n await addAttributeRefinerKeepExisting(context, customerAttributes, searchCriteriaInput, transitRefiner);\r\n }\r\n\r\n const forsvaretRefiner = await getForsvaretRefiner(context, customerAttributes);\r\n\r\n if (forsvaretRefiner) {\r\n searchCriteriaInput.Refinement!.push(forsvaretRefiner);\r\n }\r\n}\r\n\r\nexport async function getAllAttributeRefiners(context: IActionContext) {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return [];\r\n }\r\n\r\n let customerAttributes: CustomerAttribute[] | undefined = [];\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n customerAttributes = customer.Attributes;\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.transitRefinerRecordId,\r\n context.requestContext.app.config?.tobaccoRefinerRecordId,\r\n context.requestContext.app.config?.cocacolaRefinerRecordId,\r\n context.requestContext.app.config?.bamaRefinerRecordId,\r\n context.requestContext.app.config?.dutyFreeSugarRefinerRecordId,\r\n context.requestContext.app.config?.norturaRefinerRecordId\r\n ];\r\n\r\n const result: ProductRefinerValue[] = [];\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n const refiners = await getAttributeRefiners(context, customerAttributes, id);\r\n result.push(...refiners);\r\n }\r\n }\r\n\r\n const forsvaretRefiner = await getForsvaretRefiner(context, customerAttributes);\r\n\r\n if (forsvaretRefiner) {\r\n result.push(forsvaretRefiner);\r\n }\r\n\r\n return result;\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 MsDyn365, { IRequestContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue, SortColumn } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * Refiner Compression:\r\n * Refiners contains a non-trivial amount of data that is required to successfully make\r\n * a refiner-based API call. To allow for deep-linking of refiners in the URL, refiner data\r\n * must be compressed so that URL max length is not exceeded. Refiners will be compressed into\r\n * the following array style index-based format:\r\n * [DataTypeValue, LeftValueBoundString, RefinerRecordId, RefinerSourceValue, RightValueBoundString, UnitText].\r\n */\r\nconst compressedRefinerKeys = [\r\n 'DataTypeValue',\r\n 'LeftValueBoundString',\r\n 'RefinerRecordId',\r\n 'RefinerSourceValue',\r\n 'RightValueBoundString',\r\n 'UnitText'\r\n];\r\n\r\n/**\r\n * Hydrates compressed refiner data from URL.\r\n * @param fullUrl The full URL of the page.\r\n * @param requestContext\r\n */\r\nexport const hydrateRefinersFromUrl = (requestContext: IRequestContext): ProductRefinerValue[] => {\r\n const compressedRefinerArray = parseQueryParam<(string | number)[][]>('refiners', requestContext);\r\n if (!compressedRefinerArray || compressedRefinerArray.length === 0) {\r\n return [];\r\n }\r\n\r\n return compressedRefinerArray\r\n .map(compressedRefiner => {\r\n try {\r\n const parsedRefiner: ProductRefinerValue = {};\r\n compressedRefinerKeys.forEach((refinerKey, index) => {\r\n parsedRefiner[refinerKey] = compressedRefiner[index];\r\n });\r\n return parsedRefiner;\r\n } catch {\r\n return undefined;\r\n }\r\n })\r\n .filter(Boolean);\r\n};\r\n\r\n/**\r\n * Compressed a list of refiners for use in URLs.\r\n * @param refiners The uncompressed refiners.\r\n */\r\nexport const compressRefiners = (refiners: ProductRefinerValue[]) => {\r\n const compressedRefiners: (string | number)[][] = [];\r\n\r\n refiners.forEach(refiner => {\r\n const compressedRefiner: (string | number)[] = [];\r\n compressedRefinerKeys.forEach(refinerKey => {\r\n compressedRefiner.push(refiner[refinerKey]);\r\n });\r\n compressedRefiners.push(compressedRefiner);\r\n });\r\n\r\n return compressedRefiners;\r\n};\r\n\r\n/**\r\n * Method which creates a URL contiaining serialized active refiners.\r\n * @param fullUrl The Current URL of the page.\r\n * @param refiners The refiners which should be added to the URL.\r\n * @param sortingColumns\r\n * @param skipCount\r\n */\r\nexport const buildListPageUrl = (fullUrl: URL, refiners?: ProductRefinerValue[], sortingColumns?: SortColumn[], skipCount?: number) => {\r\n // Refiner Change flow\r\n if (refiners !== undefined) {\r\n if (refiners.length === 0) {\r\n fullUrl.searchParams.delete('refiners');\r\n } else {\r\n const sortedRefiners = refiners.sort((first, second) =>\r\n first.RefinerRecordId && second.RefinerRecordId && first.RefinerRecordId > second.RefinerRecordId ? 1 : -1\r\n );\r\n fullUrl.searchParams.set('refiners', JSON.stringify(compressRefiners(sortedRefiners)));\r\n }\r\n\r\n // Adding or removing a refiner means we want to always load page 1\r\n fullUrl.searchParams.delete('skip');\r\n return fullUrl.href;\r\n }\r\n\r\n if (sortingColumns !== undefined) {\r\n if (sortingColumns.length === 0) {\r\n fullUrl.searchParams.delete('sorting');\r\n } else {\r\n fullUrl.searchParams.set('sorting', JSON.stringify(sortingColumns));\r\n }\r\n\r\n // Changing the sort means always load page 1\r\n fullUrl.searchParams.delete('skip');\r\n return fullUrl.href;\r\n }\r\n\r\n if (skipCount) {\r\n fullUrl.searchParams.set('skip', skipCount.toString());\r\n }\r\n\r\n return fullUrl.href;\r\n};\r\n\r\n/**\r\n * Parses a query param from the query object of the request context.\r\n * @param key The query parameter key.\r\n * @param requestContext The request context.\r\n */\r\nexport const parseQueryParam = (key: string, requestContext: IRequestContext): T | null => {\r\n if (requestContext.query && requestContext.query[key]) {\r\n // NOTE: Query seems to already be decoded\r\n //return JSON.parse(decodeURIComponent(requestContext.query[key]));\r\n\r\n return JSON.parse(requestContext.query[key]);\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Gets the current URL of the page from the request context.\r\n * @param requestContext The request context.\r\n */\r\nexport const getCurrentUrl = (requestContext: IRequestContext): URL => {\r\n if (MsDyn365.isBrowser) {\r\n return new URL(window.location.href);\r\n }\r\n\r\n // NOTE: Typing on requestURL is incorrect\r\n if (requestContext.url.requestUrl.href) {\r\n return new URL(requestContext.url.requestUrl.href);\r\n }\r\n return new URL((requestContext.url.requestUrl));\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { ProductListInventoryFilteringOptions } from '../actions';\r\nimport { IChoiceSummaryProps } from './choice-summary.props';\r\nimport { isBoolean, isMatchingRefinementCriterion, isRangeType } from './utilities';\r\n\r\ninterface IRefinerMap {\r\n key: string,\r\n parent?:string\r\n value: ProductRefinerValue;\r\n}\r\ninterface IRefinerKey {\r\n key: string;\r\n parent?:string\r\n}\r\n\r\n/**\r\n * ChoiceSummary component.\r\n */\r\n@observer\r\nexport default class ChoiceSummary extends React.PureComponent {\r\n private readonly closeButtonGlyph: string = 'msi-close-btn';\r\n\r\n private readonly payLoad: IPayLoad;\r\n\r\n @computed get selectedRefinersMap(): IRefinerMap[] {\r\n let { selectedChoices } = this.props;\r\n const { channelInventoryConfigurationId, refinerHierarchy } = this.props;\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- app configs are of generic type\r\n if (this.props.context?.app.config.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n selectedChoices = selectedChoices.filter(choice => {\r\n const parent = refinerHierarchy?.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, choice))\r\n );\r\n return parent && parent.RecordId !== channelInventoryConfigurationId;\r\n });\r\n }\r\n return selectedChoices.map((selectedRefiner: ProductRefinerValue, index) => {\r\n const RefinerValue=this._getKeyForRefinerValue(selectedRefiner, index.toString());\r\n return {\r\n key: RefinerValue.key,\r\n parent:RefinerValue.parent,\r\n value: selectedRefiner\r\n } as IRefinerMap;\r\n });\r\n }\r\n\r\n constructor(props: Readonly) {\r\n super(props);\r\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { clearAllText, label, classNames, choiceAriaLabel, closeAriaLabel,yesLabel,noLabel } = this.props;\r\n const items = this.selectedRefinersMap;\r\n this.payLoad.contentAction.etext = clearAllText;\r\n const clearAllAttributes = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\r\n return (\r\n
\r\n {items.length > 0 && label && {label}}\r\n
    \r\n {items.map((item: IRefinerMap) => {\r\n this.payLoad.contentAction.etext = item.key;\r\n const attribute = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\r\n let LeftValueBoundString = item.value.LeftValueBoundString;\r\n if (item.value && isBoolean(item.value.DataTypeValue)) {\r\n LeftValueBoundString = LeftValueBoundString === '1' ? yesLabel : noLabel;\r\n } else if (Number(this.props.transitRefinerRecordId) === item.value.RefinerRecordId) {\r\n LeftValueBoundString = LeftValueBoundString === '1' ? yesLabel : noLabel;\r\n }\r\n return (\r\n
  • \r\n \r\n {item?.parent && {item.parent}:}\r\n {LeftValueBoundString && item.value.LeftValueBoundLocalizedString === ''\r\n ? LeftValueBoundString\r\n : (item.value.LeftValueBoundLocalizedString ||\r\n item.value.LeftValueBoundLocalizedString === undefined) &&\r\n item.value.RefinerRecordId === 0\r\n ? item.key\r\n : LeftValueBoundString}\r\n \r\n \r\n
  • \r\n );\r\n })}\r\n
\r\n {items.length > 0 && clearAllText && (\r\n \r\n {clearAllText}\r\n \r\n )}\r\n
\r\n );\r\n }\r\n\r\n private _getKeyForRefinerValue(productRefinerValue: ProductRefinerValue, index: string): IRefinerKey {\r\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry, refinerValues } = this.props;\r\n const overallFormat = choiceFormat || '{1}';\r\n const rangeFormat = choiceRangeValueFormat;\r\n let refinerName = '';\r\n if (refinerHierarchy && refinerHierarchy.find) {\r\n const parent = refinerHierarchy.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, productRefinerValue))\r\n );\r\n\r\n if (!parent) {\r\n telemetry.warning('[choice-summary] could not find parent of selected refiner value');\r\n } else {\r\n refinerName = parent.KeyName || '';\r\n }\r\n }\r\n let refinerValueName: string;\r\n if (isRangeType(productRefinerValue.DataTypeValue)) {\r\n refinerValueName = rangeFormat\r\n .replace('{0}', this._formatPrice(productRefinerValue.LeftValueBoundString, productRefinerValue.UnitText))\r\n .replace('{1}', this._formatPrice(productRefinerValue.RightValueBoundString, productRefinerValue.UnitText));\r\n } else if (productRefinerValue.RefinerRecordId === 0) {\r\n const filterValue = refinerValues?.Values.find(\r\n refiner => refiner.LeftValueBoundString === productRefinerValue.LeftValueBoundString\r\n );\r\n refinerValueName = (filterValue ? filterValue.LeftValueBoundLocalizedString : productRefinerValue.LeftValueBoundString) || '';\r\n } else {\r\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n }\r\n if (refinerName === 'Rating' || refinerName === 'Price' || refinerName === 'Pris') {\r\n return {\r\n key: overallFormat.replace('{0}', refinerName).replace('{1}', `${refinerValueName}`),\r\n parent:refinerName\r\n };\r\n }\r\n\r\n return {\r\n key: overallFormat.replace('{0}', refinerName).replace('{1}', `${refinerValueName}_${refinerName}_${index}`),\r\n parent:refinerName\r\n };\r\n }\r\n\r\n private _formatPrice(amount: string | undefined, currency: string | undefined): string {\r\n if (!amount || !currency) {\r\n this.props.telemetry.trace('[choice-summary] could not format price');\r\n return amount || '';\r\n }\r\n let result = amount;\r\n\r\n try {\r\n result = this.props.context!.cultureFormatter.formatCurrency(Number(amount), currency);\r\n } catch (error) {\r\n this.props.telemetry.warning(`Failed to format price for ${result}: ${error}`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private readonly _onClick = (e: React.MouseEvent): void => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const target = e.currentTarget as HTMLElement;\r\n const clearAll = target.getAttribute('class')!.includes('choice-summary__clear-all');\r\n const selectedRefiner = clearAll ? undefined : this._getSelectedRefinerChoice(target);\r\n\r\n if (this.props.onChoiceClicked) {\r\n this.props.onChoiceClicked({\r\n clearAll,\r\n itemClicked: target,\r\n choiceClicked: selectedRefiner,\r\n nextItemToFocus: target.nextSibling as HTMLElement\r\n });\r\n }\r\n };\r\n\r\n private _getSelectedRefinerChoice(itemClicked: HTMLElement): ProductRefinerValue | undefined {\r\n const result = this.selectedRefinersMap.find(selected => itemClicked.id === selected.key);\r\n return (result && result.value) || undefined;\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 * as React from 'react';\r\n\r\ninterface IErrorMessage {\r\n text?: string;\r\n}\r\n\r\nexport const ErrorMessage: React.FC = ({ text }) => {\r\n return (\r\n \r\n
\r\n {` `}\r\n {text}\r\n {` `}\r\n
\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\n/* eslint-disable no-duplicate-imports */\r\nimport { ICoreContext, IGridSettings, IImageData, IImageSettings, Image, IRequestContext } from '@msdyn365-commerce/core';\r\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { getFallbackImageUrl, getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { getPayloadObject, getTelemetryAttributes, ITelemetryContent, onTelemetryClick } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { IDlvrySearchResultContainerResources } from '../dlvry-search-result-container.props.autogenerated';\r\n\r\n// Import { IComponent, IComponentProps, ICoreContext, IGridSettings, IImageData, IImageSettings, Image, msdyn365Commerce } from '@msdyn365-commerce/core';\r\n\r\ninterface IFeatureSearchResultItem {\r\n product: SimpleProduct | null;\r\n context: ICoreContext;\r\n resources: IDlvrySearchResultContainerResources;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n telemetryContent?: ITelemetryContent;\r\n recommendation?: string;\r\n}\r\n\r\nexport const FeatureSearchResultItem: React.FC = ({\r\n product,\r\n context,\r\n imageSettings,\r\n resources,\r\n telemetryContent,\r\n recommendation\r\n}) => {\r\n if (product === null) {\r\n return null;\r\n }\r\n\r\n const productName = product.Name;\r\n const productRecordId = product && product.RecordId ? product.RecordId : 0;\r\n const productUrl = getProductPageUrlSync(product.Name || '', productRecordId, context && context.actionContext, undefined);\r\n const fallbackImage = getFallbackImageUrl(\r\n product.ItemId,\r\n context.actionContext.requestContext.apiSettings,\r\n context.request.app?.config?.OmniChannelMedia\r\n );\r\n const heading =\r\n recommendation && recommendation === 'descriptions' ? resources.featureSimilarDescriptionTitle : resources.featureSimilarLooksTitle;\r\n\r\n // Construct telemetry attribute to render\r\n const payLoad = getPayloadObject('click', telemetryContent!, productName!, productRecordId.toString());\r\n\r\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\r\n return (\r\n
\r\n \r\n
\r\n {renderProductPlacementImage(\r\n imageSettings,\r\n context.request.gridSettings,\r\n product.PrimaryImageUrl,\r\n product.Name,\r\n fallbackImage,\r\n context.actionContext.requestContext\r\n )}\r\n
\r\n \r\n
\r\n

{heading}

\r\n {renderProductTitle(product?.Name)}\r\n
\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 altText?: string,\r\n fallbackImage?: string,\r\n context?: IRequestContext\r\n): JSX.Element | null {\r\n if (!imageUrl || !gridSettings || !imageSettings) {\r\n return null;\r\n }\r\n const img: IImageData = {\r\n src: imageUrl,\r\n altText: altText ? altText : ''\r\n };\r\n const imageProps = {\r\n gridSettings,\r\n imageSettings,\r\n fallBackSrc: fallbackImage\r\n };\r\n return ;\r\n}\r\n\r\nfunction renderProductTitle(title?: string): JSX.Element | null {\r\n return

{title}

;\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 * as React from 'react';\r\n\r\ninterface ILink {\r\n className?: string;\r\n text?: string;\r\n href?: string;\r\n ariaLabel?: string;\r\n}\r\n\r\nexport const Link: React.FC = ({ text, className, href, ariaLabel }) => (\r\n \r\n {' '}\r\n {text}{' '}\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 { Button, Modal, ModalBody, ModalFooter, ModalHeader } from '@msdyn365-commerce-modules/utilities';\r\nimport React from 'react';\r\n\r\nexport interface ISearchResultModalViewProps {\r\n modal: React.ReactElement;\r\n modalHeader: React.ReactElement;\r\n modalFooter: React.ReactElement;\r\n modalBody: React.ReactElement;\r\n}\r\n\r\ninterface IModalToggleProps {\r\n innerRef: React.RefObject | undefined;\r\n id: string;\r\n text: string;\r\n ariaLabel: string;\r\n onClick(): void;\r\n}\r\n\r\nexport interface ISearchResultModalResources {\r\n modalTitle: string;\r\n modalCloseButtonText: string;\r\n}\r\n\r\nexport interface ISearchResultModalProps {\r\n resources: ISearchResultModalResources;\r\n isOpen: boolean;\r\n returnRef: React.RefObject | undefined;\r\n onModalToggle(): void;\r\n}\r\n\r\nexport const ModalToggle: React.FC = (props: IModalToggleProps) => {\r\n const { text, onClick, ariaLabel, innerRef, id } = props;\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const SearchResultModal = (props: ISearchResultModalProps): ISearchResultModalViewProps => {\r\n return {\r\n modal: modalNode(props),\r\n modalHeader: modalHeaderNode(props),\r\n modalFooter: modalFooterNode(props),\r\n modalBody: \r\n };\r\n};\r\n\r\nconst modalNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\r\n return {props.resources.modalTitle};\r\n};\r\n\r\nconst modalFooterNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n \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 { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport { IPriceComponentResources } from '@msdyn365-commerce/components';\r\nimport { ICoreContext, IImageSettings } from '@msdyn365-commerce/core';\r\nimport { CommerceList, Customer, ProductList, ProductPrice, ProductSearchResult, SimpleProduct, UnitOfMeasureConversion } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n ArrayExtensions,\r\n ProductInput,\r\n getSimpleProducts,\r\n GetCustomerInput,\r\n getCustomer,\r\n getWishlistByCustomerId,\r\n buildWishlistLine,\r\n OrderTemplate,\r\n QueryResultSettingsProxy,\r\n GetOrderTemplatesInput,\r\n getOrderTemplates\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport { addLinesAsync, createCommerceListAsync, createGetByCustomerInput, removeLinesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CommerceListsDataActions.g';\r\nimport * as React from 'react';\r\nimport { ProductComponent } from '../../../themes/dlvry-adventureworks/views/components/product.component';\r\n\r\nimport { IDlvrySearchResultContainerResources } from '../dlvry-search-result-container.props.autogenerated';\r\nimport { toast } from '../../../components/toast/toast';\r\nimport PQueue from 'p-queue';\r\nimport { ValidateProductAccessResult } from '../../../shared-utils/validate-product-access';\r\nimport { IProductInventoryInformation } from '../../../components/common/product-inventory-utils';\r\nimport { onBuyHasAccessValidator } from '../../../shared-utils/attributes/on-buy-access-validator';\r\n\r\nexport interface ProductSearchResultExt extends ProductSearchResult {\r\n Badge?: string;\r\n Brand?: string;\r\n Manufacturer?: string;\r\n PrefetchedPrice?: boolean;\r\n PriceFailed?: boolean;\r\n ProductPrice?: ProductPrice;\r\n Transit?: boolean;\r\n}\r\n\r\ninterface IProductSearchResultItems {\r\n cart: ICartState | undefined;\r\n products: ProductSearchResultExt[];\r\n simpleProducts: SimpleProduct[];\r\n customerInformation?: Customer;\r\n orderTemplates?: OrderTemplate[];\r\n unitConversions?: UnitOfMeasureConversion[];\r\n wishlists: CommerceList[] | undefined;\r\n context: ICoreContext;\r\n config: { [key: string]: any };\r\n resources: IDlvrySearchResultContainerResources;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n allowBackNavigation?: boolean;\r\n telemetryContent: ITelemetryContent;\r\n quickviewSlot?: {} | null | undefined;\r\n productComparisonButton?: {} | null | undefined;\r\n channelInventoryConfigurationId?: number;\r\n isPriceMinMaxEnabled?: boolean;\r\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\r\n productInventoryStatus?: IProductInventoryInformation[];\r\n disableBuyButtons?: boolean;\r\n showPrices?: boolean;\r\n validatedProductAccess?: ValidateProductAccessResult[];\r\n productInventoryInformation?: IProductInventoryInformation[];\r\n}\r\n\r\n/**\r\n * Returns the product inventory label.\r\n * @param channelInventoryConfigurationId - The channel configuration Id.\r\n * @param product - The product.\r\n * @param productInventoryStatus\r\n * @returns The inventory label.\r\n */\r\nexport function getInventoryLabel(channelInventoryConfigurationId: number | undefined, product: ProductSearchResult, productInventoryStatus: IProductInventoryInformation[] | undefined): string | undefined {\r\n if (productInventoryStatus) {\r\n const shippingInventory = productInventoryStatus.find(shipping => shipping.ProductAvailableQuantity.ProductId === product.RecordId);\r\n if (shippingInventory && shippingInventory.StockLevelLabel) {\r\n return shippingInventory.StockLevelLabel;\r\n }\r\n }\r\n if (!channelInventoryConfigurationId || !ArrayExtensions.hasElements(product.AttributeValues)) {\r\n return undefined;\r\n }\r\n const inventoryAttribute = product.AttributeValues.find(attribute => attribute.RecordId === channelInventoryConfigurationId);\r\n if (inventoryAttribute) {\r\n return inventoryAttribute.TextValue;\r\n }\r\n return undefined;\r\n}\r\n\r\nasync function callAddWishlistLine(context: ICoreContext, productId: number, wishlistId: number, toastErrorHeader?: string): Promise {\r\n try {\r\n const customer = await getCustomerAccount(context);\r\n if (customer && customer.AccountNumber) {\r\n const createdCommerceList = await addLinesAsync({ callerContext: context.actionContext },\r\n wishlistId,\r\n [\r\n buildWishlistLine(productId, customer.AccountNumber, wishlistId)\r\n ]);\r\n context.actionContext.update(createGetByCustomerInput({}, null), [createdCommerceList]);\r\n }\r\n } catch (error) {\r\n toast({\r\n header: toastErrorHeader,\r\n // @ts-ignore\r\n text: error,\r\n // @ts-ignore\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => { }\r\n });\r\n }\r\n}\r\n\r\nasync function getCustomerAccount(context: ICoreContext) {\r\n const customerInput = new GetCustomerInput(context.actionContext.requestContext.apiSettings);\r\n return getCustomer(customerInput, context.actionContext);\r\n}\r\n\r\nfunction getWishlistLineIdFromProductId(wishlists: CommerceList[] | undefined, productId: number | undefined): number | null {\r\n if (!wishlists ||\r\n !productId ||\r\n wishlists.length === 0 ||\r\n !wishlists[0].CommerceListLines ||\r\n wishlists[0].CommerceListLines.length === 0) {\r\n return null;\r\n }\r\n\r\n const foundWishlistItem = wishlists[0].CommerceListLines.filter(commerceListLine => {\r\n return commerceListLine.ProductId === productId;\r\n });\r\n\r\n if (foundWishlistItem && foundWishlistItem[0].LineId) {\r\n return foundWishlistItem[0].LineId;\r\n }\r\n return null;\r\n}\r\n\r\nasync function moveItemToWishlist(context: ICoreContext, resources: IDlvrySearchResultContainerResources, product: ProductSearchResult, defaultWishlistName: string): Promise {\r\n if (!context || !product || !context.request.user.catalogId) {\r\n return Promise.resolve();\r\n }\r\n\r\n const productInputs: ProductInput[] = [];\r\n const productInput = new ProductInput(\r\n product.RecordId,\r\n context.request.apiSettings,\r\n undefined, undefined,\r\n context.request,\r\n +context.request.user.catalogId\r\n );\r\n productInputs.push(productInput);\r\n\r\n const simpleProduct = await getSimpleProducts(productInputs, context.actionContext);\r\n\r\n if (context.request.user.isAuthenticated && simpleProduct && simpleProduct.length >= 0) {\r\n const customer = await getCustomerAccount(context);\r\n const wishlists = await getWishlistByCustomerId(createGetByCustomerInput({}, null), context.actionContext);\r\n if (!wishlists || wishlists.length === 0) {\r\n const wishlistName = defaultWishlistName;\r\n if (customer && customer.AccountNumber) {\r\n const listData: CommerceList = {\r\n CustomerId: customer.AccountNumber,\r\n Name: wishlistName,\r\n CommerceListTypeValue: 1,\r\n Id: 0\r\n };\r\n try {\r\n const commerceList = await createCommerceListAsync({\r\n callerContext: context.actionContext\r\n },\r\n listData);\r\n await callAddWishlistLine(context, simpleProduct[0].RecordId, commerceList.Id, resources.toastErrorHeader);\r\n } catch (error) {\r\n toast({\r\n header: resources.toastErrorHeader,\r\n // @ts-ignore\r\n text: error,\r\n // @ts-ignore\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => {}\r\n });\r\n }\r\n }\r\n } else {\r\n await callAddWishlistLine(context, simpleProduct[0].RecordId, wishlists[0].Id, resources.toastErrorHeader);\r\n\r\n toast({\r\n text: resources.addedProductToWishlistText.replace('{productName}', simpleProduct[0].Name || ''),\r\n autoClose: 3000,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => { }\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction removeItemFromWishlist(context: ICoreContext, wishlists: CommerceList[] | undefined, product: ProductSearchResult, toastErrorHeader?: string): void {\r\n const wishlistLineId = getWishlistLineIdFromProductId(wishlists, product.RecordId);\r\n if (wishlists && wishlists[0] && wishlistLineId) {\r\n removeLinesAsync({ callerContext: context.actionContext }, wishlists[0].Id, [{ LineId: wishlistLineId }])\r\n .then(commerceList => {\r\n const newWishlists = [\r\n ...wishlists\r\n ];\r\n newWishlists[0] = commerceList;\r\n context.actionContext.update(createGetByCustomerInput({}, null), newWishlists);\r\n })\r\n .catch(error => {\r\n toast({\r\n header: toastErrorHeader,\r\n text: error,\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => {}\r\n });\r\n });\r\n }\r\n}\r\n\r\nfunction getWishlistButton(context: ICoreContext, resources: IDlvrySearchResultContainerResources, product: ProductSearchResult, wishlists: CommerceList[] | undefined, defaultWishlistName: string) {\r\n const isWishlisted = wishlists && wishlists.length > 0 && wishlists[0].CommerceListLines?.find(x => x.ProductId === product.RecordId) ? true : false;\r\n let className = 'btn-add-to-wishlist';\r\n\r\n if (isWishlisted) {\r\n className += ' is-wishlisted';\r\n }\r\n\r\n return (\r\n
\r\n {\r\n if (!isWishlisted) {\r\n await moveItemToWishlist(context, resources, product, defaultWishlistName);\r\n } else {\r\n removeItemFromWishlist(context, wishlists, product, resources.toastErrorHeader);\r\n }\r\n }\r\n }>\r\n {!isWishlisted ? resources.addToWishlistButtonText : resources.removeFromWishlistButtonText}\r\n \r\n
\r\n );\r\n}\r\n\r\nexport const ProductSearchResultItems: React.FC = ({\r\n cart,\r\n products,\r\n simpleProducts,\r\n customerInformation,\r\n orderTemplates,\r\n unitConversions,\r\n wishlists,\r\n context,\r\n config,\r\n imageSettings,\r\n resources,\r\n moduleType,\r\n moduleId,\r\n allowBackNavigation,\r\n telemetryContent,\r\n quickviewSlot,\r\n productComparisonButton,\r\n channelInventoryConfigurationId,\r\n isPriceMinMaxEnabled,\r\n productsDimensionAvailabilities,\r\n productInventoryStatus,\r\n validatedProductAccess,\r\n disableBuyButtons,\r\n showPrices,\r\n productInventoryInformation\r\n}) => {\r\n const [orderTemplatesState, setOrderTemplatesState] = React.useState(undefined);\r\n const cartQueue = React.useMemo(() => new PQueue({ concurrency: 1 }), []);\r\n\r\n const updateOrderTemplatesAsync = async (newOrderTemplate?: ProductList) => {\r\n let newOrderTemplates;\r\n\r\n if (newOrderTemplate) {\r\n newOrderTemplates = [...(orderTemplatesState ? orderTemplatesState : orderTemplates ? orderTemplates : [])];\r\n\r\n // Add new order template if it doesn't exist\r\n if (newOrderTemplates.every(x => x.productList.Id !== newOrderTemplate.Id)) {\r\n newOrderTemplates.splice(0, 0, new OrderTemplate(newOrderTemplate, [], 0));\r\n }\r\n } else {\r\n // Refresh order templates incase new order template was created\r\n const queryResultSettings = QueryResultSettingsProxy.fromInputData({\r\n requestContext: context.request,\r\n config: config\r\n }).QueryResultSettings;\r\n const input = new GetOrderTemplatesInput('', queryResultSettings);\r\n newOrderTemplates = (await getOrderTemplates(input, context.actionContext)).map(x => new OrderTemplate(x, [], 0));\r\n }\r\n\r\n setOrderTemplatesState(newOrderTemplates);\r\n return newOrderTemplates;\r\n };\r\n\r\n const retrieveOrderTemplates = async () => {\r\n return orderTemplates ? orderTemplates : orderTemplatesState ? orderTemplatesState : updateOrderTemplatesAsync();\r\n };\r\n\r\n const priceResources: IPriceComponentResources = {\r\n priceRangeSeparator: resources.priceRangeSeparator\r\n };\r\n return (\r\n
    \r\n {products.map((product: ProductSearchResultExt, index: number) => (\r\n
  • \r\n x.RecordId === product.RecordId),\r\n customerInformation,\r\n unitConversions: unitConversions?.filter(x => x.ProductRecordId === product.RecordId)\r\n }}\r\n cartQueue={cartQueue}\r\n buyAlwaysAdd\r\n retrieveOrderTemplates={retrieveOrderTemplates}\r\n onUpdateOrderTemplates={updateOrderTemplatesAsync}\r\n quickViewButton={quickviewSlot}\r\n productComparisonButton={productComparisonButton}\r\n wishlistButton={getWishlistButton(context, resources, product, wishlists, resources.defaultWishlistName)}\r\n inventoryLabel={getInventoryLabel(channelInventoryConfigurationId, product,productInventoryStatus)}\r\n inventoryStatus={productInventoryInformation?.find(x => x.ProductAvailableQuantity.ProductId === product.RecordId)}\r\n isPriceMinMaxEnabled={isPriceMinMaxEnabled}\r\n disableBuyButton={disableBuyButtons}\r\n showPrice={showPrices}\r\n userHasAccess={validatedProductAccess?.find(x => x.RecordId === product.RecordId)?.HasAccess}\r\n priceResources={priceResources}\r\n swatchItemAriaLabel={resources.swatchItemAriaLabel}\r\n addToCartText={resources.addToCartText}\r\n updateCartText={resources.updateCartText}\r\n removeFromCartText={resources.removeFromCartText}\r\n outOfStockText={resources.outOfStockText}\r\n priceErrorText={resources.priceErrorText}\r\n toastStrings={{\r\n errorHeader: resources.toastErrorHeader,\r\n productsAddedToCart: resources.productsAddedToCart,\r\n productsRemovedFromCart: resources.productsRemovedFromCart,\r\n productsUpdatedInCart: resources.productsUpdatedInCart,\r\n goToCart: resources.toastGoToCart,\r\n noAccessToProduct: resources.toastNoAccessToProduct\r\n }}\r\n inCartTooltipText={resources.inCartTooltipText}\r\n transitTooltip={resources.transitTooltip}\r\n dimensionAvailabilities={productsDimensionAvailabilities?.find(\r\n dimensionAvailability =>\r\n ArrayExtensions.hasElements(dimensionAvailability) &&\r\n dimensionAvailability[0].masterProductId === product.MasterProductId\r\n )}\r\n addToOrderTemplateResources={{\r\n addToOrderTemplateHeader: resources.addToOrderTemplateHeader,\r\n noOrderTemplatesMessage: resources.noOrderTemplatesMessage,\r\n noOrderTemplatesDescription: resources.noOrderTemplatesDescription,\r\n createAnOrderTemplateButtonText: resources.createAnOrderTemplateButtonText,\r\n createNewOrderTemplateButtonText: resources.createNewOrderTemplateButtonText,\r\n cancelOrderTemplateCreationButtonText: resources.cancelOrderTemplateCreationButtonText,\r\n selectTemplatesText: resources.selectTemplatesText,\r\n addToTemplateButtonText: resources.addToTemplateButtonText,\r\n lineItemsText: resources.lineItemsText,\r\n createOrderTemplateHeader: resources.createOrderTemplateHeader,\r\n orderTemplateTitle: resources.orderTemplateTitle,\r\n orderTemplateNameAriaLabel: resources.orderTemplateNameAriaLabel,\r\n createOrderTemplateDescription: resources.createOrderTemplateDescription,\r\n defaultOrderTemplateName: resources.defaultOrderTemplateName,\r\n createOrderTemplateButtonText: resources.createOrderTemplateButtonText,\r\n cancelNewOrderTemplateCreationButtonText: resources.cancelNewOrderTemplateCreationButtonText,\r\n viewOrderTemplateButtonText: resources.viewOrderTemplateButtonText,\r\n continueShoppingButtonText: resources.continueShoppingButtonText,\r\n itemAddedToOrderTemplateHeaderItemOneText: resources.itemAddedToOrderTemplateHeaderItemOneText,\r\n itemAddedToOrderTemplateHeaderItemFormatText: resources.itemAddedToOrderTemplateHeaderItemFormatText,\r\n itemAddedToOrderTemplateHeaderMessageText: resources.itemAddedToOrderTemplateHeaderMessageText,\r\n priceFree: resources.priceFree,\r\n originalPriceText: resources.originalPriceText,\r\n currentPriceText: resources.currentPriceText,\r\n duplicatedProductsHeader: resources.duplicatedProductsHeader,\r\n duplicatedProductsDescription: resources.duplicatedProductsDescription,\r\n updateQuantityButtonText: resources.updateQuantityButtonText,\r\n cancelDuplicateItemsButtonText: resources.cancelDuplicateItemsButtonText,\r\n addToOrderTemplateButtonText: resources.addToOrderTemplateButtonText,\r\n addToOrderTemplateButtonTooltip: resources.addToOrderTemplateButtonTooltip\r\n }}\r\n onBuyValidate={(product) => onBuyHasAccessValidator(\r\n context,\r\n customerInformation,\r\n product,\r\n resources.toastNoAccessToProduct\r\n )}\r\n />\r\n
  • \r\n ))}\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\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface ISeparator {\r\n separator: string;\r\n}\r\n\r\nexport const Separator: React.FC = ({ separator }) => (\r\n \r\n {` `}\r\n {separator}\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\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface ITitle {\r\n className: string;\r\n text: string;\r\n}\r\n\r\nexport const Title: React.FC = ({ text, className }) => (\r\n \r\n {` `}\r\n {text}\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\n/* eslint-disable no-duplicate-imports */\r\nimport { ISliderLabel, ISliderThumbProps, Slider } from '@msdyn365-commerce-modules/utilities';\r\nimport debounce from 'lodash/debounce';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { IRefineItemProps, IRefineItemState } from './refine-item';\r\n\r\ntype InputType = 'Min' | 'Max';\r\n\r\nexport type RangeRefineItemType = 'slider' | 'input';\r\n\r\n/**\r\n * Range refine item properties.\r\n */\r\nexport interface IRangeRefineItemProps extends IRefineItemProps {\r\n rangeType: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n sliderKey?: string;\r\n}\r\n\r\n/**\r\n * Range refine item state.\r\n */\r\nexport interface IRangeRefineItemState extends IRefineItemState {\r\n validationErrorMin: string | undefined;\r\n validationErrorMax: string | undefined;\r\n selectedMin: string | undefined;\r\n selectedMax: string | undefined;\r\n touchedMin: boolean;\r\n touchedMax: boolean;\r\n sliderId: string;\r\n minValue: string | undefined;\r\n maxValue: string | undefined;\r\n labels: ISliderLabel[];\r\n sliderThumbs: ISliderThumbProps[];\r\n}\r\n\r\n/**\r\n * RangeRefineItem component (controlled by RefineSubmenu).\r\n */\r\n@observer\r\nexport default class RangeRefineItem extends React.Component {\r\n private readonly _formattedPriceReverseLookup: Map = new Map();\r\n\r\n private readonly minInput: React.RefObject;\r\n\r\n private readonly maxInput: React.RefObject;\r\n\r\n @computed get currencyCode(): string {\r\n return this.props.productRefinerValue.UnitText || '';\r\n }\r\n\r\n public constructor(props: IRangeRefineItemProps) {\r\n super(props);\r\n this._onRangeUpdate = this._onRangeUpdate.bind(this);\r\n this._onRangeUpdateEnd = this._onRangeUpdateEnd.bind(this);\r\n this._handleRangeTooltipText = this._handleRangeTooltipText.bind(this);\r\n this._changeMin = this._changeMin.bind(this);\r\n this._changeMax = this._changeMax.bind(this);\r\n this._finishChangeMin = this._finishChangeMin.bind(this);\r\n this._finishChangeMax = this._finishChangeMax.bind(this);\r\n\r\n this.minInput = React.createRef();\r\n this.maxInput = React.createRef();\r\n\r\n const { selectedRefinementCriterion } = this.props;\r\n const initialMin = selectedRefinementCriterion?.LeftValueBoundString ?? '0';\r\n const initialMax = selectedRefinementCriterion?.RightValueBoundString;\r\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(\r\n this.props.productRefinerValue.RefinerRecordId\r\n )}`;\r\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\r\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\r\n const minPrice = this._formatPrice(minValue);\r\n const maxPrice = this._formatPrice(maxValue);\r\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\r\n const selectedMin =\r\n this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\r\n const selectedMax =\r\n this.props.selectedRefinementCriterion?.RightValueBoundString ??\r\n this.props.productRefinerValue.RightValueBoundString ??\r\n maxValue;\r\n const selectedMinPrice = this._formatPrice(selectedMin);\r\n const selectedMaxPrice = this._formatPrice(selectedMax);\r\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\r\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(\r\n sliderId,\r\n sliderKeyString,\r\n selectedMin,\r\n selectedMinPrice,\r\n selectedMax,\r\n selectedMaxPrice,\r\n maxPrice\r\n );\r\n this.state = {\r\n isChecked: false,\r\n validationErrorMin: undefined,\r\n validationErrorMax: undefined,\r\n selectedMin: initialMin,\r\n selectedMax: initialMax,\r\n touchedMin: false,\r\n touchedMax: false,\r\n sliderId,\r\n minValue,\r\n maxValue,\r\n labels,\r\n sliderThumbs\r\n };\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRangeRefineItemProps, nextState: IRangeRefineItemState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public componentDidUpdate(previousProps: IRangeRefineItemProps): void {\r\n if (previousProps !== this.props) {\r\n this.updateSliderProps();\r\n }\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const { productRefinerValue, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerValue || !parentProductRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error(\r\n 'Cannot render refine value range without productRefinerValue and parentProductRefinerHierarchy'\r\n );\r\n return undefined;\r\n }\r\n\r\n if (this.props.rangeType === 'input') {\r\n return this._renderInputFields();\r\n }\r\n\r\n return this._renderSlider();\r\n }\r\n\r\n /**\r\n * Function to update slider props.\r\n */\r\n private updateSliderProps(): void {\r\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(\r\n this.props.productRefinerValue.RefinerRecordId\r\n )}`;\r\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\r\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\r\n const minPrice = this._formatPrice(minValue);\r\n const maxPrice = this._formatPrice(maxValue);\r\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\r\n const selectedMin =\r\n this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\r\n const selectedMax =\r\n this.props.selectedRefinementCriterion?.RightValueBoundString ??\r\n this.props.productRefinerValue.RightValueBoundString ??\r\n maxValue;\r\n const selectedMinPrice = this._formatPrice(selectedMin);\r\n const selectedMaxPrice = this._formatPrice(selectedMax);\r\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\r\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(\r\n sliderId,\r\n sliderKeyString,\r\n selectedMin,\r\n selectedMinPrice,\r\n selectedMax,\r\n selectedMaxPrice,\r\n maxPrice\r\n );\r\n this.setState({ sliderId, minValue, maxValue, labels, sliderThumbs });\r\n }\r\n\r\n /**\r\n * Function to create the labels for slider.\r\n * @param sliderId - Slider element id for the DOM.\r\n * @param minPrice - Slider min value.\r\n * @param maxPrice - Slider max value.\r\n * @returns Array labels.\r\n */\r\n private readonly getLabels = (sliderId: string, minPrice: string, maxPrice: string): ISliderLabel[] => {\r\n return [\r\n {\r\n labelId: `${sliderId}_start`,\r\n labelString: `${minPrice}`,\r\n labelPositioning: 'start'\r\n },\r\n {\r\n labelId: `${sliderId}_end`,\r\n labelString: `${maxPrice}`,\r\n labelPositioning: 'end'\r\n }\r\n ];\r\n };\r\n\r\n /**\r\n * Function to create the slider thumbs for slider.\r\n * @param sliderId - Slider element id for the DOM.\r\n * @param sliderKey - Unique key for slider.\r\n * @param selectedMin - Slider selected min value.\r\n * @param selectedMinPrice - Slider selected min price.\r\n * @param selectedMax - Slider selected max value.\r\n * @param selectedMaxPrice - Slider selected max price..\r\n * @param maxPrice - Slider max price..\r\n * @returns Slider Thumb Props.\r\n */\r\n private readonly getSliderThumbs = (\r\n sliderId: string,\r\n sliderKey: string,\r\n selectedMin: string,\r\n selectedMinPrice: string,\r\n selectedMax: string | undefined,\r\n selectedMaxPrice: string,\r\n maxPrice: string\r\n ): ISliderThumbProps[] => {\r\n const sliderThumbDefaultValue = 0;\r\n return [\r\n {\r\n id: `${sliderId}${sliderKey}_slider_thumb_start`,\r\n value: (selectedMin && Number(selectedMin)) || sliderThumbDefaultValue,\r\n ariaLabel: `${this.props.minValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMinPrice}`\r\n },\r\n {\r\n id: `${sliderId}${sliderKey}_slider_thumb_end`,\r\n value: Number(selectedMax) || Number(maxPrice),\r\n ariaLabel: `${this.props.maxValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMaxPrice}`\r\n }\r\n ];\r\n };\r\n\r\n private _renderInputFields(): JSX.Element | undefined {\r\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n const { selectedMin, selectedMax, touchedMin, touchedMax, validationErrorMin, validationErrorMax } = this.state;\r\n\r\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', parentProductRefinerHierarchy.KeyName || '');\r\n const formAttrs = {\r\n 'aria-label': rangeAriaLabel,\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n // To enable price formatting of selected fields, this is the approach:\r\n // initial value: min=0 formatted as price, max=undefined\r\n // onFocus/onChange: convert to number (unformat) and mark as touched to indicate value is being edited\r\n // onBlur: validate and format entered value as price\r\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${\r\n validationErrorMin ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${\r\n validationErrorMax ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n const minLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-min';\r\n const maxLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-max';\r\n const formattedSelectedMin = this._getFormattedSelectedValue(selectedMin, touchedMin, validationErrorMin);\r\n const formattedSelectedMax = this._getFormattedSelectedValue(selectedMax, touchedMax, validationErrorMax);\r\n return (\r\n
\r\n \r\n \r\n {validationErrorMin && (\r\n \r\n {validationErrorMin}\r\n \r\n )}\r\n {validationErrorMax && validationErrorMin !== validationErrorMax && (\r\n \r\n {validationErrorMax}\r\n \r\n )}\r\n
\r\n );\r\n }\r\n\r\n private _renderSlider(): JSX.Element | undefined {\r\n const { isDisabled, sliderKey } = this.props;\r\n const ariaAttributes = {\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n private _changeMin(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Min');\r\n }\r\n\r\n private _changeMax(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Max');\r\n }\r\n\r\n private _changeValue(event: React.FocusEvent, inputType: InputType): void {\r\n const selectedKey = `selected${inputType}`;\r\n const touchedKey = `touched${inputType}`;\r\n this.setState({\r\n [selectedKey]: this._getInputWithoutFormatting(event.currentTarget.value),\r\n [touchedKey]: true\r\n });\r\n }\r\n\r\n private _finishChangeMin(event: React.FocusEvent): boolean {\r\n const selectedMinValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMin: selectedMinValue,\r\n minTouched: false\r\n });\r\n const minInput = Number(selectedMinValue);\r\n const {\r\n onToggle,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n refineItemCommonProps,\r\n selectedRefinementCriterion\r\n } = this.props;\r\n const max = (selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString) || undefined;\r\n\r\n const maxNum = max ? Number(max) : undefined;\r\n\r\n if (isNaN(minInput)) {\r\n this.setState({ validationErrorMin: refineItemCommonProps.validationErrorNaN });\r\n this._focus('Min');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minInput, maxNum)) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minInput,\r\n rangeEnd: maxNum\r\n });\r\n return true;\r\n }\r\n this._focus('Min');\r\n\r\n return false;\r\n }\r\n\r\n private _finishChangeMax(event: React.FocusEvent): boolean {\r\n const selectedMaxValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMax: selectedMaxValue,\r\n maxTouched: false\r\n });\r\n const maxInput = Number(selectedMaxValue);\r\n const {\r\n onToggle,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n refineItemCommonProps,\r\n selectedRefinementCriterion\r\n } = this.props;\r\n const min = (selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString) || '0';\r\n\r\n const minNum = Number(min);\r\n\r\n if (isNaN(maxInput)) {\r\n this.setState({ validationErrorMax: refineItemCommonProps.validationErrorNaN });\r\n this._focus('Max');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minNum, maxInput)) {\r\n if (productRefinerValue) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minNum,\r\n rangeEnd: maxInput\r\n });\r\n } else {\r\n this._focus('Max');\r\n }\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _focus(inputType: InputType): void {\r\n const ref = inputType === 'Max' ? this.maxInput : this.minInput;\r\n\r\n setTimeout(() => {\r\n if (ref && ref.current) {\r\n ref.current.focus();\r\n }\r\n }, 50);\r\n }\r\n\r\n private _getFormattedSelectedValue(\r\n selected: string | undefined,\r\n touched: boolean,\r\n validationError: string | undefined\r\n ): string | undefined {\r\n if (touched || validationError || selected === undefined) {\r\n return selected;\r\n }\r\n return this._formatPrice(selected);\r\n }\r\n\r\n private _validateRange(min: number, max: number | undefined): boolean {\r\n const { refineItemCommonProps } = this.props;\r\n if (max === undefined) {\r\n return true;\r\n }\r\n\r\n if (min > max) {\r\n this.setState({\r\n validationErrorMin: refineItemCommonProps.validationErrorRange,\r\n validationErrorMax: refineItemCommonProps.validationErrorRange\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _formatPrice(amount: string | undefined): string {\r\n if (this.props.productRefinerValue.RefinerRecordId === 0) {\r\n const result = this.props.context.cultureFormatter.formatCurrency(Number(amount), this.currencyCode);\r\n return result;\r\n }\r\n return amount || '';\r\n }\r\n\r\n private _getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNum = Number(input);\r\n if (!isNaN(inputAsNum)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\r\n return reverseLookupResult || input;\r\n }\r\n\r\n // NOTE: Fix types once Shared Components build pipeline bug fixed\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _onRangeUpdate(sliderChangeNotification: any): void {\r\n // Need to filter out mousemove events as these cause errors after the menu updates and slider re-renders\r\n if (sliderChangeNotification.eventType !== 'mousemove') {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _onRangeUpdateEnd(sliderChangeNotification: any): void {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _focusOnSliderThumb(sliderChangeNotification: any): void {\r\n if (sliderChangeNotification.id) {\r\n const element = document.getElementById(`${sliderChangeNotification.id}range`);\r\n if (element) {\r\n setTimeout(() => {\r\n element.focus();\r\n }, 0);\r\n }\r\n }\r\n }\r\n\r\n private _handleRangeTooltipText(tooltip: number): string {\r\n return this._formatPrice(`${tooltip}`);\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { RatingComponent, SwatchComponent } from '@msdyn365-commerce/components';\r\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\nimport { checkIfShouldDisplayAsSwatch, DimensionTypes, IDimensionsApp, StringExtensions } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { format, getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\n/**\r\n * RefineItem properties.\r\n */\r\nexport interface IRefineItemProps {\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\r\n productRefinerValue: ProductRefinerValue;\r\n selectedRefinementCriterion: ProductRefinerValue | undefined;\r\n selectedRefinerValues?: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n context: ICoreContext>;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n index?: number;\r\n productCountAriaLabel?: string;\r\n singleProductCountAriaLabel?: string;\r\n refineItemAriaLabel?: string;\r\n refineItemsAriaLabel?: string;\r\n isMobileView?: boolean;\r\n yesText?: string;\r\n noText?: string;\r\n transitRefinerRecordId?: string;\r\n\r\n /**\r\n * The telemetry content\r\n */\r\n telemetryContent?: ITelemetryContent;\r\n onToggle(notfication: Readonly): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine item state.\r\n */\r\nexport interface IRefineItemState extends React.ComponentState {\r\n isChecked: boolean;\r\n renderingError?: object;\r\n}\r\n\r\n/**\r\n * Single-select and multi-select refine item component (controlled by RefineSubmenu).\r\n */\r\nexport default class RefineItem extends React.Component {\r\n private readonly anchorType: React.RefObject;\r\n\r\n private readonly payLoad: IPayLoad;\r\n\r\n public constructor(props: IRefineItemProps) {\r\n super(props);\r\n this._onClick = this._onClick.bind(this);\r\n this.state = {\r\n isChecked: !!this.props.selectedRefinementCriterion\r\n };\r\n this.anchorType = React.createRef();\r\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRefineItemProps, nextState: IRefineItemState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n selectedRefinementCriterion,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel,\r\n index,\r\n children,\r\n onToggle,\r\n context,\r\n telemetryContent,\r\n refineItemAriaLabel,\r\n refineItemsAriaLabel,\r\n yesText,\r\n noText,\r\n transitRefinerRecordId,\r\n ...attrs\r\n } = this.props;\r\n if (!productRefinerValue) {\r\n refineItemCommonProps.telemetry.error('[refine-item] Cannot render refineItem without productRefinerValue');\r\n return undefined;\r\n }\r\n if (!productRefinerValue.LeftValueBoundString) {\r\n refineItemCommonProps.telemetry.warning(\r\n `[refine-item] RefineItem without LeftValueBoundString: ${JSON.stringify(productRefinerValue)}`\r\n );\r\n }\r\n const isSingleSelect = parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect;\r\n let itemTypeClassName = isSingleSelect ? 'single-select' : 'multi-select';\r\n itemTypeClassName = `ms-refine-submenu-item ${itemTypeClassName}`;\r\n const inputType = isSingleSelect ? 'radio' : 'checkbox';\r\n const isChecked = !!selectedRefinementCriterion;\r\n itemTypeClassName = isChecked ? `${itemTypeClassName}-checked` : itemTypeClassName;\r\n if (parentProductRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) {\r\n return this._renderRating(\r\n productRefinerValue,\r\n parentProductRefinerHierarchy,\r\n isChecked,\r\n context,\r\n index,\r\n telemetryContent,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel\r\n );\r\n }\r\n let labelText = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString;\r\n\r\n if (transitRefinerRecordId && productRefinerValue.RefinerRecordId === Number(transitRefinerRecordId)) {\r\n if (labelText === '0') {\r\n labelText = noText ?? 'No';\r\n } else if (labelText === '1') {\r\n labelText = yesText ?? 'Yes';\r\n }\r\n }\r\n\r\n this.payLoad.contentAction.etext = labelText;\r\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const productText = labelText || '';\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const productCount = productRefinerValue.Count || 0;\r\n let refineMenuItemAriaLabel;\r\n if (productCount === 1) {\r\n refineMenuItemAriaLabel = refineItemAriaLabel\r\n ? format(refineItemAriaLabel, parentProductRefinerHierarchy.KeyName, productText)\r\n : '';\r\n } else {\r\n refineMenuItemAriaLabel = refineItemsAriaLabel\r\n ? format(refineItemsAriaLabel, parentProductRefinerHierarchy.KeyName, productText, productCount)\r\n : '';\r\n }\r\n\r\n const dimensionType = (this.props.parentProductRefinerHierarchy.KeyName?.toLocaleLowerCase() ?? '') as DimensionTypes;\r\n const shouldDisplayAsSwatch = this._getShouldDisplayAsSwatch(dimensionType);\r\n\r\n let className = 'ms-refine-submenu-item';\r\n if (shouldDisplayAsSwatch) {\r\n className = classnames(className, `ms-refine-submenu-item__dimension__${dimensionType}`);\r\n }\r\n\r\n // If the swatch has no color or image specified, it should be displayed as text.\r\n // We don't use swatch logic to display the number of the results found together with the text.\r\n const hasColor = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchColorHexCode);\r\n const hasImage = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchImageUrl);\r\n const hasContentSwatch = hasColor || hasImage;\r\n const tooltip = `${labelText}${productRefinerValue.Count !== undefined ? ` (${productRefinerValue.Count})` : ''}`;\r\n\r\n return (\r\n
  • \r\n \r\n {hasContentSwatch && shouldDisplayAsSwatch && this._renderSwatch(dimensionType)}\r\n \r\n \r\n
  • \r\n );\r\n }\r\n\r\n private _getShouldDisplayAsSwatch(dimensionType: DimensionTypes) {\r\n const shouldDisplayAsSwatch = checkIfShouldDisplayAsSwatch(dimensionType, this.props.context as ICoreContext);\r\n return shouldDisplayAsSwatch;\r\n }\r\n\r\n private _renderSwatch(dimensionType: DimensionTypes): JSX.Element | null {\r\n const productRefinerValue = this.props.productRefinerValue;\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const text = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n const swatchItems = [\r\n {\r\n itemId: `${productRefinerValue.RefinerRecordId ?? ''}-${dimensionType}-${text}`,\r\n value: text,\r\n dimensionType,\r\n colorHexCode: productRefinerValue.SwatchColorHexCode,\r\n imageUrl: productRefinerValue.SwatchImageUrl\r\n }\r\n ];\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n private _getRefinerUrl(): string {\r\n const { urlBuilder, parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n\r\n if (productRefinerValue) {\r\n return urlBuilder({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n }\r\n\r\n return '';\r\n }\r\n\r\n private readonly _onClick = (e: React.MouseEvent): void => {\r\n e.preventDefault();\r\n\r\n const { parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n if (productRefinerValue) {\r\n this.props.onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n\r\n setTimeout(() => {\r\n this.anchorType.current && this.anchorType.current.focus();\r\n }, 0);\r\n }\r\n };\r\n\r\n private _renderRating(\r\n productRefinerValue: ProductRefinerValue,\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy,\r\n isChecked: boolean,\r\n context: ICoreContext,\r\n index?: number,\r\n telemetryContent?: ITelemetryContent,\r\n ratingUserCountAriaLabel?: string,\r\n ratingSingleUserCountAriaLabel?: string\r\n ): JSX.Element | undefined {\r\n if (productRefinerValue.LeftValueBoundString) {\r\n this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString;\r\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\r\n const refinerRating = Number.parseInt(productRefinerValue.LeftValueBoundString, 10);\r\n const ratingRefiner = this.props.selectedRefinerValues?.find(\r\n value => value.DataTypeValue === productRefinerValue.DataTypeValue\r\n );\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const selectedRating = Number.parseInt(ratingRefiner?.LeftValueBoundString || '0', 10);\r\n const defaultChkProductCount = 1;\r\n let ratingComponentClass: string = 'ms-rating-component';\r\n if (refinerRating > selectedRating) {\r\n ratingComponentClass = `${ratingComponentClass}__up`;\r\n } else if (refinerRating < selectedRating) {\r\n ratingComponentClass = `${ratingComponentClass}__down`;\r\n } else {\r\n ratingComponentClass = `${ratingComponentClass}__current`;\r\n }\r\n const productCountAriaLabelValue =\r\n productRefinerValue.Count !== undefined && productRefinerValue.Count === defaultChkProductCount\r\n ? ratingSingleUserCountAriaLabel && format(ratingSingleUserCountAriaLabel, productRefinerValue.Count)\r\n : ratingUserCountAriaLabel && format(ratingUserCountAriaLabel, productRefinerValue.Count);\r\n return (\r\n \r\n \r\n \r\n \r\n {productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}\r\n \r\n \r\n \r\n );\r\n }\r\n return undefined;\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { DisplayTemplate, ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\nimport { Button, Collapse, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\r\nimport RefineItem from './refine-item';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { findMatchingRefinementCriterion, isRangeType } from './utilities';\r\n\r\n/**\r\n * Properties associated with the RefineSubmenu component.\r\n */\r\nexport interface IRefineSubmenuProps {\r\n tempRangeTypeTODO: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n productRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinerValues: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n isExpandedOnInitialLoad: boolean;\r\n context: ICoreContext>;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n productCountAriaLabel?: string;\r\n singleProductCountAriaLabel?: string;\r\n refineItemAriaLabel?: string;\r\n refineItemsAriaLabel?: string;\r\n isMobile?: boolean;\r\n yesText?: string;\r\n noText?: string;\r\n transitRefinerRecordId?: string;\r\n\r\n /**\r\n * The telemetry content\r\n */\r\n telemetryContent?: ITelemetryContent;\r\n onUpdateRefiners(notfication: Readonly): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine submenu state.\r\n */\r\nexport interface IRefineSubmenuState extends React.ComponentState {\r\n expanded: boolean;\r\n}\r\n\r\n/**\r\n *\r\n * The RefineSubmenu component renders the submenu category and child items.\r\n * This computed observes the stateful category hierarchy object.\r\n * @extends {React.PureComponent}\r\n */\r\nclass RefineSubmenu extends React.Component {\r\n private readonly MaxItems = 16;\r\n\r\n constructor(props: IRefineSubmenuProps) {\r\n super(props);\r\n\r\n this._onToggleItem = this._onToggleItem.bind(this);\r\n this._onToggleSubmenu = this._onToggleSubmenu.bind(this);\r\n\r\n const isExpanded = this.props.isExpandedOnInitialLoad;\r\n\r\n // If (this.props.productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range) {\r\n // isExpanded = true;\r\n // }\r\n\r\n this.state = {\r\n expanded: isExpanded,\r\n isShowFullList: props.productRefinerHierarchy.Values.length <= this.MaxItems\r\n };\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRefineSubmenuProps, nextState: IRefineSubmenuState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\r\n }\r\n\r\n if (productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating && this.props.context.app.config.hideRating) {\r\n return null;\r\n }\r\n\r\n const className = classnames(\r\n 'ms-refine-submenu',\r\n 'list-group',\r\n productRefinerHierarchy.KeyName // Deprecated because of the localization issues. Leaving for backward compatibility reasons.\r\n );\r\n\r\n return (\r\n
    \r\n \r\n {productRefinerHierarchy.KeyName}\r\n \r\n {\r\n // Simulate the 'resize' event so that sliders gets rendered correctly.\r\n // If not end Slider will always start a position 0 since hidden elements have no width.\r\n window.dispatchEvent(new Event('resize'));\r\n }}>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n \r\n
    \r\n );\r\n }\r\n\r\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n if (isRangeType(productRefinerHierarchy.DataTypeValue)) {\r\n return this._renderRange(productRefinerHierarchy);\r\n }\r\n return this._renderSingleMultiSelect(productRefinerHierarchy);\r\n }\r\n\r\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n selectedRefinerValues,\r\n context,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel,\r\n refineItemAriaLabel,\r\n refineItemsAriaLabel,\r\n isMobile\r\n } = this.props;\r\n const isSingleSelect =\r\n productRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect &&\r\n productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating;\r\n const role = isSingleSelect ? { role: 'listbox' } : undefined;\r\n const refinerValuesList = productRefinerHierarchy.Values || [];\r\n refinerValuesList.sort(\r\n (a, b) => (a.LeftValueBoundLocalizedString || a.LeftValueBoundString || '').localeCompare(b.LeftValueBoundLocalizedString || b.LeftValueBoundString || '', context.request.locale)\r\n );\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n if (index > (this.MaxItems - 1) && !this.state.isShowFullList) {\r\n return null;\r\n }\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n return (\r\n \r\n refinerValuesList.find(value => value.RefinerRecordId === selectedValue.RefinerRecordId)\r\n )}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n key={index}\r\n index={index}\r\n context={context}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n telemetryContent={this.props.telemetryContent}\r\n productCountAriaLabel={productCountAriaLabel}\r\n refineItemAriaLabel={refineItemAriaLabel}\r\n refineItemsAriaLabel={refineItemsAriaLabel}\r\n singleProductCountAriaLabel={singleProductCountAriaLabel}\r\n isMobileView={isMobile}\r\n yesText={this.props.yesText}\r\n noText={this.props.noText}\r\n transitRefinerRecordId={this.props.transitRefinerRecordId}\r\n />\r\n );\r\n });\r\n return (\r\n \r\n {listItems}\r\n {refinerValuesList.length > this.MaxItems && }\r\n \r\n );\r\n }\r\n\r\n private _getRangeType(productRefinerHierarchy: IProductRefinerHierarchy): 'input' | 'slider' {\r\n if (\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Range ||\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Slider ||\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.SliderWithBars\r\n ) {\r\n return 'slider';\r\n }\r\n return 'input';\r\n }\r\n\r\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n selectedRefinerValues,\r\n context,\r\n minValueSliderThumbAriaLabel,\r\n maxValueSliderThumbAriaLabel\r\n } = this.props;\r\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\r\n const refinerValuesList = productRefinerHierarchy.Values || [];\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n const rangeType = this._getRangeType(productRefinerHierarchy);\r\n const key = selectedRefinementCriterion\r\n ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}`\r\n : `not-selected-${index}`;\r\n return (\r\n
  • \r\n \r\n
  • \r\n );\r\n });\r\n return
      {listItems}
    ;\r\n }\r\n\r\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\r\n this.props.onUpdateRefiners(itemToggleNotification);\r\n }\r\n\r\n private _onToggleSubmenu(): void {\r\n this.setState(prevState => ({\r\n expanded: !prevState.expanded\r\n }));\r\n }\r\n}\r\n\r\nexport default RefineSubmenu;\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 { ITelemetry } from '@msdyn365-commerce/core';\r\nimport { AttributeDataType, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\n/**\r\n * Types of product refiner values.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerValueDataTypeValue {\r\n /**\r\n * Range slider is used for selections like price.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Range = 1,\r\n\r\n /**\r\n * Range input is a different way to specify ranges and can be expressed with input boxes\r\n * as well as a set of discrete single-select type values.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n RangeInput = 4,\r\n\r\n /**\r\n * This is a discrete list item, either multi-select or single-select.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n List = 5,\r\n\r\n /**\r\n * Boolean types allows only single-select.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Boolean = 6\r\n}\r\n\r\n/**\r\n * Types of product refiners.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerTypeValue {\r\n /**\r\n * Refiner values are single-select.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Single = 0,\r\n\r\n /**\r\n * Refiner values are multi-select.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Multi = 1\r\n}\r\n\r\n/**\r\n * ProductRefinerSource enum type.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerSource {\r\n /**\r\n * The None member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n None = 0,\r\n\r\n /**\r\n * The Attribute member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Attribute = 1,\r\n\r\n /**\r\n * The Category member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Category = 2,\r\n\r\n /**\r\n * The Price member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Price = 3,\r\n\r\n /**\r\n * The Rating member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Rating = 4\r\n}\r\n\r\n/**\r\n * Checks if the data type value corresponds to a slider.\r\n * @param dataTypeValue\r\n */\r\nexport function isRangeType(dataTypeValue: number | undefined): boolean {\r\n return (\r\n dataTypeValue === AttributeDataType.Currency ||\r\n dataTypeValue === AttributeDataType.Decimal ||\r\n dataTypeValue === AttributeDataType.Integer\r\n );\r\n}\r\n\r\nexport function isBoolean(dataTypeValue: number | undefined): boolean {\r\n return (\r\n dataTypeValue === AttributeDataType.TrueFalse);\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value.\r\n * @param productRefinerValue Product refiner value to match.\r\n * @param refinementCriteria Selected refinement criteria.\r\n */\r\nexport function findMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue | undefined {\r\n // If the value is a range, then match only on data type value; otherwise match on item string\r\n return refinementCriteria.find((refinementCriterion: ProductRefinerValue) =>\r\n isMatchingRefinementCriterion(productRefinerValue, refinementCriterion)\r\n );\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value.\r\n * @param productRefinerValue Product refiner value to match.\r\n * @param refinementCriteria Selected refinement criteria.\r\n * @param refinementCriterion\r\n */\r\nexport function isMatchingRefinementCriterion(productRefinerValue: ProductRefinerValue, refinementCriterion: ProductRefinerValue): boolean {\r\n // If the value is a range, then match only on data type value; otherwise match on item string\r\n return (\r\n refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\r\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\r\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\r\n (isRangeType(refinementCriterion.DataTypeValue) ||\r\n refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString)\r\n );\r\n}\r\n\r\nexport function getUpdatedRefinementCriteria(\r\n itemToggleNotification: IRefineItemToggleNotification,\r\n currentRefinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue[] {\r\n const updatedRefinementCriteria: ProductRefinerValue[] = [];\r\n let toggledItemFound = false;\r\n currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\r\n if (isMatchingRefinementCriterion(itemToggleNotification.productRefinerValue, selectedCriterion)) {\r\n toggledItemFound = true;\r\n if (itemToggleNotification.isSelecting) {\r\n const next = {\r\n ...selectedCriterion,\r\n LeftValueBoundString:\r\n (itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}`) ||\r\n selectedCriterion.LeftValueBoundString,\r\n RightValueBoundString:\r\n (itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}`) ||\r\n selectedCriterion.RightValueBoundString\r\n };\r\n updatedRefinementCriteria.push(next);\r\n } // Else the item is being de-selected, so omit it from the refinement criteria\r\n } else {\r\n // Keep existing criterion because it is not in the item toggle notification\r\n updatedRefinementCriteria.push(selectedCriterion);\r\n }\r\n });\r\n\r\n if (!toggledItemFound) {\r\n const next = {\r\n ...itemToggleNotification.productRefinerValue,\r\n LeftValueBoundString:\r\n (itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}`) ||\r\n itemToggleNotification.productRefinerValue.LeftValueBoundString,\r\n RightValueBoundString:\r\n (itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}`) ||\r\n itemToggleNotification.productRefinerValue.RightValueBoundString\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n // If single select, then deselect any others in the parent refiner group\r\n if (\r\n (itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.Text ||\r\n itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.TrueFalse) &&\r\n itemToggleNotification.parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect\r\n ) {\r\n itemToggleNotification.parentProductRefinerHierarchy.Values.forEach((child: ProductRefinerValue) => {\r\n if (child.RefinerRecordId === next.RefinerRecordId && child.LeftValueBoundString === next.LeftValueBoundString) {\r\n // Do nothing\r\n } else {\r\n const matchingIndex = updatedRefinementCriteria.findIndex((criterion: ProductRefinerValue) =>\r\n isMatchingRefinementCriterion(child, criterion)\r\n );\r\n if (matchingIndex > -1) {\r\n updatedRefinementCriteria.splice(matchingIndex, 1);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return updatedRefinementCriteria;\r\n}\r\n\r\nexport function formatPrice(\r\n amount: string | undefined,\r\n currency: string | undefined,\r\n locale: string | undefined,\r\n telemetry: ITelemetry\r\n): string {\r\n if (!amount || !currency) {\r\n telemetry.trace(`[refine-menu.utilities.formatPrice] could not format price for ${amount} ${currency}`);\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (error) {\r\n result = `${priceAmount} ${currency}`;\r\n telemetry.warning(`[refine-menu.utilities.formatPrice] Failed to format price for ${result}: ${error}`);\r\n }\r\n\r\n return result;\r\n}\r\n","import { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResultExt } from \"../../modules/dlvry-search-result-container/components\";\r\nimport { Customer } from '@msdyn365-commerce/retail-proxy';\r\nimport { hasAccessToBuy } from '.';\r\n\r\nexport interface OnBuyHasAccessValidatorResult {\r\n isValid: boolean;\r\n message?: string;\r\n}\r\n\r\nexport async function onBuyHasAccessValidator(\r\n context: ICoreContext,\r\n customer: Customer | undefined,\r\n product: ProductSearchResultExt,\r\n validationMessage: string | undefined\r\n): Promise {\r\n if (!product || !product.AttributeValues) {\r\n return { isValid: true };\r\n }\r\n\r\n const hasAccess = hasAccessToBuy(context, customer, product.AttributeValues);\r\n\r\n return {\r\n isValid: hasAccess,\r\n message: hasAccess ? undefined : validationMessage\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 { ICookieValue, ICookieContext } from '@msdyn365-commerce/core';\r\n\r\nexport const GetCookie = (cookies: ICookieContext, cookieName: string): string | undefined => {\r\n const marketCookie = cookies.get(cookieName) as ICookieValue | undefined;\r\n\r\n if (marketCookie && marketCookie.value && marketCookie.value.length > 0) {\r\n return marketCookie.value;\r\n } else {\r\n return undefined;\r\n }\r\n};\r\n\r\nexport const SetCookie = (cookies: ICookieContext, value: string, cookieName: string, exp: number): void => {\r\n if (value) {\r\n cookies.set(cookieName, value, { path: '/', maxAge: exp });\r\n }\r\n};\r\n"],"names":["GetOrganizationCustomerInput","constructor","apiSettings","user","getDataServiceRequest","this","query","createDataServiceRequestForOperation","Entities","bypassCache","returnEntity","shouldCacheOutput","getCacheKey","getCacheObjectType","dataCacheType","DataServiceQuery","getOrganizationCustomerAction","async","input","ctx","requestContext","isAuthenticated","callActionOrExecute","getOrganizationCustomer","createObservableDataAction","id","action","inputData","_user$customerAccount","customerAccountNumber","getProductUnitOfMeasureOptionsInput","queryResultSettings","productIds","resultSettings","top","getProductUnitOfMeasureOptionsAsync","context","request","callerContext","BaseCollectionInput","pageType","refiners","category","searchText","includeAttributes","isUpdateRefinerPanel","locale","catalogId","channelInventoryConfiguration","inventoryRefiner","_objectSpread","Paging","toJS","Sorting","generateCacheKey","key","value","map","refiner","RefinerRecordId","LeftValueBoundString","RightValueBoundString","convertToString","createBaseCollectionInput","args","inputClassConstuctor","urlTokens","categoryId","QueryResultSettingsProxy","fromInputData","QueryResultSettings","queryRefiners","hydrateRefinersFromUrl","config","undefined","_inputData$config","updateRefinerPanel","getUpdateRefinerPanel","getCatalogId","_args$requestContext$","sorting","Columns","JSON","parse","decodeURIComponent","itemId","q","recommendation","productId","stringify","ProductId","Recommendation","SearchText","Error","CachedPriceForProductSearchResultInput","products","productRecIds","ArrayExtensions","hasElements","Promise","resolve","product","RecordId","projectDomain","ChannelId","channelId","CatalogId","productPrices","getActivePricesAsync","getPagingFromInputDataOrDefaultValue","Date","productResults","activePrice","find","price","_activePrice$Customer","_activePrice$BasePric","_activePrice$TradeAgr","_activePrice$Adjusted","Badge","getDiscountBadge","Price","CustomerContextualPrice","BasePrice","Math","max","TradeAgreementPrice","AdjustedPrice","ProductPrice","PrefetchedPrice","error","telemetry","exception","debug","GetFullProductsByCollectionInput","length","ProductListInventoryFilteringOptions","returnProducts","productSearchResults","metadataCount","productSearchResultsWithImages","productSearchResult","newImageUrl","generateProductImageUrl","PrimaryImageUrl","app","inventoryLevel","InventoryLevels","threshold","enableStockCheck","count","AttributeValues","element","InventoryProductAttributeRecordId","inventoryRanges","TextValue","InventoryOutOfStockAttributeValueText","channelInventoryConfigurationId","inventoryAwareSortableAttributeId","ProductAvailabilitySortableAttributeRecordId","actionDataAction","_context$requestConte","_context$requestConte2","_context$requestConte3","_context$requestConte4","_context$requestConte5","promise","channelInventoryConfigurationPromise","searchProductId","searchCriteriaInput","Context","Refinement","slice","IncludeAttributes","SkipVariantExpansion","SearchCondition","index","_input$refiners$index","ExtensionProperties","addOrUpdateZeroPriceRefiner","shouldFilterAlcohol","addAlcoholRefinerAsync","addAllAttributeRefiners","AsyncResult","getInventoryConfigurationAsync","filter","isInStockRefiner","inventoryRefinerValue","getInventorySortableRefinerValue","some","push","productListInventoryDisplay","HideOOS","isInStock","inventoryInStockRefinerValue","prioritySortingAttribute","match","_input$queryResultSet","_input$queryResultSet2","priorityColumnName","column","ColumnName","IsDescending","SortOOS","_input$queryResultSet3","_input$queryResultSet4","sortColumnName","CategoryIds","searchByCriteriaAsync","searchObject","Number","isNaN","RecommendationListId","Ids","forEach","x","MaxVariantPrice","MinVariantPrice","getCachedPriceForProductSearchResultDataAction","metadata","Top","itemsPerPage","skip","Skip","sortOptions","sortByOptionRelevanceDesc","sortByOptionRatingAsc","sortByOptionRatingDesc","sortByOptionNameAsc","sortByOptionNameDesc","sortByOptionPriceAsc","sortByOptionPriceDesc","sortByOptionBestSelling","sortByOptionNewScore","sortByOptionTrendingScore","MappedSearchInput","buildCacheKey","getMappedSearchConfiguration","getSearchConfigurationAsync","then","searchConfiguration","ProductSortColumns","sortColumn","toUpperCase","warning","Boolean","createInput","getMappedSearchConfigurationDataAction","DefaultValues","RefinersByCollectionInput","getRefinersForCollectionDataAction","alcoholFilter","attributeRefiners","getAllAttributeRefiners","concat","getAlcoholRefiners","defaultRefiners","getProductRefinerHierarchy","defaultCategoryIdValue","defaultProductIdValue","DataTypeValue","AttributeDataType","TrueFalse","UnitText","RowNumber","Count","RefinerSourceValue","ProductRefinerSource","Attribute","_input$channelInvento2","_input$channelInvento3","inventoryProductAttributeRecordId","AlcoholGroupAttributeId","isGodmodeEnabled","godmode","url","requestUrl","searchParams","get","toLowerCase","doAlcoholFiltering","alcoholRefinerRecordId","alcoholGroupAttributeId","result","alcoholRefiner","alcoholLicenseValue","_customer$Attributes","customer","alcoholLicense","Attributes","AttributeValue","StringValue","console","warn","Array","fill","_","toString","addAlcoholRefiner","priceRefiner","_context$requestConte6","channel","Currency","getAttributeRefiners","customerAttributes","attributeRecordId","friendlyName","attributeValue","_customerAttributes$f","attribute","getForsvaretRefiner","_context$requestConte7","forsvaretAttributeId","forsvaretAttributeRecordId","_customerAttributes$f2","IntegerValue","Integer","addAttributeRefiner","_context$requestConte8","_context$requestConte9","_context$requestConte10","_context$requestConte11","_context$requestConte12","_context$requestConte13","attributeRecordIds","tobaccoRefinerRecordId","cocacolaRefinerRecordId","bamaRefinerRecordId","dutyFreeSugarRefinerRecordId","norturaRefinerRecordId","transitRefiner","transitRefinerRecordId","addAttributeRefinerKeepExisting","forsvaretRefiner","_context$requestConte14","_context$requestConte15","_context$requestConte16","_context$requestConte17","_context$requestConte18","_context$requestConte19","compressedRefinerKeys","compressedRefinerArray","parseQueryParam","compressedRefiner","parsedRefiner","refinerKey","_unused","buildListPageUrl","fullUrl","sortingColumns","skipCount","delete","sortedRefiners","sort","first","second","set","compressedRefiners","compressRefiners","href","getCurrentUrl","MsDyn365","isBrowser","URL","window","location","ChoiceSummary","React","props","super","closeButtonGlyph","_onClick","e","preventDefault","stopPropagation","target","currentTarget","clearAll","getAttribute","includes","selectedRefiner","_getSelectedRefinerChoice","onChoiceClicked","itemClicked","choiceClicked","nextItemToFocus","nextSibling","payLoad","getPayloadObject","telemetryContent","_this$props$context","selectedChoices","refinerHierarchy","choice","parent","hierarchy","Values","isMatchingRefinementCriterion","RefinerValue","_getKeyForRefinerValue","render","clearAllText","label","classNames","choiceAriaLabel","closeAriaLabel","yesLabel","noLabel","items","selectedRefinersMap","contentAction","etext","clearAllAttributes","getTelemetryAttributes","className","classnames","item","isBoolean","Object","assign","urlBuilder","onClick","role","style","fontWeight","LeftValueBoundLocalizedString","productRefinerValue","choiceFormat","choiceRangeValueFormat","refinerValues","overallFormat","rangeFormat","refinerValueName","refinerName","KeyName","isRangeType","replace","_formatPrice","filterValue","amount","currency","trace","cultureFormatter","formatCurrency","selected","__decorate","computed","observer","ErrorMessage","_ref","text","FeatureSearchResultItem","_context$request$app","imageSettings","resources","productName","Name","productRecordId","productUrl","getProductPageUrlSync","actionContext","fallbackImage","getFallbackImageUrl","ItemId","OmniChannelMedia","heading","featureSimilarDescriptionTitle","featureSimilarLooksTitle","onTelemetryClick","gridSettings","imageUrl","altText","img","src","imageProps","fallBackSrc","Image","loadFailureBehavior","renderProductPlacementImage","title","Link","ariaLabel","ModalToggle","innerRef","ref","SearchResultModal","modal","modalNode","modalHeader","modalHeaderNode","modalFooter","modalFooterNode","modalBody","ModalBody","Modal","autoFocus","applicationNode","returnFocusRef","returnRef","isOpen","toggle","onModalToggle","zIndex","ModalHeader","modalTitle","ModalFooter","Button","modalCloseButtonText","getInventoryLabel","productInventoryStatus","shippingInventory","shipping","ProductAvailableQuantity","StockLevelLabel","inventoryAttribute","callAddWishlistLine","wishlistId","toastErrorHeader","getCustomerAccount","AccountNumber","createdCommerceList","addLinesAsync","buildWishlistLine","update","createGetByCustomerInput","_error$data","_error$data2","toast","header","footer","data","CorrelationId","type","autoClose","position","canClose","showProgress","onClose","customerInput","GetCustomerInput","getCustomer","getWishlistButton","wishlists","defaultWishlistName","_wishlists$0$Commerce","isWishlisted","CommerceListLines","removeFromWishlistButtonText","addToWishlistButtonText","wishlistLineId","foundWishlistItem","commerceListLine","LineId","getWishlistLineIdFromProductId","removeLinesAsync","Id","commerceList","newWishlists","catch","_error$data5","_error$data6","removeItemFromWishlist","productInputs","productInput","ProductInput","simpleProduct","getSimpleProducts","getWishlistByCustomerId","addedProductToWishlistText","wishlistName","listData","CustomerId","CommerceListTypeValue","createCommerceListAsync","_error$data3","_error$data4","moveItemToWishlist","ProductSearchResultItems","cart","simpleProducts","customerInformation","orderTemplates","unitConversions","moduleType","moduleId","allowBackNavigation","quickviewSlot","productComparisonButton","isPriceMinMaxEnabled","productsDimensionAvailabilities","validatedProductAccess","disableBuyButtons","showPrices","productInventoryInformation","orderTemplatesState","setOrderTemplatesState","cartQueue","PQueue","concurrency","updateOrderTemplatesAsync","newOrderTemplates","newOrderTemplate","every","productList","splice","OrderTemplate","GetOrderTemplatesInput","getOrderTemplates","retrieveOrderTemplates","priceResources","priceRangeSeparator","_validatedProductAcce","ProductComponent","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","allowBack","typeName","ProductRecordId","buyAlwaysAdd","onUpdateOrderTemplates","quickViewButton","wishlistButton","inventoryLabel","inventoryStatus","disableBuyButton","showPrice","userHasAccess","HasAccess","swatchItemAriaLabel","addToCartText","updateCartText","removeFromCartText","outOfStockText","priceErrorText","toastStrings","errorHeader","productsAddedToCart","productsRemovedFromCart","productsUpdatedInCart","goToCart","toastGoToCart","noAccessToProduct","toastNoAccessToProduct","inCartTooltipText","transitTooltip","dimensionAvailabilities","dimensionAvailability","masterProductId","MasterProductId","addToOrderTemplateResources","addToOrderTemplateHeader","noOrderTemplatesMessage","noOrderTemplatesDescription","createAnOrderTemplateButtonText","createNewOrderTemplateButtonText","cancelOrderTemplateCreationButtonText","selectTemplatesText","addToTemplateButtonText","lineItemsText","createOrderTemplateHeader","orderTemplateTitle","orderTemplateNameAriaLabel","createOrderTemplateDescription","defaultOrderTemplateName","createOrderTemplateButtonText","cancelNewOrderTemplateCreationButtonText","viewOrderTemplateButtonText","continueShoppingButtonText","itemAddedToOrderTemplateHeaderItemOneText","itemAddedToOrderTemplateHeaderItemFormatText","itemAddedToOrderTemplateHeaderMessageText","duplicatedProductsHeader","duplicatedProductsDescription","updateQuantityButtonText","cancelDuplicateItemsButtonText","addToOrderTemplateButtonText","addToOrderTemplateButtonTooltip","onBuyValidate","onBuyHasAccessValidator","Separator","separator","Title","RangeRefineItem","_selectedRefinementCr","_this$props$selectedR","_this$props$selectedR2","_ref2","_this$props$selectedR3","_this$props$selectedR4","_formattedPriceReverseLookup","Map","getLabels","sliderId","minPrice","maxPrice","labelId","labelString","labelPositioning","getSliderThumbs","sliderKey","selectedMin","selectedMinPrice","selectedMax","selectedMaxPrice","_this$props$minValueS","_this$props$maxValueS","minValueSliderThumbAriaLabel","currencyCode","ariaValueText","maxValueSliderThumbAriaLabel","_onRangeUpdate","bind","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","minInput","maxInput","selectedRefinementCriterion","initialMin","initialMax","String","parentProductRefinerHierarchy","minValue","maxValue","labels","sliderKeyString","sliderThumbs","state","isChecked","validationErrorMin","validationErrorMax","touchedMin","touchedMax","shouldComponentUpdate","nextProps","nextState","componentDidUpdate","previousProps","updateSliderProps","refineItemCommonProps","rangeType","_renderInputFields","_renderSlider","_ref3","_this$props$selectedR5","_this$props$selectedR6","_ref4","_this$props$selectedR7","_this$props$selectedR8","setState","isDisabled","formAttrs","rangeNameFormat","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onChange","onFocus","onBlur","maxLabel","placeholder","placeholderTextMax","ariaAttributes","Slider","inForm","min","step","orientation","showLabels","showTooltip","onChangeEnd","debounce","handleTooltipText","event","_changeValue","inputType","selectedKey","touchedKey","_getInputWithoutFormatting","selectedMinValue","minTouched","onToggle","maxNum","validationErrorNaN","_focus","_validateRange","isSelecting","rangeStart","rangeEnd","selectedMaxValue","maxTouched","minNum","setTimeout","current","focus","touched","validationError","validationErrorRange","inputAsNum","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","document","getElementById","tooltip","RefineItem","anchorType","_this$props$parentPro","_this$props$parentPro2","_this$props","productCountAriaLabel","singleProductCountAriaLabel","children","refineItemAriaLabel","refineItemsAriaLabel","yesText","noText","attrs","_objectWithoutProperties","_excluded","isSingleSelect","RefinerTypeValue","RefinerType","SingleSelect","itemTypeClassName","SourceValue","Rating","_renderRating","labelText","productText","productCount","refineMenuItemAriaLabel","format","dimensionType","toLocaleLowerCase","shouldDisplayAsSwatch","_getShouldDisplayAsSwatch","hasColor","StringExtensions","isNullOrWhitespace","SwatchColorHexCode","hasImage","SwatchImageUrl","hasContentSwatch","_getRefinerUrl","tabIndex","_renderSwatch","checkIfShouldDisplayAsSwatch","_productRefinerValue$","swatchItems","colorHexCode","SwatchComponent","list","isSelectionEnabled","isRefineItem","ratingUserCountAriaLabel","ratingSingleUserCountAriaLabel","_productRefinerValue$2","refinerRating","parseInt","ratingRefiner","selectedRefinerValues","selectedRating","defaultChkProductCount","ratingComponentClass","productCountAriaLabelValue","isMobileView","RatingComponent","avgRating","ratingCount","hideCount","readOnly","moduleTypeName","RefineSubmenu","MaxItems","_onToggleItem","_onToggleSubmenu","isExpanded","isExpandedOnInitialLoad","expanded","isShowFullList","productRefinerHierarchy","hideRating","Collapse","timeout","onEntered","dispatchEvent","Event","_renderChildItems","_renderRange","_renderSingleMultiSelect","isMobile","refinerValuesList","a","b","localeCompare","listItems","child","findMatchingRefinementCriterion","selectedValue","_getRangeType","DisplayTemplateValue","DisplayTemplate","Range","SliderWithBars","itemToggleNotification","onUpdateRefiners","prevState","ProductRefinerValueDataTypeValue","ProductRefinerTypeValue","dataTypeValue","Decimal","refinementCriteria","refinementCriterion","getUpdatedRefinementCriteria","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","selectedCriterion","next","Text","matchingIndex","findIndex","criterion","validationMessage","isValid","hasAccess","hasAccessToBuy","message","GetCookie","cookies","cookieName","marketCookie","SetCookie","exp","path","maxAge"],"sourceRoot":""}