{"version":3,"file":"static/js/45391577bb0ce2c821a3.bundle.js","mappings":"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","sources":["webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/base-collection-action.ts?3323","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/get-inventory-refiners.ts?4245","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/get-full-products-by-collection.ts?f5b3","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/get-mapped-search-configuration.ts?3b1f","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/get-product-refiner-hierarchy.ts?9d69","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/get-refiners-for-collection.ts?59b3","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/actions/url-utils.ts?d952","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/choice-summary.tsx?dfb0","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/error-message.tsx?5fd9","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/feature-search-result-item.tsx?0e3e","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/link.tsx?67e3","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/modal.tsx?7e9d","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/product-search-result-items.tsx?b1c6","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/separator.tsx?2f27","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/title.tsx?5871","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/range-refine-item.tsx?7f6d","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/refine-item.tsx?8e94","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/refine-submenu.tsx?9c65","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/components/utilities.ts?e76c","webpack://Msdyn365.Commerce.Online/./src/modules/lobas-search-result-container/list-page-state.ts?87a7"],"sourcesContent":["/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 { convertToString, IQueryResultSettings, ProductRefinerValue, SortColumn } from '@msdyn365-commerce/retail-proxy';\r\nimport { buildCacheKey, 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 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 ) {\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 }\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 = buildCacheKey(\r\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- disabling this as inputs can be undefined depending on page type\r\n `${this.pageType}-${this.locale}-${this.category || this.searchText}-${this.catalogId}-${this.refiners.map(\r\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\r\n refiner => `${refiner.RefinerRecordId + (refiner.LeftValueBoundString || '') + (refiner.RightValueBoundString || '')}-`\r\n )}-${convertToString(queryResultSettings)}`,\r\n this.apiSettings,\r\n 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) => 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 undefined,\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) {\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 (\r\n pageType === 'Search' &&\r\n args.requestContext.query &&\r\n args.requestContext.query.productId &&\r\n args.requestContext.query.recommendation\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 JSON.stringify({ ProductId: args.requestContext.query.productId, Recommendation: args.requestContext.query.recommendation }),\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. All rights reserved.\r\n * See License.txt 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, getCatalogId } from '@msdyn365-commerce/core';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { BaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\r\n\r\n/**\r\n * InventoryInStockRefinerValue Input action.\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 input.queryResultSettings,\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 );\r\n\r\n this.inventoryProductAttributeRecordId = inventoryProductAttributeRecordId;\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 */\r\nasync function action(input: InventoryInStockRefinerValueInput, context: IActionContext): Promise {\r\n const catalogId = getCatalogId(context.requestContext);\r\n const refiners = await getProductRefinerHierarchy(\r\n {\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: catalogId\r\n }\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n\r\n return refiners.find(refiner => refiner.RecordId === input.inventoryProductAttributeRecordId) ?? null;\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 */\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","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 getCatalogId\r\n} from '@msdyn365-commerce/core';\r\nimport {\r\n AsyncResult,\r\n ChannelInventoryConfiguration,\r\n ProductRefinerValue,\r\n ProductSearchCriteria,\r\n ProductSearchResult\r\n} 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 { ArrayExtensions, generateProductImageUrl, InventoryLevels } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport getInventoryRefinersAction, { InventoryInStockRefinerValueInput } from './get-inventory-refiners';\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 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: ProductSearchResult[];\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 sorted products based on availability.\r\n * @param input - The GetFullProductsByCollectionInput input.\r\n * @param context - The context.\r\n * @param channelInventoryConfiguration - The channelInventoryConfiguration.\r\n * @returns Refiners.\r\n */\r\nasync function getInventoryInStockRefinerValueAsync(\r\n input: GetFullProductsByCollectionInput,\r\n context: IActionContext,\r\n channelInventoryConfiguration: ChannelInventoryConfiguration\r\n): Promise {\r\n const refinerInput = new InventoryInStockRefinerValueInput(input, channelInventoryConfiguration.InventoryProductAttributeRecordId);\r\n\r\n const inventoryRefiner = await getInventoryRefinersAction(refinerInput, context);\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- inventoryRefiner may be null\r\n return (\r\n inventoryRefiner?.Values.find(\r\n value =>\r\n value.LeftValueBoundString !== channelInventoryConfiguration.InventoryOutOfStockAttributeValueText &&\r\n value.RightValueBoundString !== channelInventoryConfiguration.InventoryOutOfStockAttributeValueText\r\n ) ?? null\r\n );\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 inventoryConfiguration = channelInventoryConfiguration ?? (await getInventoryConfigurationAsync({ callerContext: context }));\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: inventoryConfiguration ? inventoryConfiguration.InventoryProductAttributeRecordId : undefined,\r\n inventoryAwareSortableAttributeId: inventoryConfiguration\r\n ? inventoryConfiguration.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 searchProductId;\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n const catalogId = getCatalogId(context.requestContext);\r\n searchCriteriaInput.Context = { ChannelId: context.requestContext.apiSettings.channelId, CatalogId: catalogId };\r\n searchCriteriaInput.Refinement = input.refiners;\r\n searchCriteriaInput.IncludeAttributes = input.includeAttributes;\r\n searchCriteriaInput.SkipVariantExpansion = true;\r\n const defaultNumber: number = 0;\r\n\r\n const channelInventoryConfiguration = await getInventoryConfigurationAsync({ callerContext: context });\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- app configs are of generic type\r\n if (context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n const refinerValue = await getInventoryInStockRefinerValueAsync(input, context, channelInventoryConfiguration);\r\n const isInventoryAvailableRefinerValueExist = searchCriteriaInput.Refinement.some(\r\n value => value.RefinerRecordId === refinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryAvailableRefinerValueExist && refinerValue) {\r\n searchCriteriaInput.Refinement.push(refinerValue);\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) {\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?.productId && context.requestContext.query.recommendation) {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Existing code\r\n const searchObject = JSON.parse(input.searchText);\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Existing code\r\n searchProductId = Number(searchObject.ProductId);\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- Existing code\r\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\r\n searchCriteriaInput.Ids = [searchProductId || 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 }\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 const productSearchResults = await promise;\r\n return returnProducts(productSearchResults, context, promise.metadata.count, channelInventoryConfiguration);\r\n}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '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. All rights reserved.\r\n * See License.txt 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\ninterface SearchConfiguration {\r\n ProductSortColumns?: SortColumn[];\r\n}\r\n\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: '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. All rights reserved.\r\n * See License.txt 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 { IActionContext } from '@msdyn365-commerce/core';\r\nimport { IQueryResultSettings, ProductRefiner, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { getProductSearchRefinersAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\n\r\n/**\r\n * Uses Bulk refiner API to get refiners and child refiner values.\r\n * @param searchCriteria Product search criteria.\r\n * @param maxItems Max items.\r\n * @param queryResultSettings\r\n * @param ctx Action context.\r\n */\r\nexport async function getProductRefinerHierarchy(\r\n searchCriteria: ProductSearchCriteria,\r\n queryResultSettings: IQueryResultSettings,\r\n ctx: IActionContext\r\n): Promise {\r\n return getProductSearchRefinersAsync({ callerContext: ctx, queryResultSettings }, searchCriteria).then(\r\n (productRefiners: ProductRefiner[]) => {\r\n if (!productRefiners) {\r\n ctx.trace('[getRefinersByCriteriaAction] returned no refiners');\r\n return [];\r\n }\r\n\r\n const result = (productRefiners || []).map((productRefiner: ProductRefiner) => productRefiner);\r\n\r\n if (result.length === 0) {\r\n ctx.trace('[getRefinersByCriteriaAction] returned no IProductRefinerHierarchy objects');\r\n return [];\r\n }\r\n\r\n return result;\r\n }\r\n );\r\n}\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 {\r\n getCatalogId,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\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 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 ctx\r\n */\r\nasync function action(input: RefinersByCollectionInput, ctx: IActionContext): Promise {\r\n let searchProductId;\r\n const catalogId = getCatalogId(ctx.requestContext);\r\n if (input.pageType === 'Category') {\r\n if (input.category) {\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: catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? input.refiners : []\r\n },\r\n input.queryResultSettings,\r\n ctx\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 && ctx.requestContext.query && ctx.requestContext.query.q) {\r\n return getProductRefinerHierarchy(\r\n {\r\n SearchCondition: input.searchText,\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? input.refiners : []\r\n },\r\n input.queryResultSettings,\r\n ctx\r\n );\r\n }\r\n if (input.searchText && ctx.requestContext.query && ctx.requestContext.query.productId) {\r\n const searchObject = JSON.parse(input.searchText);\r\n searchProductId = Number(searchObject.ProductId);\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 return getProductRefinerHierarchy(\r\n {\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? input.refiners : [],\r\n RecommendationListId: searchObject.Recommendation,\r\n Ids: [searchProductId || DefaultValues.defaultProductIdValue]\r\n },\r\n input.queryResultSettings,\r\n ctx\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}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-refiners-for-collection',\r\n action: >action,\r\n input: createInput\r\n});\r\n\r\nexport default actionDataAction;\r\n","/* eslint-disable security/detect-object-injection */\r\n/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 return JSON.parse(decodeURIComponent(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. All rights reserved.\r\n * See License.txt 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 { isMatchingRefinementCriterion, isRangeType } from './utilities';\r\n\r\ninterface IRefinerMap {\r\n key: string;\r\n value: ProductRefinerValue;\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) => {\r\n return {\r\n key: this._getKeyForRefinerValue(selectedRefiner),\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 } = 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\r\n return (\r\n
  • \r\n \r\n {item.key}\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): string {\r\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry } = 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\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 {\r\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n }\r\n\r\n return overallFormat.replace('{0}', refinerName).replace('{1}', refinerValueName);\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(\r\n selected => (itemClicked.textContent && itemClicked.textContent.trim()) === selected.key\r\n );\r\n return (result && result.value) || undefined;\r\n }\r\n}\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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
{text}
\r\n
\r\n );\r\n};\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 { ILobasSearchResultContainerResources } from '../lobas-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: ILobasSearchResultContainerResources;\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(product.ItemId, context.actionContext.requestContext.apiSettings);\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. All rights reserved.\r\n * See License.txt 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. All rights reserved.\r\n * See License.txt 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. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport { IPriceComponentResources, ProductComponent } from '@msdyn365-commerce/components';\r\nimport { ICoreContext, IImageSettings } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport { ArrayExtensions } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { ILobasSearchResultContainerResources } from '../lobas-search-result-container.props.autogenerated';\r\n\r\ninterface IProductSearchResultItems {\r\n products: ProductSearchResult[];\r\n context: ICoreContext;\r\n resources: ILobasSearchResultContainerResources;\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 channelInventoryConfigurationId?: number;\r\n isPriceMinMaxEnabled?: boolean;\r\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\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 * @returns The inventory label.\r\n */\r\nexport function getInventoryLabel(channelInventoryConfigurationId: number | undefined, product: ProductSearchResult): string | undefined {\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\nexport const ProductSearchResultItems: React.FC = ({\r\n products,\r\n context,\r\n imageSettings,\r\n resources,\r\n moduleType,\r\n moduleId,\r\n allowBackNavigation,\r\n telemetryContent,\r\n quickviewSlot,\r\n channelInventoryConfigurationId,\r\n isPriceMinMaxEnabled,\r\n productsDimensionAvailabilities\r\n}) => {\r\n const priceResources: IPriceComponentResources = {\r\n priceRangeSeparator: resources.priceRangeSeparator\r\n };\r\n return (\r\n
    \r\n {products.map((product: ProductSearchResult, index: number) => (\r\n
  • \r\n \r\n ArrayExtensions.hasElements(dimensionAvailability) &&\r\n dimensionAvailability[0].masterProductId === product.MasterProductId\r\n )}\r\n />\r\n
  • \r\n ))}\r\n
\r\n );\r\n};\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 }) => {separator} ;\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 }) => {text} ;\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 { AttributeDataType } from '@msdyn365-commerce/retail-proxy';\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 =\r\n this.props.productRefinerValue.DataTypeValue !== AttributeDataType.Currency\r\n ? this._formatText(minValue, this.props.productRefinerValue.UnitText)\r\n : this._formatPrice(minValue);\r\n const maxPrice =\r\n this.props.productRefinerValue.DataTypeValue !== AttributeDataType.Currency\r\n ? this._formatText(maxValue, this.props.productRefinerValue.UnitText)\r\n : 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 const result = this.props.context.cultureFormatter.formatCurrency(Number(amount), this.currencyCode);\r\n return result;\r\n }\r\n\r\n private _formatText(value: string | undefined, unit: string | undefined): string {\r\n const result = `${value} ${unit}`;\r\n return result;\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 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 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 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. All rights reserved.\r\n * See License.txt 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 * 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\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 ...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 this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString ?? productRefinerValue.LeftValueBoundString;\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 = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\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 return (\r\n
  • \r\n \r\n {this._renderSwatch()}\r\n \r\n \r\n
  • \r\n );\r\n }\r\n\r\n private _renderSwatch(): JSX.Element | null {\r\n const productRefinerValue = this.props.productRefinerValue;\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\r\n const dimensionType = (this.props.parentProductRefinerHierarchy.KeyName?.toLocaleLowerCase() ?? '') as DimensionTypes;\r\n const hasColor = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchColorHexCode);\r\n const hasImage = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchImageUrl);\r\n const hasValidSwatch = hasColor || hasImage;\r\n const shouldDisplayAsSwatch =\r\n hasValidSwatch && checkIfShouldDisplayAsSwatch(dimensionType, this.props.context as ICoreContext);\r\n const swatchItems = shouldDisplayAsSwatch\r\n ? [\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 : undefined;\r\n\r\n if (!swatchItems) {\r\n return null;\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. All rights reserved.\r\n * See License.txt 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 * 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\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 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 };\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 return (\r\n
    \r\n \r\n {productRefinerHierarchy.KeyName}\r\n \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 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\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 />\r\n );\r\n });\r\n return (\r\n \r\n {listItems}\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. All rights reserved.\r\n * See License.txt 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\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","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt 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 {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { ProductPrice, ProductRefinerValue, ProductSearchResult, SimpleProduct, SortingInfo } from '@msdyn365-commerce/retail-proxy';\r\nimport { observable } from 'mobx';\r\n\r\nimport { listPageType } from './actions';\r\n\r\n/**\r\n * ListPageState class.\r\n */\r\nexport class ListPageState {\r\n @observable public activeFilters: ProductRefinerValue[] | null = null;\r\n\r\n @observable public activeProducts: ProductSearchResult[] = [];\r\n\r\n @observable public sortingCritera: SortingInfo | null = null;\r\n\r\n @observable public currentPageNumber: number | null = null;\r\n\r\n @observable public refiners: IProductRefinerHierarchy[] | null = null;\r\n\r\n @observable public totalProductCount: number | undefined;\r\n\r\n @observable public pageSize: number = 10;\r\n\r\n @observable public pageType: listPageType = 'Unknown';\r\n\r\n @observable public featureProduct: SimpleProduct | null = null;\r\n\r\n @observable public productPrices: ProductPrice[] | undefined = [];\r\n}\r\n\r\n/**\r\n * ListPageStateInput - action input.\r\n */\r\nexport class ListPageStateInput implements IActionInput {\r\n public getCacheKey = () => 'ListPageState';\r\n\r\n public getCacheObjectType = () => 'ListPageState';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\nexport async function listPageStateAction(input: ListPageStateInput, ctx: IActionContext): Promise {\r\n return new ListPageState();\r\n}\r\n\r\n/**\r\n * Create new input for create action.\r\n * @param inputData\r\n */\r\nexport const createListPageInput = (inputData: ICreateActionContext>): IActionInput => {\r\n return new ListPageStateInput();\r\n};\r\n\r\n/**\r\n * ListPageState - create action.\r\n */\r\nexport default createObservableDataAction({\r\n action: >listPageStateAction,\r\n input: createListPageInput\r\n});\r\n"],"names":["BaseCollectionInput","constructor","pageType","apiSettings","queryResultSettings","refiners","category","searchText","includeAttributes","isUpdateRefinerPanel","locale","catalogId","getCacheKey","_objectSpread","this","Paging","toJS","Sorting","buildCacheKey","map","refiner","RefinerRecordId","LeftValueBoundString","RightValueBoundString","convertToString","getCacheObjectType","dataCacheType","createBaseCollectionInput","args","inputClassConstuctor","requestContext","urlTokens","query","categoryId","QueryResultSettingsProxy","QueryResultSettings","queryRefiners","hydrateRefinersFromUrl","inputData","config","undefined","_inputData$config","updateRefinerPanel","getUpdateRefinerPanel","getCatalogId","sorting","Columns","JSON","parse","decodeURIComponent","itemId","q","productId","recommendation","stringify","ProductId","Recommendation","Error","InventoryInStockRefinerValueInput","input","inventoryProductAttributeRecordId","arguments","length","super","createObservableDataAction","id","action","async","context","_refiners$find","getProductRefinerHierarchy","Context","ChannelId","channelId","CatalogId","find","RecordId","GetFullProductsByCollectionInput","ProductListInventoryFilteringOptions","returnProducts","productSearchResults","metadataCount","channelInventoryConfiguration","productSearchResultsWithImages","productSearchResult","newImageUrl","generateProductImageUrl","PrimaryImageUrl","app","inventoryLevel","InventoryLevels","enableStockCheck","products","count","inventoryConfiguration","getInventoryConfigurationAsync","callerContext","ArrayExtensions","AttributeValues","element","InventoryProductAttributeRecordId","inventoryRanges","TextValue","InventoryOutOfStockAttributeValueText","channelInventoryConfigurationId","inventoryAwareSortableAttributeId","ProductAvailabilitySortableAttributeRecordId","actionDataAction","_context$requestConte","_context$requestConte2","_context$requestConte3","_context$requestConte4","_context$requestConte5","promise","searchProductId","searchCriteriaInput","Refinement","IncludeAttributes","SkipVariantExpansion","productListInventoryDisplay","HideOOS","refinerValue","_inventoryRefiner$Val","refinerInput","inventoryRefiner","getInventoryRefinersAction","Values","value","getInventoryInStockRefinerValueAsync","some","push","SortOOS","_input$queryResultSet","_input$queryResultSet2","sortColumnName","column","ColumnName","IsDescending","CategoryIds","searchByCriteriaAsync","SearchCondition","searchObject","Number","isNaN","RecommendationListId","Ids","metadata","Top","itemsPerPage","skip","Skip","sortOptions","sortByOptionRelevanceDesc","sortByOptionRatingAsc","sortByOptionRatingDesc","sortByOptionNameAsc","sortByOptionNameDesc","sortByOptionPriceAsc","sortByOptionPriceDesc","sortByOptionBestSelling","sortByOptionNewScore","sortByOptionTrendingScore","MappedSearchInput","getMappedSearchConfiguration","ctx","getSearchConfigurationAsync","then","searchConfiguration","ProductSortColumns","sortColumn","key","toUpperCase","telemetry","warning","filter","Boolean","createInput","getMappedSearchConfigurationDataAction","searchCriteria","getProductSearchRefinersAsync","productRefiners","trace","result","productRefiner","DefaultValues","RefinersByCollectionInput","defaultCategoryIdValue","defaultProductIdValue","compressedRefinerKeys","compressedRefinerArray","parseQueryParam","compressedRefiner","parsedRefiner","forEach","refinerKey","index","_unused","buildListPageUrl","fullUrl","sortingColumns","skipCount","searchParams","delete","sortedRefiners","sort","first","second","set","compressedRefiners","compressRefiners","href","toString","getCurrentUrl","MsDyn365","URL","window","location","url","requestUrl","ChoiceSummary","React","props","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","isMatchingRefinementCriterion","_getKeyForRefinerValue","render","clearAllText","label","classNames","choiceAriaLabel","closeAriaLabel","items","selectedRefinersMap","contentAction","etext","clearAllAttributes","getTelemetryAttributes","className","classnames","item","attribute","Object","assign","urlBuilder","onClick","role","productRefinerValue","choiceFormat","choiceRangeValueFormat","overallFormat","rangeFormat","refinerValueName","refinerName","KeyName","isRangeType","DataTypeValue","replace","_formatPrice","UnitText","LeftValueBoundLocalizedString","amount","currency","cultureFormatter","formatCurrency","error","selected","textContent","trim","__decorate","computed","observer","ErrorMessage","_ref","text","FeatureSearchResultItem","product","imageSettings","resources","productName","Name","productRecordId","productUrl","getProductPageUrlSync","actionContext","fallbackImage","getFallbackImageUrl","ItemId","heading","featureSimilarDescriptionTitle","featureSimilarLooksTitle","onTelemetryClick","gridSettings","imageUrl","altText","img","src","imageProps","fallBackSrc","Image","loadFailureBehavior","renderProductPlacementImage","request","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","inventoryAttribute","ProductSearchResultItems","moduleType","moduleId","allowBackNavigation","quickviewSlot","isPriceMinMaxEnabled","productsDimensionAvailabilities","priceResources","priceRangeSeparator","ProductComponent","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","allowBack","typeName","data","quickViewButton","inventoryLabel","swatchItemAriaLabel","dimensionAvailabilities","dimensionAvailability","masterProductId","MasterProductId","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","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","AttributeDataType","_formatText","setState","isDisabled","formAttrs","rangeNameFormat","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onChange","onFocus","onBlur","maxLabel","placeholder","placeholderTextMax","ariaAttributes","Slider","inForm","min","max","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","currencyCode","unit","inputAsNum","get","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","document","getElementById","tooltip","RefineItem","anchorType","_productRefinerValue$","_this$props","productCountAriaLabel","singleProductCountAriaLabel","children","refineItemAriaLabel","refineItemsAriaLabel","attrs","_objectWithoutProperties","_excluded","isSingleSelect","RefinerTypeValue","RefinerType","itemTypeClassName","SourceValue","ProductRefinerSource","_renderRating","productText","productCount","Count","refineMenuItemAriaLabel","format","_getRefinerUrl","tabIndex","_renderSwatch","_this$props$parentPro","_this$props$parentPro2","_productRefinerValue$2","dimensionType","toLocaleLowerCase","hasColor","StringExtensions","SwatchColorHexCode","hasImage","SwatchImageUrl","swatchItems","checkIfShouldDisplayAsSwatch","colorHexCode","SwatchComponent","list","isSelectionEnabled","isRefineItem","ratingUserCountAriaLabel","ratingSingleUserCountAriaLabel","_productRefinerValue$3","refinerRating","parseInt","ratingRefiner","selectedRefinerValues","selectedRating","defaultChkProductCount","ratingComponentClass","productCountAriaLabelValue","isMobileView","RatingComponent","avgRating","ratingCount","hideCount","readOnly","moduleTypeName","RefineSubmenu","_onToggleItem","_onToggleSubmenu","isExpanded","isExpandedOnInitialLoad","expanded","productRefinerHierarchy","hideRating","Collapse","timeout","_renderChildItems","_renderRange","_renderSingleMultiSelect","isMobile","refinerValuesList","listItems","child","findMatchingRefinementCriterion","selectedValue","_getRangeType","DisplayTemplateValue","DisplayTemplate","itemToggleNotification","onUpdateRefiners","prevState","ProductRefinerValueDataTypeValue","ProductRefinerTypeValue","dataTypeValue","refinementCriteria","refinementCriterion","RefinerSourceValue","getUpdatedRefinementCriteria","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","selectedCriterion","next","matchingIndex","findIndex","criterion","splice","ListPageState","activeFilters","activeProducts","sortingCritera","currentPageNumber","pageSize","featureProduct","productPrices","observable","ListPageStateInput","listPageStateAction","createListPageInput"],"sourceRoot":""}