{"version":3,"file":"static/js/06e63b14ed55dab6b29e.bundle.js","mappings":"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","sources":["webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/base-collection-action.ts?ec13","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/get-full-products-by-collection.ts?f1fe","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/get-mapped-search-configuration.ts?6cc4","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/get-refiners-for-collection.ts?56d8","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/get-product-refiner-hierarchy.ts?3937","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/actions/url-utils.ts?1541","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/list-page-state.ts?b0a4","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/utilities.ts?8569","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/choice-summary.tsx?3f71","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/error-message.tsx?6302","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/feature-search-result-item.tsx?71fa","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/link.tsx?52c2","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/modal.tsx?d78e","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/product-search-result-items.tsx?5174","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/range-refine-item.tsx?6288","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/refine-item.tsx?a594","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/refine-submenu.tsx?1292","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/separator.tsx?4ea6","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/components/title.tsx?c269","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/search-result-container.tsx?7500","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search-result-container/search-result-container.view.tsx?b779","webpack://@msdyn365-commerce-partners/fabrikam/./src/search-state-data-action.ts?8223","webpack://@msdyn365-commerce-partners/fabrikam/./src/search-state.ts?dd10","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/actions/get-auto-suggest-suggestions.ts?4735","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/components/search.categorysuggest.tsx?c65d","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/components/search.form.tsx?25a5","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/components/search.keywordsuggest.tsx?297c","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/components/search.label.tsx?0c17","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/components/search.productsuggest.tsx?2af9","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/search.tsx?72fb","webpack://@msdyn365-commerce-partners/fabrikam/./src/modules/search/search.view.tsx?1505"],"sourcesContent":["/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport {\n CacheType,\n getCatalogId,\n IActionInput,\n IAny,\n ICommerceApiSettings,\n ICreateActionContext,\n IGeneric\n} from '@msdyn365-commerce/core';\nimport { convertToString, IQueryResultSettings, ProductRefinerValue, SortColumn } from '@msdyn365-commerce/retail-proxy';\nimport {\n buildCacheKey,\n QueryResultSettingsProxy\n} from '@msdyn365-commerce-modules/retail-actions';\nimport { toJS } from 'mobx';\n\nimport { hydrateRefinersFromUrl } from './url-utils';\n\n/**\n * Export listPageType.\n */\nexport type listPageType = 'Category' | 'Search' | 'Unknown';\n\n/**\n * Get include attributes from config.\n * @param inputData - ICreateActionContext.\n * @returns Boolean.\n */\nfunction getIncludeAttributes(inputData: ICreateActionContext, IGeneric>): boolean {\n if (inputData &&\n inputData.config &&\n inputData.config.includeAttributes !== undefined &&\n inputData.config.includeAttributes === true) {\n return true;\n }\n return false;\n}\n\n/**\n * Get updateRefinerPanel from config.\n * @param inputData - ICreateActionContext.\n * @returns Boolean.\n */\nfunction getUpdateRefinerPanel(inputData: ICreateActionContext, IGeneric>): boolean {\n return !!inputData.config?.updateRefinerPanel;\n}\n\n/**\n * BaseCollection Action Input.\n */\nexport class BaseCollectionInput implements IActionInput {\n public pageType: listPageType;\n\n public category: number | undefined;\n\n public searchText: string | undefined;\n\n public refiners: ProductRefinerValue[];\n\n public queryResultSettings: IQueryResultSettings;\n\n public apiSettings: ICommerceApiSettings;\n\n public includeAttributes: boolean | undefined;\n\n public locale?: string;\n\n public isUpdateRefinerPanel?: boolean;\n\n public catalogId?: number;\n\n public constructor(\n pageType: listPageType,\n apiSettings: ICommerceApiSettings,\n queryResultSettings: IQueryResultSettings,\n refiners: ProductRefinerValue[],\n category: number | undefined,\n searchText: string | undefined,\n includeAttributes: boolean | undefined,\n isUpdateRefinerPanel?: boolean | undefined,\n locale?: string,\n catalogId?: number\n ) {\n this.pageType = pageType;\n this.apiSettings = apiSettings;\n this.category = category;\n this.searchText = searchText;\n this.queryResultSettings = queryResultSettings;\n this.refiners = refiners;\n this.includeAttributes = includeAttributes;\n this.isUpdateRefinerPanel = isUpdateRefinerPanel;\n this.locale = locale;\n this.catalogId = catalogId;\n }\n\n public getCacheKey = () => {\n const queryResultSettings = {\n ...this.queryResultSettings.Paging,\n ...toJS(this.queryResultSettings.Sorting)\n };\n\n const cacheKey = buildCacheKey(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- disabling this as inputs can be undefined depending on page type\n `${this.pageType}-${this.locale}-${this.category || this.searchText}-${this.catalogId}-${this.refiners.map(refiner => `${refiner.RefinerRecordId + (refiner.LeftValueBoundString || '') + (refiner.RightValueBoundString || '')}-`)}-${convertToString(queryResultSettings)}`, this.apiSettings, this.locale\n );\n return cacheKey;\n };\n\n public getCacheObjectType = () => 'CollectionActionResult';\n\n public dataCacheType = (): CacheType => 'request';\n}\n\n// TODO: Create a data model here or import one to capture the response of the action\nexport interface IGetFullProductsByCollectionData {\n text: string;\n}\n\nexport type CollectionClassConstructor = new (\n pageType: listPageType,\n apiSettings: ICommerceApiSettings,\n queryResultSettings: IQueryResultSettings,\n refiners: ProductRefinerValue[],\n category: number | undefined,\n searchText: string | undefined,\n includeAttributes: boolean | undefined,\n isUpdateRefinerPanel?: boolean | undefined,\n locale?: string,\n catalogId?: number\n) => BaseCollectionInput;\n\n/**\n * TODO: Use this function to create the input required to make the action call.\n * @param args\n * @param inputClassConstuctor\n */\nexport const createBaseCollectionInput = (\n args: ICreateActionContext,\n inputClassConstuctor: CollectionClassConstructor\n): BaseCollectionInput => {\n const pageType =\n args.requestContext.urlTokens.pageType === 'Category' || (args.requestContext.query && args.requestContext.query.categoryId) ? 'Category' : 'Search';\n\n const queryResultSettings = QueryResultSettingsProxy.fromInputData(args).QueryResultSettings;\n const queryRefiners = hydrateRefinersFromUrl(args.requestContext);\n const includeAttributes = getIncludeAttributes(args);\n const isUpdateRefinerPanel = getUpdateRefinerPanel(args);\n const catalogId = getCatalogId(args.requestContext);\n\n if (args.requestContext.query && args.requestContext.query.sorting) {\n queryResultSettings.Sorting = { Columns: JSON.parse(decodeURIComponent(args.requestContext.query.sorting)) };\n }\n\n if (pageType === 'Category') {\n return new inputClassConstuctor(\n pageType,\n args.requestContext.apiSettings,\n queryResultSettings,\n queryRefiners,\n +(args.requestContext.urlTokens.itemId || (args.requestContext.query && args.requestContext.query.categoryId) || 0),\n undefined,\n includeAttributes,\n isUpdateRefinerPanel,\n args.requestContext.locale,\n catalogId\n );\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.q) {\n return new inputClassConstuctor(\n pageType,\n args.requestContext.apiSettings,\n queryResultSettings,\n queryRefiners,\n undefined,\n args.requestContext.query.q,\n includeAttributes,\n isUpdateRefinerPanel,\n args.requestContext.locale,\n catalogId\n );\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.productId && args.requestContext.query.recommendation) {\n return new inputClassConstuctor(\n pageType,\n args.requestContext.apiSettings,\n queryResultSettings,\n queryRefiners,\n undefined,\n JSON.stringify({ ProductId: args.requestContext.query.productId, Recommendation: args.requestContext.query.recommendation }),\n includeAttributes,\n isUpdateRefinerPanel,\n args.requestContext.locale,\n catalogId\n );\n }\n\n throw new Error('[getFullProductsForCollection]Unable to create input');\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport MsDyn365, {\n CacheType,\n createObservableDataAction,\n IAction,\n IActionContext,\n IActionInput,\n ICreateActionContext\n} from '@msdyn365-commerce/core';\nimport { AsyncResult, ChannelInventoryConfiguration, ProductSearchCriteria, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\nimport { getInventoryConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\nimport { ArrayExtensions, generateProductImageUrl, InventoryLevels, ObjectExtensions } from '@msdyn365-commerce-modules/retail-actions';\n\nimport { ListPageStateInput } from '../list-page-state';\nimport {\n BaseCollectionInput,\n createBaseCollectionInput\n} from './base-collection-action';\n\n/**\n * GetFullProductsByCollection Action Input.\n */\nexport class GetFullProductsByCollectionInput extends BaseCollectionInput implements IActionInput {\n /**\n * The cache object type.\n * @returns The cache object type.\n */\n public getCacheObjectType = (): string => 'FullProductSearchResult';\n\n /**\n * The data cache type.\n * @returns The data cache type.\n */\n public dataCacheType = (): CacheType => {\n if (\n this.pageType !== 'Category' ||\n (this.refiners && this.refiners.length > 0) ||\n (this.queryResultSettings && this.queryResultSettings.Sorting && this.queryResultSettings.Sorting.Columns && this.queryResultSettings.Sorting.Columns.length > 0)\n ) {\n return 'request';\n }\n return 'application';\n\n };\n}\n\n/**\n * This setting defines inventory filtering options.\n */\nexport enum ProductListInventoryFilteringOptions {\n\n /**\n * Filter out all products out of stock.\n */\n HideOOS = 'hideOOS',\n\n /**\n * Sort products by availability, OOS goes last.\n */\n SortOOS = 'sortOOS',\n\n /**\n * No filtering selected.\n */\n Default = 'default'\n}\n\n/**\n * The full product search result with count interface.\n */\nexport interface IFullProductsSearchResultsWithCount {\n products: ProductSearchResult[];\n count: number;\n channelInventoryConfigurationId?: number;\n}\n\n/**\n * CreateInput function which creates and actionInput used to fetch products for a list page.\n * @param args - The API arguments.\n * @returns IActionInput - The action input.\n */\nconst createInput = (args: ICreateActionContext<{ itemsPerPage: number ;includedAttributes: boolean | undefined }>): IActionInput => {\n const input = createBaseCollectionInput(args, GetFullProductsByCollectionInput);\n\n // Set Top\n if (input.queryResultSettings.Paging && args.config) {\n input.queryResultSettings.Paging.Top = args.config.itemsPerPage || 1;\n }\n\n // Set Skip\n if (input.queryResultSettings.Paging && args.requestContext.query && args.requestContext.query.skip) {\n input.queryResultSettings.Paging.Skip = +args.requestContext.query.skip;\n }\n\n input.queryResultSettings.count = true;\n\n return input;\n};\n\n/**\n * Finds whether a product is out of stock based on the attribute.\n * @param product - The product.\n * @param channelInventoryConfiguration - The channel configuration.\n * @returns True if is OOS, false otherwise.\n */\nfunction isOutOfStock(product: ProductSearchResult, channelInventoryConfiguration: ChannelInventoryConfiguration): boolean {\n if (!ArrayExtensions.hasElements(product.AttributeValues)) {\n // If no attributes then assume is in stock\n return false;\n }\n for (const attribute of product.AttributeValues) {\n if (attribute.RecordId === channelInventoryConfiguration.InventoryProductAttributeRecordId &&\n attribute.TextValue === channelInventoryConfiguration.InventoryOutOfStockAttributeValueText) {\n // The matching recordId indicates that is the inventory attribute\n // if the text value are the same then is out of stock.\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Returns only in stock products.\n * @param products - The product.\n * @param channelInventoryConfiguration - The channel configuration.\n * @returns Filtered product search result.\n */\nfunction filterOutOfStockProducts(\n products: ProductSearchResult[],\n channelInventoryConfiguration: ChannelInventoryConfiguration): ProductSearchResult[] {\n if (!ArrayExtensions.hasElements(products)) {\n return [];\n }\n const filteredProducts: ProductSearchResult[] = [];\n\n for (const product of products) {\n if (!isOutOfStock(product, channelInventoryConfiguration)) {\n filteredProducts.push(product);\n }\n }\n return filteredProducts;\n}\n\n/**\n * Returns sorted products based on availability.\n * @param products - The product.\n * @param channelInventoryConfiguration - The channel configuration.\n * @returns Sorted product search result.\n */\nfunction sortsProductsBasedOnAvailability(\n products: ProductSearchResult[],\n channelInventoryConfiguration: ChannelInventoryConfiguration): ProductSearchResult[] {\n\n if (!ArrayExtensions.hasElements(products)) {\n return [];\n }\n const inStockProducts: ProductSearchResult[] = [];\n const outOfStockProducts: ProductSearchResult[] = [];\n\n for (const product of products) {\n if (isOutOfStock(product, channelInventoryConfiguration)) {\n outOfStockProducts.push(product);\n } else {\n inStockProducts.push(product);\n }\n }\n return inStockProducts.concat(outOfStockProducts);\n}\n\n/**\n * Returns list of products based on inventory information.\n * @param products - The products.\n * @param channelInventoryConfiguration - The channel configuration.\n * @param context - The context.\n * @returns List of product based on the inventory information.\n */\nexport function returnProductsBasedOnInventoryInformation(\n products: ProductSearchResult[],\n channelInventoryConfiguration: ChannelInventoryConfiguration,\n context: IActionContext): ProductSearchResult[] {\n if (!ArrayExtensions.hasElements(products) || ObjectExtensions.isNullOrUndefined(channelInventoryConfiguration)) {\n return [];\n }\n switch (context.requestContext.app.config.productListInventoryDisplay) {\n case ProductListInventoryFilteringOptions.HideOOS:\n return filterOutOfStockProducts(products, channelInventoryConfiguration);\n case ProductListInventoryFilteringOptions.SortOOS:\n return sortsProductsBasedOnAvailability(products, channelInventoryConfiguration);\n default:\n return products;\n }\n}\n\n/**\n * Returns list of products based on inventory information.\n * @param productSearchResults - The products.\n * @param context - The context.\n * @param metadataCount - The metadata count.\n * @returns List of product based on the inventory information.\n */\nexport async function returnProducts(\n productSearchResults: ProductSearchResult[],\n context: IActionContext,\n metadataCount: number | undefined): Promise {\n\n const defaultProductCount: number = 0;\n\n const productSearchResultsWithImages = productSearchResults.map(productSearchResult => {\n const newImageUrl = generateProductImageUrl(\n productSearchResult,\n context.requestContext.apiSettings\n );\n\n if (newImageUrl) {\n productSearchResult.PrimaryImageUrl = newImageUrl;\n }\n\n return (productSearchResult);\n });\n\n // If inventory level is threshold or inventory check is disabled then return the list of products without the inventory configuration\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\n if (context.requestContext.app.config.inventoryLevel === InventoryLevels.threshold || context.requestContext.app.config.enableStockCheck === false) {\n return {\n products: productSearchResultsWithImages,\n count: metadataCount ?? defaultProductCount\n };\n }\n const channelInventoryConfiguration = await getInventoryConfigurationAsync({ callerContext: context });\n\n const mappedProducts = productSearchResultsWithImages.map(productSearchResult => {\n if (ArrayExtensions.hasElements(productSearchResult.AttributeValues)) {\n for (const element of productSearchResult.AttributeValues) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- need check.\n if (channelInventoryConfiguration &&\n element.RecordId !== undefined &&\n element.RecordId === channelInventoryConfiguration.InventoryProductAttributeRecordId &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\n context.requestContext.app.config.inventoryRanges !== 'all' &&\n element.TextValue !== channelInventoryConfiguration.InventoryOutOfStockAttributeValueText) {\n // If same RecordId then it means that is the Inventory attribute\n // Based on the inventory range (and filtering options), the inventory label will be displayed\n // If Inventory range is 'All' then in stock and out of stock labels are shown, else only OOS\n // if the text value is different that the channelInventoryConfiguration.InventoryOutOfStockAttributeValueText then is in stock\n element.TextValue = '';\n }\n }\n }\n\n return (productSearchResult);\n });\n const productsBasedOnInventory = returnProductsBasedOnInventoryInformation(mappedProducts, channelInventoryConfiguration, context);\n return {\n products: productsBasedOnInventory,\n count: metadataCount ?? defaultProductCount,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- check config.\n channelInventoryConfigurationId: channelInventoryConfiguration ? channelInventoryConfiguration.InventoryProductAttributeRecordId : undefined\n };\n}\n\n/**\n * Action function to fetch products for a list page.\n * @param input - The input.\n * @param context - The context.\n * @returns IFullProductsSearchResultsWithCount - The full product search result with count.\n */\nasync function action(\n input: GetFullProductsByCollectionInput,\n context: IActionContext\n): Promise {\n\n let promise: AsyncResult;\n let searchProductId;\n const searchCriteriaInput: ProductSearchCriteria = {};\n searchCriteriaInput.Context = { ChannelId: context.requestContext.apiSettings.channelId, CatalogId: input.catalogId };\n searchCriteriaInput.Refinement = input.refiners;\n searchCriteriaInput.IncludeAttributes = input.includeAttributes;\n searchCriteriaInput.SkipVariantExpansion = true;\n const defaultNumber: number = 0;\n\n if (input.pageType === 'Category' || (context.requestContext.query && context.requestContext.query.categoryId)) {\n if (input.category) {\n searchCriteriaInput.CategoryIds = [input.category || defaultNumber];\n promise = searchByCriteriaAsync(\n {\n callerContext: context,\n queryResultSettings: input.queryResultSettings\n },\n searchCriteriaInput\n );\n } else {\n throw new Error(\n '[GetFullProductsForCollection]Category Page Detected, but no global categoryId found'\n );\n }\n } else if (input.searchText && (context.requestContext.query && context.requestContext.query.q)) {\n searchCriteriaInput.SearchCondition = input.searchText;\n promise = searchByCriteriaAsync(\n {\n callerContext: context,\n queryResultSettings: input.queryResultSettings\n },\n searchCriteriaInput\n );\n } else if (input.searchText && (context.requestContext.query && context.requestContext.query.productId && context.requestContext.query.recommendation)) {\n const searchObject = JSON.parse(input.searchText);\n searchProductId = Number(searchObject.ProductId);\n if (Number.isNaN(searchProductId)) {\n throw new Error('Failed to cast search product id into a number.');\n } else if (!searchObject.Recommendation) {\n throw new Error('Failed to retrieve the Recommendation.');\n } else {\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\n searchCriteriaInput.Ids = [searchProductId || defaultNumber];\n promise = searchByCriteriaAsync(\n {\n callerContext: context,\n queryResultSettings: input.queryResultSettings\n },\n searchCriteriaInput\n );\n }\n } else {\n throw new Error(\n '[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found'\n );\n }\n\n const productSearchResults = await promise;\n\n // Update ListPageState For SSR\n if (!MsDyn365.isBrowser) {\n context.update(new ListPageStateInput(), { totalProductCount: promise.metadata.count ?? defaultNumber, activeFilters: input.refiners });\n }\n\n return returnProducts(productSearchResults, context, promise.metadata.count);\n}\n\nexport const actionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search-result-container/get-full-products-by-collection',\n action: >action,\n input: createInput\n});\n\nexport default actionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, createObservableDataAction, IAction, IActionContext, IActionInput, IAny, ICommerceApiSettings, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\nimport { SortColumn } from '@msdyn365-commerce/retail-proxy';\nimport { getSearchConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\n\n// TODO: import from commerce entities when available\ninterface SearchConfiguration {\n ProductSortColumns?: SortColumn[];\n}\n\nexport interface MappedSearchConfiguration {\n key: string;\n sortColumn: SortColumn;\n}\n\nexport const sortOptions = {\n sortByOptionRelevanceDesc: 'Ranking-Desc',\n sortByOptionRatingAsc: 'AverageRating-Asc',\n sortByOptionRatingDesc: 'AverageRating-Desc',\n sortByOptionNameAsc: 'Name-Asc',\n sortByOptionNameDesc: 'Name-Desc',\n sortByOptionPriceAsc: 'Price-Asc',\n sortByOptionPriceDesc: 'Price-Desc',\n sortByOptionBestSelling: 'BestSelling',\n sortByOptionNewScore: 'NewScore',\n sortByOptionTrendingScore: 'TrendingScore'\n};\n\n/**\n * ActionInput class for the get-mapped-search-configuration Data Action.\n */\nexport class MappedSearchInput implements IActionInput {\n private readonly apiSettings: ICommerceApiSettings;\n\n constructor(apiSettings: ICommerceApiSettings) {\n this.apiSettings = apiSettings;\n }\n\n public getCacheKey = () => buildCacheKey('MappedSearchInput', this.apiSettings);\n\n public getCacheObjectType = () => 'MappedSearchInput';\n\n public dataCacheType = (): CacheType => 'request';\n}\n\n/**\n * Get a mapped search configuration that is easy to use for sorting.\n * @param input\n * @param ctx\n */\nexport async function getMappedSearchConfiguration(input: MappedSearchInput, ctx: IActionContext): Promise {\n return getSearchConfigurationAsync({ callerContext: ctx }).then((searchConfiguration: SearchConfiguration) => {\n return ((searchConfiguration.ProductSortColumns || []).map((sortColumn: SortColumn) => {\n let key = '';\n if (sortColumn.ColumnName) {\n switch (sortColumn.ColumnName.toUpperCase()) {\n case 'NAME':\n key = sortColumn.IsDescending ? sortOptions.sortByOptionNameDesc : sortOptions.sortByOptionNameAsc;\n break;\n case 'PRICE':\n key = sortColumn.IsDescending ? sortOptions.sortByOptionPriceDesc : sortOptions.sortByOptionPriceAsc;\n break;\n case 'AVERAGERATING':\n key = sortColumn.IsDescending ? sortOptions.sortByOptionRatingDesc : sortOptions.sortByOptionRatingAsc;\n break;\n case 'RANKING':\n key = sortOptions.sortByOptionRelevanceDesc;\n break;\n case 'BESTSELLINGSCORE':\n key = sortOptions.sortByOptionBestSelling;\n break;\n case 'NEWSCORE':\n key = sortOptions.sortByOptionNewScore;\n break;\n case 'TRENDINGSCORE':\n key = sortOptions.sortByOptionTrendingScore;\n break;\n default:\n }\n } else {\n ctx.telemetry.warning('[get-mapped-search-configuration] unknown search option');\n }\n if (key) {\n return {\n key,\n sortColumn\n };\n }\n return undefined;\n\n }).filter(Boolean));\n });\n}\n\nexport const createInput = (inputData: ICreateActionContext>): IActionInput => {\n return new MappedSearchInput(inputData.requestContext.apiSettings);\n};\n\nexport const getMappedSearchConfigurationDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search-result-container/get-mapped-search-configuration',\n action: >getMappedSearchConfiguration,\n input: createInput\n});\n\nexport default getMappedSearchConfigurationDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, ICreateActionContext } from '@msdyn365-commerce/core';\n\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\n\n/**\n * Default Category/Product Id Values.\n */\nenum DefaultValues {\n defaultCategoryIdValue = 0,\n defaultProductIdValue = 0\n}\n\n/**\n * Refiners-by-Collection Input action.\n */\nexport class RefinersByCollectionInput extends BaseCollectionInput implements IActionInput {\n public getCacheObjectType = () => 'ProductRefiner';\n\n public dataCacheType = () => {\n if (\n this.pageType !== 'Category' ||\n (this.refiners && this.refiners.length > 0) ||\n (this.queryResultSettings && this.queryResultSettings.Sorting && this.queryResultSettings.Sorting.Columns && this.queryResultSettings.Sorting.Columns.length > 0)\n ) {\n return 'request';\n }\n return 'application';\n\n };\n}\n\n/**\n * Create input method which creates an ActionInput for fetching list page refiners.\n * @param args\n */\nconst createInput = (args: ICreateActionContext): IActionInput => {\n return createBaseCollectionInput(args, RefinersByCollectionInput);\n};\n\n/**\n * Action method which fetches refiners for the given list page.\n * @param input\n * @param ctx\n */\nasync function action(input: RefinersByCollectionInput, ctx: IActionContext): Promise {\n let searchProductId;\n if (input.pageType === 'Category') {\n if (input.category) {\n return getProductRefinerHierarchy(\n {\n CategoryIds: [input.category || DefaultValues.defaultCategoryIdValue],\n Context: {\n ChannelId: input.apiSettings.channelId,\n CatalogId: input.catalogId\n },\n Refinement: input.isUpdateRefinerPanel ? input.refiners : []\n },\n input.queryResultSettings,\n ctx);\n }\n throw new Error('[GetRefinersForCollection]Category Page Detected, but no global categoryId found');\n\n } else {\n if (input.searchText && (ctx.requestContext.query && ctx.requestContext.query.q)) {\n return getProductRefinerHierarchy(\n {\n SearchCondition: input.searchText,\n Context: {\n ChannelId: input.apiSettings.channelId,\n CatalogId: input.catalogId\n },\n Refinement: input.isUpdateRefinerPanel ? input.refiners : []\n },\n input.queryResultSettings,\n ctx);\n }\n if (input.searchText && (ctx.requestContext.query && ctx.requestContext.query.productId)) {\n const searchObject = JSON.parse(input.searchText);\n searchProductId = Number(searchObject.ProductId);\n if (Number.isNaN(searchProductId)) {\n throw new Error('Failed to cast search product id into a number.');\n } else if (!searchObject.Recommendation) {\n throw new Error('Failed to retrieve the Recommendation.');\n } else {\n return getProductRefinerHierarchy(\n {\n Context: {\n ChannelId: input.apiSettings.channelId,\n CatalogId: input.catalogId\n },\n Refinement: input.isUpdateRefinerPanel ? input.refiners : [],\n RecommendationListId: searchObject.Recommendation,\n Ids: [searchProductId || DefaultValues.defaultProductIdValue]\n },\n input.queryResultSettings,\n ctx);\n }\n } else {\n throw new Error(\n '[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found'\n );\n }\n\n }\n}\n\nexport const actionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search-result-container/get-refiners-for-collection',\n action: >action,\n input: createInput\n});\n\nexport default actionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { IActionContext } from '@msdyn365-commerce/core';\nimport { IQueryResultSettings, ProductRefiner, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\nimport { getProductSearchRefinersAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\n\n/**\n * Uses Bulk refiner API to get refiners and child refiner values.\n * @param searchCriteria Product search criteria.\n * @param maxItems Max items.\n * @param queryResultSettings\n * @param ctx Action context.\n */\nexport async function getProductRefinerHierarchy(searchCriteria: ProductSearchCriteria, queryResultSettings: IQueryResultSettings, ctx: IActionContext): Promise {\n return getProductSearchRefinersAsync({ callerContext: ctx, queryResultSettings }, searchCriteria).then((productRefiners: ProductRefiner[]) => {\n if (!productRefiners) {\n ctx.trace('[getRefinersByCriteriaAction] returned no refiners');\n return [];\n }\n\n const result = (productRefiners || []).map((productRefiner: ProductRefiner) => productRefiner);\n\n if (result.length === 0) {\n ctx.trace('[getRefinersByCriteriaAction] returned no IProductRefinerHierarchy objects');\n return [];\n }\n\n return result;\n });\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport MsDyn365, { IRequestContext } from '@msdyn365-commerce/core';\nimport { ProductRefinerValue, SortColumn } from '@msdyn365-commerce/retail-proxy';\n\n/**\n * Refiner Compression:\n * Refiners contains a non-trivial amount of data that is required to successfully make\n * a refiner-based API call. To allow for deep-linking of refiners in the URL, refiner data\n * must be compressed so that URL max length is not exceeded. Refiners will be compressed into\n * the following array style index-based format:\n * [DataTypeValue, LeftValueBoundString, RefinerRecordId, RefinerSourceValue, RightValueBoundString, UnitText].\n */\nconst compressedRefinerKeys = ['DataTypeValue', 'LeftValueBoundString', 'RefinerRecordId', 'RefinerSourceValue', 'RightValueBoundString', 'UnitText'];\n\n/**\n * Hydrates compressed refiner data from URL.\n * @param fullUrl The full URL of the page.\n * @param requestContext\n */\nexport const hydrateRefinersFromUrl = (requestContext: IRequestContext): ProductRefinerValue[] => {\n const compressedRefinerArray = parseQueryParam<(string | number)[][]>('refiners', requestContext);\n if (!compressedRefinerArray || compressedRefinerArray.length === 0) {\n return [];\n }\n\n return compressedRefinerArray.map((compressedRefiner) => {\n try {\n const parsedRefiner: ProductRefinerValue = {};\n compressedRefinerKeys.forEach((refinerKey, index) => {\n parsedRefiner[refinerKey] = compressedRefiner[index];\n });\n return parsedRefiner;\n } catch {\n return undefined;\n }\n }).filter(Boolean);\n};\n\n/**\n * Compressed a list of refiners for use in URLs.\n * @param refiners The uncompressed refiners.\n */\nexport const compressRefiners = (refiners: ProductRefinerValue[]) => {\n const compressedRefiners: (string | number)[][] = [];\n\n refiners.forEach((refiner) => {\n const compressedRefiner: (string | number)[] = [];\n compressedRefinerKeys.forEach((refinerKey) => {\n compressedRefiner.push(refiner[refinerKey]);\n });\n compressedRefiners.push(compressedRefiner);\n });\n\n return compressedRefiners;\n};\n\n/**\n * Method which creates a URL contiaining serialized active refiners.\n * @param fullUrl The Current URL of the page.\n * @param refiners The refiners which should be added to the URL.\n * @param sortingColumns\n * @param skipCount\n */\nexport const buildListPageUrl = (fullUrl: URL, refiners?: ProductRefinerValue[], sortingColumns?: SortColumn[], skipCount?: number) => {\n // Refiner Change flow\n if (refiners !== undefined) {\n if (refiners.length === 0) {\n fullUrl.searchParams.delete('refiners');\n } else {\n const sortedRefiners = refiners.sort((first, second) => (first.RefinerRecordId && second.RefinerRecordId &&\n (first.RefinerRecordId > second.RefinerRecordId) ? 1 : -1));\n fullUrl.searchParams.set('refiners', JSON.stringify(compressRefiners(sortedRefiners)));\n }\n\n // Adding or removing a refiner means we want to always load page 1\n fullUrl.searchParams.delete('skip');\n return fullUrl.href;\n }\n\n if (sortingColumns !== undefined) {\n if (sortingColumns.length === 0) {\n fullUrl.searchParams.delete('sorting');\n } else {\n fullUrl.searchParams.set('sorting', JSON.stringify(sortingColumns));\n }\n\n // Changing the sort means always load page 1\n fullUrl.searchParams.delete('skip');\n return fullUrl.href;\n }\n\n if (skipCount) {\n fullUrl.searchParams.set('skip', skipCount.toString());\n }\n\n return fullUrl.href;\n};\n\n/**\n * Parses a query param from the query object of the request context.\n * @param key The query parameter key.\n * @param requestContext The request context.\n */\nexport const parseQueryParam = (key: string, requestContext: IRequestContext): T | null => {\n if (requestContext.query && requestContext.query[key]) {\n return JSON.parse(decodeURIComponent(requestContext.query[key]));\n }\n return null;\n};\n\n/**\n * Gets the current URL of the page from the request context.\n * @param requestContext The request context.\n */\nexport const getCurrentUrl = (requestContext: IRequestContext): URL => {\n if (MsDyn365.isBrowser) {\n return new URL(window.location.href);\n }\n\n // NOTE: Typing on requestURL is incorrect\n if (requestContext.url.requestUrl.href) {\n return new URL(requestContext.url.requestUrl.href);\n }\n return new URL((requestContext.url.requestUrl));\n\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport {\n CacheType,\n createObservableDataAction,\n IAction,\n IActionContext,\n IActionInput,\n IAny,\n ICreateActionContext,\n IGeneric\n} from '@msdyn365-commerce/core';\nimport { ProductPrice, ProductRefinerValue, ProductSearchResult, SimpleProduct, SortingInfo } from '@msdyn365-commerce/retail-proxy';\nimport { observable } from 'mobx';\n\nimport { listPageType } from './actions';\n\n/**\n * ListPageState class.\n */\nexport class ListPageState {\n @observable public activeFilters: ProductRefinerValue[] | null = null;\n\n @observable public activeProducts: ProductSearchResult[] = [];\n\n @observable public sortingCritera: SortingInfo | null = null;\n\n @observable public currentPageNumber: number | null = null;\n\n @observable public refiners: IProductRefinerHierarchy[] | null = null;\n\n @observable public totalProductCount: number | undefined;\n\n @observable public pageSize: number = 10;\n\n @observable public pageType: listPageType = 'Unknown';\n\n @observable public featureProduct: SimpleProduct | null = null;\n\n @observable public productPrices: ProductPrice[] | undefined = [];\n}\n\n/**\n * ListPageStateInput - action input.\n */\nexport class ListPageStateInput implements IActionInput {\n public getCacheKey = () => 'ListPageState';\n\n public getCacheObjectType = () => 'ListPageState';\n\n public dataCacheType = (): CacheType => 'request';\n}\n\nexport async function listPageStateAction(\n input: ListPageStateInput,\n ctx: IActionContext\n): Promise {\n return new ListPageState();\n}\n\n/**\n * Create new input for create action.\n * @param inputData\n */\nexport const createListPageInput = (\n inputData: ICreateActionContext>\n): IActionInput => {\n return new ListPageStateInput();\n};\n\n/**\n * ListPageState - create action.\n */\nexport default createObservableDataAction({\n action: >listPageStateAction,\n input: createListPageInput\n});\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ITelemetry } from '@msdyn365-commerce/core';\nimport { AttributeDataType, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\n\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\n\n/**\n * Types of product refiner values.\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\nexport enum ProductRefinerValueDataTypeValue {\n\n /**\n * Range slider is used for selections like price.\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Range = 1,\n\n /**\n * Range input is a different way to specify ranges and can be expressed with input boxes\n * as well as a set of discrete single-select type values.\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n RangeInput = 4,\n\n /**\n * This is a discrete list item, either multi-select or single-select.\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n List = 5,\n\n /**\n * Boolean types allows only single-select.\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Boolean = 6\n}\n\n/**\n * Types of product refiners.\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\nexport enum ProductRefinerTypeValue {\n\n /**\n * Refiner values are single-select.\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Single = 0,\n\n /**\n * Refiner values are multi-select.\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Multi = 1\n}\n\n/**\n * ProductRefinerSource enum type.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\nexport enum ProductRefinerSource {\n\n /**\n * The None member.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n None = 0,\n\n /**\n * The Attribute member.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Attribute = 1,\n\n /**\n * The Category member.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Category = 2,\n\n /**\n * The Price member.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Price = 3,\n\n /**\n * The Rating member.\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\n * @example\n * ```\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\n * ```\n */\n Rating = 4\n}\n\n/**\n * Checks if the data type value corresponds to a slider.\n * @param dataTypeValue\n */\nexport function isRangeType(dataTypeValue: number | undefined): boolean {\n return dataTypeValue === AttributeDataType.Currency ||\n dataTypeValue === AttributeDataType.Decimal ||\n dataTypeValue === AttributeDataType.Integer;\n}\n\n/**\n * Find the refinement criterion associated with this product refiner value.\n * @param productRefinerValue Product refiner value to match.\n * @param refinementCriteria Selected refinement criteria.\n */\nexport function findMatchingRefinementCriterion(\n productRefinerValue: ProductRefinerValue,\n refinementCriteria: ProductRefinerValue[]\n): ProductRefinerValue | undefined {\n // If the value is a range, then match only on data type value; otherwise match on item string\n return refinementCriteria.find(\n (refinementCriterion: ProductRefinerValue) => isMatchingRefinementCriterion(productRefinerValue, refinementCriterion)\n );\n}\n\n/**\n * Find the refinement criterion associated with this product refiner value.\n * @param productRefinerValue Product refiner value to match.\n * @param refinementCriteria Selected refinement criteria.\n * @param refinementCriterion\n */\nexport function isMatchingRefinementCriterion(\n productRefinerValue: ProductRefinerValue,\n refinementCriterion: ProductRefinerValue\n): boolean {\n // If the value is a range, then match only on data type value; otherwise match on item string\n return refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\n (isRangeType(refinementCriterion.DataTypeValue) || refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString);\n}\n\nexport function getUpdatedRefinementCriteria(\n itemToggleNotification: IRefineItemToggleNotification,\n currentRefinementCriteria: ProductRefinerValue[]): ProductRefinerValue[] {\n const updatedRefinementCriteria: ProductRefinerValue[] = [];\n let toggledItemFound = false;\n currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\n if (isMatchingRefinementCriterion(itemToggleNotification.productRefinerValue, selectedCriterion)) {\n toggledItemFound = true;\n if (itemToggleNotification.isSelecting) {\n const next = {\n ...selectedCriterion,\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || selectedCriterion.LeftValueBoundString,\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || selectedCriterion.RightValueBoundString\n };\n updatedRefinementCriteria.push(next);\n\n } // Else the item is being de-selected, so omit it from the refinement criteria\n } else {\n // Keep existing criterion because it is not in the item toggle notification\n updatedRefinementCriteria.push(selectedCriterion);\n }\n });\n\n if (!toggledItemFound) {\n const next = {\n ...itemToggleNotification.productRefinerValue,\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || itemToggleNotification.productRefinerValue.LeftValueBoundString,\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || itemToggleNotification.productRefinerValue.RightValueBoundString\n };\n updatedRefinementCriteria.push(next);\n\n // If single select, then deselect any others in the parent refiner group\n if ((itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.Text || itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.TrueFalse) &&\n itemToggleNotification.parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect) {\n itemToggleNotification.parentProductRefinerHierarchy.Values.forEach((child: ProductRefinerValue) => {\n if (child.RefinerRecordId === next.RefinerRecordId && child.LeftValueBoundString === next.LeftValueBoundString) {\n // Do nothing\n } else {\n const matchingIndex = updatedRefinementCriteria.findIndex((criterion: ProductRefinerValue) => isMatchingRefinementCriterion(child, criterion));\n if (matchingIndex > -1) {\n updatedRefinementCriteria.splice(matchingIndex, 1);\n }\n }\n });\n }\n }\n\n return updatedRefinementCriteria;\n}\n\nexport function formatPrice(\n amount: string | undefined,\n currency: string | undefined,\n locale: string | undefined,\n telemetry: ITelemetry): string {\n if (!amount || !currency) {\n telemetry.trace(`[refine-menu.utilities.formatPrice] could not format price for ${amount} ${currency}`);\n return amount || '';\n }\n const priceAmount = (amount && Number(amount)) || 0;\n let result: string;\n\n try {\n result = new Intl.NumberFormat(locale, {\n style: 'currency',\n currencyDisplay: 'symbol',\n currency,\n minimumFractionDigits: 0\n }).format(priceAmount);\n } catch (error) {\n result = `${priceAmount} ${currency}`;\n telemetry.warning(`[refine-menu.utilities.formatPrice] Failed to format price for ${result}: ${error}`);\n }\n\n return result;\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport { computed } from 'mobx';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { IChoiceSummaryProps } from './choice-summary.props';\nimport { isMatchingRefinementCriterion, isRangeType } from './utilities';\n\ninterface IRefinerMap {\n key: string;\n value: ProductRefinerValue;\n}\n\n/**\n * ChoiceSummary component.\n */\n@observer\nexport default class ChoiceSummary extends React.PureComponent {\n private readonly closeButtonGlyph: string = 'msi-close-btn';\n\n private readonly payLoad: IPayLoad;\n\n @computed get selectedRefinersMap(): IRefinerMap[] {\n const { selectedChoices } = this.props;\n return selectedChoices.map((selectedRefiner: ProductRefinerValue) => {\n return {\n key: this._getKeyForRefinerValue(selectedRefiner),\n value: selectedRefiner\n } as IRefinerMap;\n });\n }\n\n constructor(props: Readonly) {\n super(props);\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\n }\n\n public render(): JSX.Element {\n const { clearAllText, label, classNames, choiceAriaLabel, closeAriaLabel } = this.props;\n const items = this.selectedRefinersMap;\n this.payLoad.contentAction.etext = clearAllText;\n const clearAllAttributes = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\n return (\n
\n {items.length > 0 && label && \n {label}\n }\n
    \n {items.map((item: IRefinerMap, index: number) => {\n const listItemProps = {\n 'aria-posinset': index,\n 'aria-setsize': items.length\n };\n\n this.payLoad.contentAction.etext = item.key;\n const attribute = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\n\n return (\n
  • \n \n {item.key}\n \n \n
  • \n );\n })}\n
\n {items.length > 0 && clearAllText && \n {clearAllText}\n }\n
\n );\n }\n\n private _getKeyForRefinerValue(productRefinerValue: ProductRefinerValue): string {\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry } = this.props;\n const overallFormat = choiceFormat || '{1}';\n const rangeFormat = choiceRangeValueFormat;\n let refinerName = '';\n if (refinerHierarchy && refinerHierarchy.find) {\n const parent = refinerHierarchy.find(\n (hierarchy: IProductRefinerHierarchy) => !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, productRefinerValue))\n );\n\n if (!parent) {\n telemetry.warning('[choice-summary] could not find parent of selected refiner value');\n } else {\n refinerName = parent.KeyName || '';\n }\n }\n\n let refinerValueName: string;\n if (isRangeType(productRefinerValue.DataTypeValue)) {\n refinerValueName = rangeFormat\n .replace('{0}', this._formatPrice(productRefinerValue.LeftValueBoundString, productRefinerValue.UnitText))\n .replace('{1}', this._formatPrice(productRefinerValue.RightValueBoundString, productRefinerValue.UnitText));\n } else {\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\n }\n\n return overallFormat.replace('{0}', refinerName).replace('{1}', refinerValueName);\n }\n\n private _formatPrice(amount: string | undefined, currency: string | undefined): string {\n if (!amount || !currency) {\n this.props.telemetry.trace('[choice-summary] could not format price');\n return amount || '';\n }\n let result = amount;\n\n try {\n result = this.props.context!.cultureFormatter.formatCurrency(Number(amount), currency);\n } catch (error) {\n this.props.telemetry.warning(`Failed to format price for ${result}: ${error}`);\n }\n\n return result;\n }\n\n private readonly _onClick = (e: React.MouseEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n\n const target = e.currentTarget as HTMLElement;\n const clearAll = target.getAttribute('class')!.includes('choice-summary__clear-all');\n const selectedRefiner = clearAll ? undefined : this._getSelectedRefinerChoice(target);\n\n if (this.props.onChoiceClicked) {\n this.props.onChoiceClicked({\n clearAll,\n itemClicked: target,\n choiceClicked: selectedRefiner,\n nextItemToFocus: target.nextSibling as HTMLElement\n });\n }\n };\n\n private _getSelectedRefinerChoice(itemClicked: HTMLElement): ProductRefinerValue | undefined {\n const result = this.selectedRefinersMap.find(selected => (itemClicked.textContent && itemClicked.textContent.trim()) === selected.key);\n return (result && result.value) || undefined;\n }\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport * as React from 'react';\n\ninterface IErrorMessage {\n text?: string;\n}\n\nexport const ErrorMessage: React.FC = ({ text }) => {\n return (\n \n
\n {' '}\n {text}\n {' '}\n
\n
\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ICoreContext, IGridSettings, IImageData, IImageSettings, Image, IRequestContext } from '@msdyn365-commerce/core';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\nimport { getFallbackImageUrl, getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\nimport { getPayloadObject, getTelemetryAttributes, ITelemetryContent, onTelemetryClick } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchResultContainerResources } from '../search-result-container.props.autogenerated';\n\n// Import { IComponent, IComponentProps, ICoreContext, IGridSettings, IImageData, IImageSettings, Image, msdyn365Commerce } from '@msdyn365-commerce/core';\n\ninterface IFeatureSearchResultItem {\n product: SimpleProduct | null;\n context: ICoreContext;\n resources: ISearchResultContainerResources;\n imageSettings?: IImageSettings;\n moduleType: string;\n moduleId: string;\n telemetryContent?: ITelemetryContent;\n recommendation?: string;\n}\n\nexport const FeatureSearchResultItem: React.FC = ({\n product,\n context,\n imageSettings,\n resources,\n telemetryContent,\n recommendation\n}) => {\n if (product === null) {\n return null;\n }\n\n const productName = product.Name;\n const productRecordId = product && product.RecordId ? product.RecordId : 0;\n const productUrl = getProductPageUrlSync(product.Name || '', productRecordId, context && context.actionContext, undefined);\n const fallbackImage = getFallbackImageUrl(product.ItemId, context.actionContext.requestContext.apiSettings);\n const heading = recommendation && recommendation === 'descriptions' ? resources.featureSimilarDescriptionTitle : resources.featureSimilarLooksTitle;\n\n // Construct telemetry attribute to render\n const payLoad = getPayloadObject('click', telemetryContent!, productName!, productRecordId.toString());\n\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\n return (\n
\n \n
\n {renderProductPlacementImage(\n imageSettings, context.request.gridSettings, product.PrimaryImageUrl,\n product.Name, fallbackImage, context.actionContext.requestContext)}\n
\n \n
\n

\n {heading}\n

\n {renderProductTitle(product?.Name)}\n
\n
\n );\n\n};\n\nfunction renderProductPlacementImage(\n imageSettings?: IImageSettings, gridSettings?: IGridSettings, imageUrl?: string,\n altText?: string, fallbackImage?: string, context?: IRequestContext): JSX.Element | null {\n\n if (!imageUrl || !gridSettings || !imageSettings) {\n return null;\n }\n const img: IImageData = {\n src: imageUrl,\n altText: altText ? altText : ''\n };\n const imageProps = {\n gridSettings,\n imageSettings,\n fallBackSrc: fallbackImage\n };\n return (\n \n );\n}\n\nfunction renderProductTitle(title?: string): JSX.Element | null {\n return (

\n {title}\n

);\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport * as React from 'react';\n\ninterface ILink {\n className?: string;\n text?: string;\n href?: string;\n ariaLabel?: string;\n}\n\nexport const Link: React.FC = ({ text, className, href, ariaLabel }) => (\n {' '}\n {text}\n {' '}\n);\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport {\n Button,\n Modal,\n ModalBody,\n ModalFooter,\n ModalHeader\n} from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nexport interface ISearchResultModalViewProps {\n modal: React.ReactElement;\n modalHeader: React.ReactElement;\n modalFooter: React.ReactElement;\n modalBody: React.ReactElement;\n}\n\ninterface IModalToggleProps {\n innerRef: React.RefObject | undefined;\n id: string;\n text: string;\n ariaLabel: string;\n onClick(): void;\n}\n\nexport interface ISearchResultModalResources {\n modalTitle: string;\n modalCloseButtonText: string;\n}\n\nexport interface ISearchResultModalProps {\n resources: ISearchResultModalResources;\n isOpen: boolean;\n returnRef: React.RefObject | undefined;\n onModalToggle(): void;\n}\n\nexport const ModalToggle: React.FC = (props: IModalToggleProps) => {\n const { text, onClick, ariaLabel, innerRef, id } = props;\n return (\n {text}\n );\n};\n\nexport const SearchResultModal = (props: ISearchResultModalProps): ISearchResultModalViewProps => {\n return {\n modal: modalNode(props),\n modalHeader: modalHeaderNode(props),\n modalFooter: modalFooterNode(props),\n modalBody: \n };\n};\n\nconst modalNode = (props: ISearchResultModalProps) => {\n return (\n \n );\n};\n\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\n return (\n \n {props.resources.modalTitle}\n \n );\n};\n\nconst modalFooterNode = (props: ISearchResultModalProps) => {\n return (\n \n \n \n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\nimport { IPriceComponentResources, ProductComponent } from '@msdyn365-commerce/components';\nimport { ICoreContext, IImageSettings } from '@msdyn365-commerce/core';\nimport { ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\nimport { ArrayExtensions } from '@msdyn365-commerce-modules/retail-actions';\nimport { ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchResultContainerResources } from '../search-result-container.props.autogenerated';\n\ninterface IProductSearchResultItems {\n products: ProductSearchResult[];\n context: ICoreContext;\n resources: ISearchResultContainerResources;\n imageSettings?: IImageSettings;\n moduleType: string;\n moduleId: string;\n allowBackNavigation?: boolean;\n telemetryContent: ITelemetryContent;\n quickviewSlot?: {} | null | undefined;\n channelInventoryConfigurationId?: number;\n isPriceMinMaxEnabled?: boolean;\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\n}\n\n/**\n * Returns the product inventory label.\n * @param channelInventoryConfigurationId - The channel configuration Id.\n * @param product - The product.\n * @returns The inventory label.\n */\nfunction getInventoryLabel(channelInventoryConfigurationId: number | undefined, product: ProductSearchResult): string | undefined {\n if (!channelInventoryConfigurationId || !ArrayExtensions.hasElements(product.AttributeValues)) {\n return undefined;\n }\n const inventoryAttribute = product.AttributeValues.find(attribute => attribute.RecordId === channelInventoryConfigurationId);\n if (inventoryAttribute) {\n return inventoryAttribute.TextValue;\n }\n return undefined;\n}\n\nexport const ProductSearchResultItems: React.FC = ({\n products,\n context,\n imageSettings,\n resources,\n moduleType,\n moduleId,\n allowBackNavigation,\n telemetryContent,\n quickviewSlot,\n channelInventoryConfigurationId,\n isPriceMinMaxEnabled,\n productsDimensionAvailabilities\n}) => {\n const priceResources: IPriceComponentResources = {\n priceRangeSeparator: resources.priceRangeSeparator\n };\n return (\n\n
    \n {products.map((product: ProductSearchResult, index: number) => (\n
  • \n ArrayExtensions.hasElements(dimensionAvailability) &&\n dimensionAvailability[0].masterProductId === product.MasterProductId)}\n />\n
  • \n ))}\n
\n );\n\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ISliderLabel, ISliderThumbProps, Slider } from '@msdyn365-commerce-modules/utilities';\nimport debounce from 'lodash/debounce';\nimport { computed } from 'mobx';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { IRefineItemProps, IRefineItemState } from './refine-item';\n\ntype InputType = 'Min' | 'Max';\n\nexport type RangeRefineItemType = 'slider' | 'input';\n\n/**\n * Range refine item properties.\n */\nexport interface IRangeRefineItemProps extends IRefineItemProps {\n rangeType: RangeRefineItemType;\n minValueSliderThumbAriaLabel?: string;\n maxValueSliderThumbAriaLabel?: string;\n sliderKey?: string;\n}\n\n/**\n * Range refine item state.\n */\nexport interface IRangeRefineItemState extends IRefineItemState {\n validationErrorMin: string | undefined;\n validationErrorMax: string | undefined;\n selectedMin: string | undefined;\n selectedMax: string | undefined;\n touchedMin: boolean;\n touchedMax: boolean;\n sliderId: string;\n minValue: string | undefined;\n maxValue: string | undefined;\n labels: ISliderLabel[];\n sliderThumbs: ISliderThumbProps[];\n}\n\n/**\n * RangeRefineItem component (controlled by RefineSubmenu).\n */\n@observer\nexport default class RangeRefineItem extends React.Component {\n private readonly _formattedPriceReverseLookup: Map = new Map();\n\n private readonly minInput: React.RefObject;\n\n private readonly maxInput: React.RefObject;\n\n @computed get currencyCode(): string {\n return this.props.productRefinerValue.UnitText || '';\n }\n\n public constructor(props: IRangeRefineItemProps) {\n super(props);\n this._onRangeUpdate = this._onRangeUpdate.bind(this);\n this._onRangeUpdateEnd = this._onRangeUpdateEnd.bind(this);\n this._handleRangeTooltipText = this._handleRangeTooltipText.bind(this);\n this._changeMin = this._changeMin.bind(this);\n this._changeMax = this._changeMax.bind(this);\n this._finishChangeMin = this._finishChangeMin.bind(this);\n this._finishChangeMax = this._finishChangeMax.bind(this);\n\n this.minInput = React.createRef();\n this.maxInput = React.createRef();\n\n const { selectedRefinementCriterion } = this.props;\n const initialMin = selectedRefinementCriterion?.LeftValueBoundString ?? '0';\n const initialMax = selectedRefinementCriterion?.RightValueBoundString;\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(this.props.productRefinerValue.RefinerRecordId)}`;\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\n const minPrice = this._formatPrice(minValue);\n const maxPrice = this._formatPrice(maxValue);\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\n const selectedMin = this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\n const selectedMax = this.props.selectedRefinementCriterion?.RightValueBoundString ??\n this.props.productRefinerValue.RightValueBoundString ?? maxValue;\n const selectedMinPrice = this._formatPrice(selectedMin);\n const selectedMaxPrice = this._formatPrice(selectedMax);\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(sliderId,\n sliderKeyString, selectedMin, selectedMinPrice, selectedMax, selectedMaxPrice, maxPrice);\n this.state = {\n isChecked: false,\n validationErrorMin: undefined,\n validationErrorMax: undefined,\n selectedMin: initialMin,\n selectedMax: initialMax,\n touchedMin: false,\n touchedMax: false,\n sliderId,\n minValue,\n maxValue,\n labels,\n sliderThumbs\n };\n }\n\n public shouldComponentUpdate(nextProps: IRangeRefineItemProps,\n nextState: IRangeRefineItemState): boolean {\n if (this.state === nextState && this.props === nextProps) {\n return false;\n }\n return true;\n }\n\n public componentDidUpdate(previousProps: IRangeRefineItemProps): void {\n if (previousProps !== this.props) {\n this.updateSliderProps();\n }\n }\n\n public render(): JSX.Element | undefined {\n const { productRefinerValue, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\n\n if (!productRefinerValue || !parentProductRefinerHierarchy) {\n refineItemCommonProps.telemetry.error('Cannot render refine value range without productRefinerValue and parentProductRefinerHierarchy');\n return undefined;\n }\n\n if (this.props.rangeType === 'input') {\n return this._renderInputFields();\n }\n\n return this._renderSlider();\n }\n\n /**\n * Function to update slider props.\n */\n private updateSliderProps(): void {\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(this.props.productRefinerValue.RefinerRecordId)}`;\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\n const minPrice = this._formatPrice(minValue);\n const maxPrice = this._formatPrice(maxValue);\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\n const selectedMin = this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\n const selectedMax = this.props.selectedRefinementCriterion?.RightValueBoundString ??\n this.props.productRefinerValue.RightValueBoundString ?? maxValue;\n const selectedMinPrice = this._formatPrice(selectedMin);\n const selectedMaxPrice = this._formatPrice(selectedMax);\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(sliderId,\n sliderKeyString, selectedMin, selectedMinPrice, selectedMax, selectedMaxPrice, maxPrice);\n this.setState({ sliderId, minValue, maxValue, labels, sliderThumbs });\n }\n\n /**\n * Function to create the labels for slider.\n * @param sliderId - Slider element id for the DOM.\n * @param minPrice - Slider min value.\n * @param maxPrice - Slider max value.\n * @returns Array labels.\n */\n private readonly getLabels = (sliderId: string, minPrice: string, maxPrice: string): ISliderLabel[] => {\n return ([\n {\n labelId: `${sliderId}_start`,\n labelString: `${minPrice}`,\n labelPositioning: 'start'\n },\n {\n labelId: `${sliderId}_end`,\n labelString: `${maxPrice}`,\n labelPositioning: 'end'\n }\n ]);\n };\n\n /**\n * Function to create the slider thumbs for slider.\n * @param sliderId - Slider element id for the DOM.\n * @param sliderKey - Unique key for slider.\n * @param selectedMin - Slider selected min value.\n * @param selectedMinPrice - Slider selected min price.\n * @param selectedMax - Slider selected max value.\n * @param selectedMaxPrice - Slider selected max price..\n * @param maxPrice - Slider max price..\n * @returns Slider Thumb Props.\n */\n private readonly getSliderThumbs = (sliderId: string,\n sliderKey: string,\n selectedMin: string,\n selectedMinPrice: string,\n selectedMax: string | undefined,\n selectedMaxPrice: string,\n maxPrice: string): ISliderThumbProps[] => {\n const sliderThumbDefaultValue = 0;\n return ([\n {\n id: `${sliderId}${sliderKey}_slider_thumb_start`,\n value: (selectedMin && Number(selectedMin)) || sliderThumbDefaultValue,\n ariaLabel: `${this.props.minValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\n ariaValueText: `${selectedMinPrice}`\n },\n {\n id: `${sliderId}${sliderKey}_slider_thumb_end`,\n value: Number(selectedMax) || Number(maxPrice),\n ariaLabel: `${this.props.maxValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\n ariaValueText: `${selectedMaxPrice}`\n }\n ]);\n };\n\n private _renderInputFields(): JSX.Element | undefined {\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\n const { selectedMin, selectedMax, touchedMin, touchedMax, validationErrorMin, validationErrorMax } = this.state;\n\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', (parentProductRefinerHierarchy.KeyName || ''));\n const formAttrs = {\n 'aria-label': rangeAriaLabel,\n 'aria-disabled': isDisabled\n };\n\n // To enable price formatting of selected fields, this is the approach:\n // initial value: min=0 formatted as price, max=undefined\n // onFocus/onChange: convert to number (unformat) and mark as touched to indicate value is being edited\n // onBlur: validate and format entered value as price\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${validationErrorMin ? 'refine-submenu__input-range--error' : ''}`;\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${validationErrorMax ? 'refine-submenu__input-range--error' : ''}`;\n const minLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-min';\n const maxLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-max';\n const formattedSelectedMin = this._getFormattedSelectedValue(selectedMin, touchedMin, validationErrorMin);\n const formattedSelectedMax = this._getFormattedSelectedValue(selectedMax, touchedMax, validationErrorMax);\n return (\n
\n \n \n {validationErrorMin &&\n \n {validationErrorMin}\n }\n {validationErrorMax && validationErrorMin !== validationErrorMax &&\n \n {validationErrorMax}\n }\n
\n );\n }\n\n private _renderSlider(): JSX.Element | undefined {\n const { isDisabled, sliderKey } = this.props;\n const ariaAttributes = {\n 'aria-disabled': isDisabled\n };\n\n return (\n \n );\n }\n\n private _changeMin(event: React.FocusEvent): void {\n this._changeValue(event, 'Min');\n }\n\n private _changeMax(event: React.FocusEvent): void {\n this._changeValue(event, 'Max');\n }\n\n private _changeValue(event: React.FocusEvent, inputType: InputType): void {\n const selectedKey = `selected${inputType}`;\n const touchedKey = `touched${inputType}`;\n this.setState({\n [selectedKey]: this._getInputWithoutFormatting(event.currentTarget.value),\n [touchedKey]: true\n });\n }\n\n private _finishChangeMin(event: React.FocusEvent): boolean {\n const selectedMinValue = this._getInputWithoutFormatting(event.currentTarget.value);\n this.setState({\n selectedMin: selectedMinValue,\n minTouched: false\n });\n const minInput = Number(selectedMinValue);\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\n const max = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\n\n const maxNum = max ? Number(max) : undefined;\n\n if (isNaN(minInput)) {\n this.setState({ validationErrorMin: refineItemCommonProps.validationErrorNaN });\n this._focus('Min');\n return false;\n }\n\n if (this._validateRange(minInput, maxNum)) {\n onToggle({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: true,\n rangeStart: minInput,\n rangeEnd: maxNum\n });\n return true;\n }\n this._focus('Min');\n\n return false;\n }\n\n private _finishChangeMax(event: React.FocusEvent): boolean {\n const selectedMaxValue = this._getInputWithoutFormatting(event.currentTarget.value);\n this.setState({\n selectedMax: selectedMaxValue,\n maxTouched: false\n });\n const maxInput = Number(selectedMaxValue);\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\n const min = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\n\n const minNum = Number(min);\n\n if (isNaN(maxInput)) {\n this.setState({ validationErrorMax: refineItemCommonProps.validationErrorNaN });\n this._focus('Max');\n return false;\n }\n\n if (this._validateRange(minNum, maxInput)) {\n if (productRefinerValue) {\n onToggle({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: true,\n rangeStart: minNum,\n rangeEnd: maxInput\n });\n } else {\n this._focus('Max');\n }\n return true;\n }\n\n return false;\n }\n\n private _focus(inputType: InputType): void {\n const ref = inputType === 'Max' ? this.maxInput : this.minInput;\n\n setTimeout(() => {\n if (ref && ref.current) {\n ref.current.focus();\n }\n }, 50);\n }\n\n private _getFormattedSelectedValue(selected: string | undefined, touched: boolean, validationError: string | undefined): string | undefined {\n if (touched || validationError || selected === undefined) {\n return selected;\n }\n return this._formatPrice(selected);\n }\n\n private _validateRange(min: number, max: number | undefined): boolean {\n const { refineItemCommonProps } = this.props;\n if (max === undefined) {\n return true;\n }\n\n if (min > max) {\n this.setState({\n validationErrorMin: refineItemCommonProps.validationErrorRange,\n validationErrorMax: refineItemCommonProps.validationErrorRange\n });\n return false;\n }\n\n return true;\n }\n\n private _formatPrice(amount: string | undefined): string {\n const result = this.props.context.cultureFormatter.formatCurrency(Number(amount), this.currencyCode);\n return result;\n }\n\n private _getInputWithoutFormatting(input: string): string {\n // First try to cast raw input to a number\n const inputAsNum = Number(input);\n if (!isNaN(inputAsNum)) {\n return input;\n }\n\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\n return reverseLookupResult || input;\n }\n\n // NOTE: Fix types once Shared Components build pipeline bug fixed\n private _onRangeUpdate(sliderChangeNotification: any): void {\n // Need to filter out mousemove events as these cause errors after the menu updates and slider re-renders\n if (sliderChangeNotification.eventType !== 'mousemove') {\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\n if (productRefinerValue && sliderChangeNotification) {\n onToggle({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: true,\n rangeStart: sliderChangeNotification.firstThumbValue,\n rangeEnd: sliderChangeNotification.secondThumbValue\n });\n\n this._focusOnSliderThumb(sliderChangeNotification);\n }\n }\n }\n\n private _onRangeUpdateEnd(sliderChangeNotification: any): void {\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\n if (productRefinerValue && sliderChangeNotification) {\n onToggle({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: true,\n rangeStart: sliderChangeNotification.firstThumbValue,\n rangeEnd: sliderChangeNotification.secondThumbValue\n });\n\n this._focusOnSliderThumb(sliderChangeNotification);\n }\n }\n\n private _focusOnSliderThumb(sliderChangeNotification: any): void {\n if (sliderChangeNotification.id) {\n const element = document.getElementById(`${sliderChangeNotification.id}range`);\n if (element) {\n setTimeout(\n () => {\n element.focus();\n }, 0);\n }\n }\n }\n\n private _handleRangeTooltipText(tooltip: number): string {\n return this._formatPrice(`${tooltip}`);\n }\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { RatingComponent, SwatchComponent } from '@msdyn365-commerce/components';\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\nimport { ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\nimport { checkIfShouldDisplayAsSwatch, DimensionTypes, IDimensionsApp, StringExtensions } from '@msdyn365-commerce-modules/retail-actions';\nimport { format, getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IRefineItemCommonProps } from './refine-item.props.common';\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\n\n/**\n * RefineItem properties.\n */\nexport interface IRefineItemProps {\n\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\n productRefinerValue: ProductRefinerValue;\n selectedRefinementCriterion: ProductRefinerValue | undefined;\n selectedRefinerValues?: ProductRefinerValue[];\n refineItemCommonProps: IRefineItemCommonProps;\n isDisabled: boolean;\n context: ICoreContext>;\n moduleId: string;\n moduleTypeName: string;\n index?: number;\n productCountAriaLabel?: string;\n singleProductCountAriaLabel?: string;\n isMobileView?: boolean;\n\n /**\n * The telemetry content\n */\n telemetryContent?: ITelemetryContent;\n onToggle(notfication: Readonly): void;\n urlBuilder(refiner: IRefineItemToggleNotification): string;\n}\n\n/**\n * Refine item state.\n */\nexport interface IRefineItemState extends React.ComponentState {\n isChecked: boolean;\n renderingError?: object;\n}\n\n/**\n * Single-select and multi-select refine item component (controlled by RefineSubmenu).\n */\nexport default class RefineItem extends React.Component {\n private readonly anchorType: React.RefObject;\n\n private readonly payLoad: IPayLoad;\n\n public constructor(props: IRefineItemProps) {\n super(props);\n this._onClick = this._onClick.bind(this);\n this.state = {\n isChecked: !!this.props.selectedRefinementCriterion\n };\n this.anchorType = React.createRef();\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\n }\n\n public shouldComponentUpdate(nextProps: IRefineItemProps,\n nextState: IRefineItemState): boolean {\n if (this.state === nextState && this.props === nextProps) {\n return false;\n }\n return true;\n }\n\n public render(): JSX.Element | undefined {\n const {\n isDisabled,\n refineItemCommonProps,\n parentProductRefinerHierarchy,\n productRefinerValue,\n selectedRefinementCriterion,\n productCountAriaLabel,\n singleProductCountAriaLabel,\n index,\n children,\n onToggle,\n context,\n telemetryContent,\n ...attrs\n } = this.props;\n if (!productRefinerValue) {\n refineItemCommonProps.telemetry.error('[refine-item] Cannot render refineItem without productRefinerValue');\n return undefined;\n }\n if (!productRefinerValue.LeftValueBoundString) {\n refineItemCommonProps.telemetry.warning(`[refine-item] RefineItem without LeftValueBoundString: ${JSON.stringify(productRefinerValue)}`);\n }\n const isSingleSelect = parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect;\n let itemTypeClassName = isSingleSelect ? 'single-select' : 'multi-select';\n itemTypeClassName = `ms-refine-submenu-item ${itemTypeClassName}`;\n const inputType = isSingleSelect ? 'radio' : 'checkbox';\n const isChecked = !!selectedRefinementCriterion;\n itemTypeClassName = isChecked ? `${itemTypeClassName}-checked` : itemTypeClassName;\n if (parentProductRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) {\n return this._renderRating(productRefinerValue, parentProductRefinerHierarchy, isChecked, context, index, telemetryContent,\n productCountAriaLabel, singleProductCountAriaLabel);\n\n }\n this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString;\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\n\n return (\n
  • \n \n {this._renderSwatch()}\n \n {productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}\n {productRefinerValue.Count !== undefined && ` (${productRefinerValue.Count})`}\n \n \n
  • \n );\n\n }\n\n private _renderSwatch(): JSX.Element | null {\n const productRefinerValue = this.props.productRefinerValue;\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\n const text = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\n\n const dimensionType = (this.props.parentProductRefinerHierarchy.KeyName?.toLocaleLowerCase() ?? '') as DimensionTypes;\n const hasColor = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchColorHexCode);\n const hasImage = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchImageUrl);\n const hasValidSwatch = hasColor || hasImage;\n const shouldDisplayAsSwatch = hasValidSwatch && checkIfShouldDisplayAsSwatch(\n dimensionType, this.props.context as ICoreContext);\n const swatchItems = shouldDisplayAsSwatch ? [\n {\n itemId: `${productRefinerValue.RefinerRecordId ?? ''}-${dimensionType}-${text}`,\n value: text,\n dimensionType,\n colorHexCode: productRefinerValue.SwatchColorHexCode,\n imageUrl: productRefinerValue.SwatchImageUrl\n }\n ] : undefined;\n\n if (!swatchItems) {\n return null;\n }\n\n return (\n \n );\n }\n\n private _getRefinerUrl(): string {\n const { urlBuilder, parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\n\n if (productRefinerValue) {\n return urlBuilder({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: !selectedRefinementCriterion\n });\n }\n\n return '';\n }\n\n private readonly _onClick = (e: React.MouseEvent): void => {\n e.preventDefault();\n\n const { parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\n if (productRefinerValue) {\n this.props.onToggle({\n parentProductRefinerHierarchy,\n productRefinerValue,\n isSelecting: !selectedRefinementCriterion\n });\n\n setTimeout(\n () => {\n this.anchorType.current && this.anchorType.current.focus();\n },\n 0\n );\n }\n };\n\n private _renderRating(productRefinerValue: ProductRefinerValue, parentProductRefinerHierarchy: IProductRefinerHierarchy,\n isChecked: boolean, context: ICoreContext, index?: number, telemetryContent?: ITelemetryContent,\n ratingUserCountAriaLabel?: string, ratingSingleUserCountAriaLabel?: string): JSX.Element | undefined {\n if (productRefinerValue.LeftValueBoundString) {\n this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString;\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\n const refinerRating = Number.parseInt(productRefinerValue.LeftValueBoundString, 10);\n const ratingRefiner = this.props.selectedRefinerValues?.find(value => value.DataTypeValue === productRefinerValue.DataTypeValue);\n const selectedRating = Number.parseInt(ratingRefiner?.LeftValueBoundString || '0', 10);\n const defaultChkProductCount = 1;\n let ratingComponentClass: string = 'ms-rating-component';\n if (refinerRating > selectedRating) {\n ratingComponentClass = `${ratingComponentClass}__up`;\n } else if (refinerRating < selectedRating) {\n ratingComponentClass = `${ratingComponentClass}__down`;\n } else {\n ratingComponentClass = `${ratingComponentClass}__current`;\n }\n const productCountAriaLabelValue = (productRefinerValue.Count !== undefined &&\n productRefinerValue.Count === defaultChkProductCount) ? (ratingSingleUserCountAriaLabel &&\n format(ratingSingleUserCountAriaLabel, productRefinerValue.Count)) : (ratingUserCountAriaLabel &&\n format(ratingUserCountAriaLabel, productRefinerValue.Count));\n return (\n \n \n \n \n {productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}\n \n \n \n );\n }\n return undefined;\n }\n\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\nimport { DisplayTemplate, ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\nimport { Button, Collapse, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\nimport RefineItem from './refine-item';\nimport { IRefineItemCommonProps } from './refine-item.props.common';\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\nimport { findMatchingRefinementCriterion, isRangeType } from './utilities';\n\n/**\n * Properties associated with the RefineSubmenu component.\n */\nexport interface IRefineSubmenuProps {\n tempRangeTypeTODO: RangeRefineItemType;\n minValueSliderThumbAriaLabel?: string;\n maxValueSliderThumbAriaLabel?: string;\n productRefinerHierarchy: IProductRefinerHierarchy;\n selectedRefinerValues: ProductRefinerValue[];\n refineItemCommonProps: IRefineItemCommonProps;\n isDisabled: boolean;\n isExpandedOnInitialLoad: boolean;\n context: ICoreContext>;\n moduleId: string;\n moduleTypeName: string;\n productCountAriaLabel?: string;\n singleProductCountAriaLabel?: string;\n isMobile?: boolean;\n\n /**\n * The telemetry content\n */\n telemetryContent?: ITelemetryContent;\n onUpdateRefiners(notfication: Readonly): void;\n urlBuilder(refiner: IRefineItemToggleNotification): string;\n}\n\n/**\n * Refine submenu state.\n */\nexport interface IRefineSubmenuState extends React.ComponentState {\n expanded: boolean;\n}\n\n/**\n *\n * The RefineSubmenu component renders the submenu category and child items.\n * This computed observes the stateful category hierarchy object.\n * @extends {React.PureComponent}\n */\nclass RefineSubmenu extends React.Component {\n constructor(props: IRefineSubmenuProps) {\n super(props);\n\n this._onToggleItem = this._onToggleItem.bind(this);\n this._onToggleSubmenu = this._onToggleSubmenu.bind(this);\n\n const isExpanded = this.props.isExpandedOnInitialLoad;\n\n // If (this.props.productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range) {\n // isExpanded = true;\n // }\n\n this.state = {\n expanded: isExpanded\n };\n }\n\n public shouldComponentUpdate(nextProps: IRefineSubmenuProps,\n nextState: IRefineSubmenuState): boolean {\n if (this.state === nextState && this.props === nextProps) {\n return false;\n }\n return true;\n }\n\n public render(): JSX.Element | null {\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\n\n if (!productRefinerHierarchy) {\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\n }\n\n if ((productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) && (this.props.context.app.config.hideRating)) {\n return null;\n }\n return (\n
    \n \n {productRefinerHierarchy.KeyName}\n \n \n {this._renderChildItems(productRefinerHierarchy)}\n \n
    \n );\n }\n\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\n if (isRangeType(productRefinerHierarchy.DataTypeValue)) {\n return this._renderRange(productRefinerHierarchy);\n }\n return this._renderSingleMultiSelect(productRefinerHierarchy);\n }\n\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context, productCountAriaLabel, singleProductCountAriaLabel, isMobile } = this.props;\n const isSingleSelect = (productRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect) && (productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating);\n const role = isSingleSelect ? { role: 'radiogroup' } : undefined;\n const refinerValuesList = (productRefinerHierarchy.Values || []);\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\n if (!child) {\n refineItemCommonProps.telemetry.error(\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\n );\n return null;\n }\n\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\n\n return (\n refinerValuesList.find(value => value.RefinerRecordId === selectedValue.RefinerRecordId))}\n refineItemCommonProps={refineItemCommonProps}\n onToggle={this._onToggleItem}\n urlBuilder={this.props.urlBuilder}\n isDisabled={isDisabled}\n key={index}\n index={index}\n context={context}\n moduleId={this.props.moduleId}\n moduleTypeName={this.props.moduleTypeName}\n telemetryContent={this.props.telemetryContent}\n productCountAriaLabel={productCountAriaLabel}\n singleProductCountAriaLabel={singleProductCountAriaLabel}\n isMobileView={isMobile}\n />\n );\n });\n return (\n
      \n {listItems}\n
    \n );\n }\n\n private _getRangeType(productRefinerHierarchy: IProductRefinerHierarchy): 'input' | 'slider' {\n if (productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Range ||\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Slider ||\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.SliderWithBars) {\n return 'slider';\n }\n return 'input';\n }\n\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context, minValueSliderThumbAriaLabel, maxValueSliderThumbAriaLabel } = this.props;\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\n const refinerValuesList = (productRefinerHierarchy.Values || []);\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\n if (!child) {\n refineItemCommonProps.telemetry.error(\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\n );\n return null;\n }\n\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\n\n const rangeType = this._getRangeType(productRefinerHierarchy);\n const key = selectedRefinementCriterion ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}` : `not-selected-${index}`;\n return (\n
  • \n \n
  • \n );\n });\n return (
      \n {listItems}\n
    );\n }\n\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\n this.props.onUpdateRefiners(itemToggleNotification);\n }\n\n private _onToggleSubmenu(): void {\n this.setState(prevState => ({\n expanded: !prevState.expanded\n }));\n }\n}\n\nexport default RefineSubmenu;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport * as React from 'react';\n\ninterface ISeparator {\n separator: string;\n}\n\nexport const Separator: React.FC = ({ separator }) => (\n {' '}\n {separator}\n {' '}\n);\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport * as React from 'react';\n\ninterface ITitle {\n className: string;\n text: string;\n}\n\nexport const Title: React.FC = ({ text, className }) => (\n {' '}\n {text}\n {' '}\n);\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CategoryHierarchy as CategoryHierarchyData, IProductRefinerHierarchy, IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\nimport MsDyn365, { getCatalogId, ICoreContext } from '@msdyn365-commerce/core';\nimport { format, ProductPrice, ProductRefinerValue, SortColumn,\n TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\nimport { ArrayExtensions, DimensionAvailabilitiesForProductSearchResultInput, DimensionTypes,\n getDimensionAvailabilitiesForProductSearchResultAction, getPriceForProductSearchResult,\n IDimensionsApp, PriceForProductSearchResultInput } from '@msdyn365-commerce-modules/retail-actions';\nimport { getTelemetryObject, ILabeledDropdownOnChangeNotification, ILabeledDropdownOption, IModuleProps,\n INodeProps, ITelemetryContent, LabeledDropdown, UncontrolledPagination } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport { computed, observable, reaction, transaction } from 'mobx';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { buildListPageUrl, getCollectionProducts, getCollectionRefinersAction, getCurrentUrl,\n GetFullProductsByCollectionInput, parseQueryParam, RefinersByCollectionInput, sortOptions } from './actions';\nimport { hydrateRefinersFromUrl } from './actions/url-utils';\nimport {\n ErrorMessage, FeatureSearchResultItem, getUpdatedRefinementCriteria, IChoiceSummaryClickNotification,\n IRefineItemCommonProps, IRefineItemToggleNotification, ISearchResultModalViewProps, isMatchingRefinementCriterion,\n Link, ModalToggle, ProductSearchResultItems, SearchResultModal, Separator, Title\n} from './components';\nimport ChoiceSummary from './components/choice-summary';\nimport RefineSubmenu from './components/refine-submenu';\nimport { ISearchResultContainerData } from './search-result-container.data';\nimport { expandRefinersCount, ISearchResultContainerProps } from './search-result-container.props.autogenerated';\n\nexport interface ISearchResultContainerViewProps extends ISearchResultContainerProps {\n products?: React.ReactNode;\n className?: string;\n SearchResultContainer: IModuleProps;\n TitleViewProps: ITitleViewProps;\n categoryHierarchy: ICategoryHierarchyViewProps;\n pagination?: React.ReactNode;\n ProductsContainer: INodeProps;\n ProductSectionContainer: INodeProps;\n refineMenu: IRefineMenuViewProps;\n sortByOptions: ISortByViewProps;\n choiceSummary?: React.ReactNode;\n modalToggle: React.ReactNode;\n searchResultModal: ISearchResultModalViewProps;\n isMobile: boolean;\n CategoryNavContainer: INodeProps;\n RefineAndProductSectionContainer: INodeProps;\n errorMessage: React.ReactNode;\n FeatureSearchContainer: INodeProps;\n similarLookProduct?: React.ReactNode;\n productPrices?: ProductPrice[];\n}\n\nexport interface ITitleViewProps {\n TitleContainer: INodeProps;\n title: ISearchResultTitle;\n}\n\nexport interface IRefineMenuViewProps {\n RefineMenuContainer: INodeProps;\n RefinerSectionContainer: INodeProps;\n refiners?: React.ReactNode[];\n}\n\nexport interface ICategoryHierarchyViewProps {\n categoryHierarchyList?: React.ReactNode[];\n categoryHierarchySeparator?: React.ReactNode;\n CategoryHierarchyContainer: INodeProps;\n}\n\nexport interface ISortByViewProps {\n SortingContainer: INodeProps;\n sortByDropDown?: React.ReactNode;\n}\n\nexport type GridSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Title component for search result container.\n */\nexport interface ISearchResultTitle {\n titlePrefix?: React.ReactNode;\n titleText?: React.ReactNode;\n titleCount?: React.ReactNode;\n}\n\nexport interface ISearchResultContainerState {\n sortingState: ISortByCollectionState;\n modalIsOpen: boolean;\n refiners: IProductRefinerHierarchy[];\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\n}\n\ninterface ISortByCollectionState {\n selectedSortByOption: ILabeledDropdownOption;\n pending: boolean;\n}\n\n/**\n *\n * SearchResultContainer component.\n * @extends {React.PureComponent>}\n */\n@observer\nexport default class SearchResultContainer extends React.PureComponent, ISearchResultContainerState> {\n\n @computed get isMobile(): boolean {\n return (this._viewport === 'xs' || this._viewport === 'sm');\n }\n\n private readonly sortByDropdownOptions: ILabeledDropdownOption[] = [\n { key: sortOptions.sortByOptionRelevanceDesc, value: this.props.resources.sortByOptionRelevanceDesc },\n { key: sortOptions.sortByOptionNameAsc, value: this.props.resources.sortByOptionNameAsc },\n { key: sortOptions.sortByOptionNameDesc, value: this.props.resources.sortByOptionNameDesc },\n { key: sortOptions.sortByOptionPriceAsc, value: this.props.resources.sortByOptionPriceAsc },\n { key: sortOptions.sortByOptionPriceDesc, value: this.props.resources.sortByOptionPriceDesc },\n { key: sortOptions.sortByOptionRatingDesc, value: this.props.resources.sortByOptionRatingDesc },\n { key: sortOptions.sortByOptionBestSelling, value: this.props.resources.sortByOptionBestSelling },\n { key: sortOptions.sortByOptionNewScore, value: this.props.resources.sortByOptionNewScore },\n { key: sortOptions.sortByOptionTrendingScore, value: this.props.resources.sortByOptionTrendingScore }\n ];\n\n private readonly _refineItemCommonProps: IRefineItemCommonProps;\n\n private readonly _pageType: string | undefined = this.props.context.request.urlTokens.pageType;\n\n @observable\n private _viewport: GridSize;\n\n private readonly _modalToggleRef: React.RefObject;\n\n private readonly _sortAndFilterContainerRef: React.RefObject;\n\n private expandrefinerCount: number | undefined = 0;\n\n private readonly telemetryContent: ITelemetryContent;\n\n private readonly productPrices: ProductPrice[];\n\n private readonly defaultPageNumber = 0;\n\n private readonly catalogId = getCatalogId(this.props.context.request);\n\n public constructor(props: ISearchResultContainerProps, state: ISearchResultContainerState) {\n super(props);\n this._viewport = props.context.request && props.context.request.device && props.context.request.device.Type === 'Mobile' ? 'xs' : 'lg';\n this._modalToggleRef = React.createRef();\n this._sortAndFilterContainerRef = React.createRef();\n this._toggleModal = this._toggleModal.bind(this);\n this._updateViewport = this._updateViewport.bind(this);\n this.productPrices = [];\n this.state = {\n sortingState: {\n pending: false,\n selectedSortByOption: this.sortByDropdownOptions[0]\n },\n modalIsOpen: false,\n refiners: []\n };\n const {\n placeholderTextMax,\n minLabel,\n maxLabel,\n rangeNameFormat\n } = this.props.resources;\n\n const locale = this.props.context.request.locale;\n const telemetry = this.props.telemetry;\n const validationErrorNaN = this.props.resources.validationErrorNotNumber;\n const validationErrorRange = this.props.resources.validationErrorNotRange;\n this._refineItemCommonProps = {\n telemetry,\n locale,\n placeholderTextMax,\n minLabel,\n maxLabel,\n rangeNameFormat,\n validationErrorNaN,\n validationErrorRange\n };\n this.telemetryContent = getTelemetryObject(this.props.context.request.telemetryPageName!, this.props.friendlyName, this.props.telemetry);\n\n // Initalization of list page\n this.props.data.products.then((products) => {\n this.props.data.listPageState.then((listPageState) => {\n if (this._pageType === 'Category') {\n listPageState.pageType = 'Category';\n } else {\n listPageState.pageType = 'Search';\n }\n\n let querySorting: SortColumn[] = [];\n\n if (this.props.context.request.query && this.props.context.request.query.sorting) {\n querySorting = JSON.parse(decodeURIComponent(this.props.context.request.query.sorting)) as SortColumn[];\n }\n\n listPageState.currentPageNumber = this.props.context.request.query && (+this.props.context.request.query.skip / (this.props.config.itemsPerPage || 10)) || 0;\n listPageState.sortingCritera = { Columns: querySorting };\n listPageState.pageSize = this.props.config.itemsPerPage || 10;\n listPageState.activeProducts = products.products;\n listPageState.totalProductCount = products.count;\n listPageState.activeFilters = hydrateRefinersFromUrl(this.props.context.request);\n\n // Initialize reaction based on listPageState properties\n reaction(\n () => {\n return [listPageState.activeFilters && listPageState.activeFilters.length, listPageState.currentPageNumber, listPageState.sortingCritera && listPageState.sortingCritera.Columns && listPageState.sortingCritera.Columns.length];\n },\n () => {\n const input = new GetFullProductsByCollectionInput(\n listPageState.pageType,\n this.props.context.request.apiSettings,\n { Paging: { Top: this.props.config.itemsPerPage, Skip: Math.max((listPageState.pageSize * (listPageState.currentPageNumber || 0)), 0) }, count: true, Sorting: listPageState.sortingCritera || {} },\n listPageState.activeFilters || [],\n +(this.props.context.request.urlTokens.itemId || 0),\n\n this.props.context.request.query && this.props.context.request.query.q ? this.props.context.request.query.q : JSON.stringify({ ProductId: this.props.context.request.query?.productId, Recommendation: this.props.context.request.query?.recommendation }),\n !!(this.props && this.props.config && this.props.config.includeAttributes !== undefined && this.props.config.includeAttributes),\n this.props.config.updateRefinerPanel,\n this.props.context.request.locale,\n this.catalogId\n );\n getCollectionProducts(input, this.props.context.actionContext).then(productResults => {\n listPageState.activeProducts = productResults.products;\n listPageState.totalProductCount = productResults.count;\n if (this.props.config.enableAffiliationBasedPricing && this.props.context.actionContext.requestContext?.user?.isAuthenticated) {\n this._getActivePrice();\n }\n });\n\n if (this.props.config.updateRefinerPanel) {\n const refinerInput = new RefinersByCollectionInput(\n listPageState.pageType,\n this.props.context.request.apiSettings,\n {\n Paging: {\n Top: this.props.config.itemsPerPage,\n Skip: Math.max((listPageState.pageSize * (listPageState.currentPageNumber ?? this.defaultPageNumber)),\n this.defaultPageNumber)\n },\n count: true, Sorting: listPageState.sortingCritera ?? {}\n },\n listPageState.activeFilters ?? [],\n +(this.props.context.request.urlTokens.itemId ?? 0),\n this.props.context.request.query?.q ? this.props.context.request.query.q : this.props.context.request.query?.productId,\n false,\n this.props.config.updateRefinerPanel\n );\n\n getCollectionRefinersAction(refinerInput, this.props.context.actionContext).then((refiners) => {\n this.setState({ refiners });\n }).catch(error => {\n this.props.telemetry.error(error);\n });\n }\n }\n );\n\n });\n });\n\n if (this.props.context.request.query?.productId) {\n this.props.data.featureProduct.then((products) => {\n this.props.data.listPageState.then((listPageStateFeature) => {\n listPageStateFeature.featureProduct = products;\n });\n });\n }\n this._updateViewport();\n }\n\n public static getFriendlyName(locale: string, nameTranslations?: TextValueTranslation[]): string | undefined {\n let nameTranslation: TextValueTranslation | undefined;\n if (locale && nameTranslations && ArrayExtensions.hasElements(nameTranslations)) {\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\n }\n\n return nameTranslation?.Text;\n }\n\n public async componentDidMount(): Promise {\n if (MsDyn365.isBrowser && window.addEventListener) {\n window.addEventListener('resize', this._updateViewport);\n this._updateViewport();\n }\n if (this.props.config.enableAffiliationBasedPricing &&\n this.props.context.actionContext.requestContext?.user?.isAuthenticated) {\n this._getActivePrice();\n }\n\n const context = this.props.context as ICoreContext;\n const dimensionsToDisplayOnProductCard = context.app.config.dimensionsInProductCard;\n const dimensionsToDisplayAsSwatch = context.app.config.dimensionsAsSwatchType;\n if (ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) && !dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) &&\n ArrayExtensions.hasElements(dimensionsToDisplayAsSwatch) && !dimensionsToDisplayAsSwatch.includes(DimensionTypes.none) &&\n this.props.config.includeAttributes) {\n await this._getProductsDimensionsAvailabilities();\n }\n }\n\n public componentWillUnmount(): void {\n if (MsDyn365.isBrowser && window.removeEventListener) {\n window.removeEventListener('resize', this._updateViewport);\n }\n }\n\n public render(): JSX.Element {\n const { imageSettings, className } = this.props.config;\n const { resources } = this.props;\n const products = (this.props.data.listPageState.result && this.props.data.listPageState.result.activeProducts) || [];\n const searchProduct = (this.props.data.listPageState.result && this.props.data.listPageState.result.featureProduct) || null;\n let errorText = '';\n if (!products || products.length === 0) {\n errorText = this._pageType === 'Category' ? resources.resultCategoryNotFoundText : resources.resultSearchNotFoundText;\n\n }\n const productsComponent = this._getProducts();\n const featureComponent = (\n \n );\n\n const searchResultContainerViewProps = {\n ...this.props,\n products: productsComponent,\n TitleViewProps: this._getCollectionTitle(),\n categoryHierarchy: !this.props.config.disableHierarchy && this._getCategoryHierarchy(),\n refineMenu: this._getRefineMenu(),\n className: classnames('ms-search-result-container', className),\n SearchResultContainer: {\n moduleProps: this.props,\n className: classnames('ms-search-result-container', className)\n },\n sortByOptions: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 ? this._getSortingDropDown() : null,\n pagination: this._getPagination(),\n ProductsContainer: { className: 'ms-search-result-container__Products' },\n ProductSectionContainer: { className: 'ms-search-result-container__product-section' },\n CategoryNavContainer: { className: 'ms-search-result-container__category-nav-section' },\n RefineAndProductSectionContainer: { className: 'ms-search-result-container__refine-product-section' },\n choiceSummary: this._getChoiceSummary(),\n modalToggle: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 ? (\n \n ) : null,\n searchResultModal: this._getSearchResultModal(),\n isMobile: this.isMobile,\n errorMessage: errorText && (\n \n ),\n FeatureSearchContainer: { className: 'ms-feature-search-result' },\n similarLookProduct: this.props.data.listPageState.result && (this.props.data.listPageState.result.featureProduct !== null && this.props.data.listPageState.result.featureProduct !== undefined) ? featureComponent : null,\n productPrices: this.productPrices\n };\n return this.props.renderView(searchResultContainerViewProps) as React.ReactElement;\n }\n\n /**\n * Get products dimension availabilities.\n * @returns Void.\n */\n private readonly _getProductsDimensionsAvailabilities = async (): Promise => {\n const productsList = (this.props.data.listPageState.result?.activeProducts) ?? [];\n\n const productsDimensionAvailabilities = await getDimensionAvailabilitiesForProductSearchResultAction(\n new DimensionAvailabilitiesForProductSearchResultInput(productsList, this.props.context as ICoreContext),\n this.props.context.actionContext);\n\n if (ArrayExtensions.hasElements(productsDimensionAvailabilities)) {\n this.setState({ productsDimensionAvailabilities });\n }\n };\n\n /**\n * Get the active price for the products.\n */\n private readonly _getActivePrice = async (): Promise => {\n const productsList = (this.props.data.listPageState.result?.activeProducts) ?? [];\n const products = await getPriceForProductSearchResult(\n new PriceForProductSearchResultInput(productsList),\n this.props.context.actionContext);\n\n const listPageState = await this.props.data.listPageState;\n listPageState.activeProducts = products;\n };\n\n private readonly _getSearchResultModal = (): ISearchResultModalViewProps => {\n const { resources } = this.props;\n return SearchResultModal(\n {\n resources: {\n modalCloseButtonText: resources.modalCloseButtonText,\n modalTitle: resources.modalTitle\n },\n isOpen: this.state.modalIsOpen,\n returnRef: this._modalToggleRef,\n onModalToggle: this._toggleModal\n });\n };\n\n private readonly _getCollectionTitle = (): ITitleViewProps => {\n const { data, context, resources } = this.props;\n\n let collectionTitle: string | undefined = '';\n if (context && context.request && context.request.query && context.request.query.q) {\n collectionTitle = `\"${context.request.query.q}\"`;\n } else {\n collectionTitle = (data.category.result && SearchResultContainer.getFriendlyName(context.request.locale, data.category.result.NameTranslations)) ||\n (data.category.result && data.category.result.Name);\n }\n let productCountText = '';\n let productCountNumber: number | undefined;\n if (data.listPageState && data.listPageState.result && data.listPageState.result.totalProductCount !== undefined) {\n productCountNumber = data.listPageState.result.totalProductCount;\n } else if (data.products && data.products.result) {\n productCountNumber = data.products.result.count;\n }\n\n if (productCountNumber && productCountNumber !== 0) {\n productCountText = productCountNumber !== 1 ? format(this.props.resources.numberOfProducts, productCountNumber) : this.props.resources.oneProduct;\n } else {\n productCountText = format(this.props.resources.numberOfProducts, 0);\n }\n const pageName = context.request.telemetryPageName ? `result-count-${context.request.telemetryPageName.toLowerCase()}` : '';\n const titlePrefix = ;\n const titleText = collectionTitle && <Title className='ms-search-result__collection-title-text' text={collectionTitle} />;\n const titleCount = <Title className='ms-search-result__collection-title-count' text={productCountText} />;\n\n return {\n TitleContainer: { className: `ms-search-result-container__title ${pageName}` },\n title: {\n titlePrefix,\n titleText,\n titleCount\n }\n };\n\n };\n\n private readonly _getCategoryHierarchy = (): ICategoryHierarchyViewProps => {\n const { data } = this.props;\n const categoryHierarchy = data.categoryHierarchy.result;\n const categoryLinks =\n categoryHierarchy && categoryHierarchy.map((value: CategoryHierarchyData, index: number) => {\n\n return (\n <Link\n key={index}\n text={value.Name}\n ariaLabel={`${this.props.resources.categoryLinkAriaLabel} ${value.Name}`}\n href={value.Url}\n />\n );\n });\n const categoryLinkSeparator = <Separator separator='/' />;\n\n return {\n CategoryHierarchyContainer: { tag: 'nav', className: 'ms-search-result-container__category-hierarchy' },\n categoryHierarchyList: categoryLinks,\n categoryHierarchySeparator: categoryLinkSeparator\n };\n\n };\n\n private readonly _getSortingDropDown = (): ISortByViewProps => {\n const { resources } = this.props;\n const activeDropdown = this._getCurrentlySelectedOption() || this.state.sortingState.selectedSortByOption;\n let dropdwonOptions = this.sortByDropdownOptions;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- App config settings are of \"any\" value.\n if (this.props.context.app.config.hideRating) {\n dropdwonOptions = this.sortByDropdownOptions.filter((dropdownOption) => dropdownOption.key !== 'AverageRating-Desc');\n }\n const dropdown = (\n <LabeledDropdown\n labelClassname='reviews-list-sort-by'\n labelText={resources.sortByDropdownLabel}\n dropdownId='categorySortByDropdown'\n dropdownClassname='reviews-list-dropdown'\n toggleColor='link'\n dropdownOptions={dropdwonOptions}\n selectedOption={activeDropdown}\n onSelectOption={this._updateSortByDropdown}\n ref={this._sortAndFilterContainerRef}\n />);\n return {\n SortingContainer: { className: 'ms-search-result-container__Sort-by-category' },\n sortByDropDown: dropdown\n };\n };\n\n private readonly _getPagination = (): React.ReactNode => {\n const { config, context, data, resources } = this.props;\n const listPageState = data && data.listPageState && data.listPageState.result;\n const fullUrl = getCurrentUrl(context.request);\n const itemsPerPage = config.itemsPerPage || 10;\n const skipCount = listPageState && listPageState.currentPageNumber !== null ? (listPageState.currentPageNumber * (this.props.config.itemsPerPage || 10)) : ((this.props.context.request.query && +this.props.context.request.query.skip) || 0);\n const totalItems = listPageState && listPageState.totalProductCount || 0;\n const previousText = resources.flipperPrevious;\n const nextText = resources.flipperNext;\n\n if (totalItems <= itemsPerPage) {\n return null;\n }\n return (\n <UncontrolledPagination\n className='ms-search-result-container__pagination'\n role='navigation'\n aria-label={resources.paginationAriaLabel}\n url={fullUrl.href}\n qsp='skip'\n items={totalItems}\n itemsPerPage={itemsPerPage}\n startingItem={skipCount}\n previousText={this._renderPrev(previousText)}\n nextText={this._renderNext(nextText)}\n previousAriaLabel={previousText}\n nextAriaLabel={nextText}\n telemetryContent={this.telemetryContent}\n />);\n };\n\n private readonly _getRefineMenu = (): IRefineMenuViewProps => {\n const { data, context, config } = this.props;\n const tempRangeTypeTODO = context.request.query && context.request.query.inputRange ? 'input' : 'slider';\n const validRefiners = this.props.config.updateRefinerPanel && ArrayExtensions.hasElements(this.state.refiners) ? this.state.refiners.filter(refiner => {\n return ArrayExtensions.hasElements(refiner.Values);\n }) : data.refiners.result && data.refiners.result.filter(refiner => {\n return ArrayExtensions.hasElements(refiner.Values);\n });\n\n const activeRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\n\n this._getexpandRefinerCount(validRefiners && validRefiners.length, config.expandRefinersCount);\n const expandedRefiners = this.expandrefinerCount;\n const subMenus = validRefiners && validRefiners.map((productRefinerHierarchy: IProductRefinerHierarchy, index: number) => {\n return (\n <RefineSubmenu\n productRefinerHierarchy={productRefinerHierarchy}\n selectedRefinerValues={activeRefiners}\n refineItemCommonProps={this._refineItemCommonProps}\n minValueSliderThumbAriaLabel={this.props.resources.minValueSliderThumbAriaLabel}\n maxValueSliderThumbAriaLabel={this.props.resources.maxValueSliderThumbAriaLabel}\n key={index}\n onUpdateRefiners={this._onUpdateRefiners}\n urlBuilder={this._buildRefinerUrl}\n isDisabled={false}\n isExpandedOnInitialLoad={!!(expandedRefiners && expandedRefiners > index)}\n tempRangeTypeTODO={tempRangeTypeTODO}\n context={context}\n moduleId={this.props.id}\n moduleTypeName={this.props.typeName}\n telemetryContent={this.telemetryContent}\n productCountAriaLabel={this.props.resources.productCountAriaLabel}\n singleProductCountAriaLabel={this.props.resources.singleProductCountAriaLabel}\n isMobile={this.isMobile}\n />\n );\n });\n\n return {\n RefineMenuContainer: { className: 'ms-search-result-container__refine-menu' },\n RefinerSectionContainer: { className: 'ms-search-result-container__refiner-section' },\n refiners: subMenus\n };\n\n };\n\n private readonly _getChoiceSummary = (): React.ReactNode => {\n const { resources, data, telemetry } = this.props;\n const selectedRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\n return (\n <ChoiceSummary\n classNames='ms-choice-summary-by-category'\n clearAllText={resources.clearAllText}\n label={resources.choiceSummaryLabel}\n closeAriaLabel={resources.closeAriaLabel}\n selectedChoices={selectedRefiners}\n\n // @ts-expect-error: NOTE Type-unsafe line below, null refinersByCategoryHierarchy case not handled\n refinerHierarchy={data.refiners.result}\n choiceFormat={resources.choiceFormat}\n choiceRangeValueFormat={resources.choiceRangeValueFormat}\n telemetry={telemetry}\n onChoiceClicked={this._onChoiceClicked}\n urlBuilder={this._buildRefinerUrlForChoiceSummary}\n choiceAriaLabel={resources.choiceAriaLabel}\n telemetryContent={this.telemetryContent}\n context={this.props.context}\n />\n );\n\n };\n\n private readonly _getProducts = (): JSX.Element => {\n const { imageSettings, allowBackNavigation } = this.props.config;\n const { resources } = this.props;\n const breaCrumbType = this.props.context.app.config.breadcrumbType;\n const allowBack = allowBackNavigation && (breaCrumbType === 'back' || breaCrumbType === 'categoryAndBack');\n const products = (this.props.data.listPageState.result && this.props.data.listPageState.result.activeProducts) || [];\n const quickviewslot = this.props.slots && this.props.slots.quickview && this.props.slots.quickview[0];\n const isPriceMinMaxFeatureState = this.props.data.featureState.result?.find(\n featureState => featureState.Name === 'Dynamics.AX.Application.RetailSearchPriceRangeFeature');\n return (\n <ProductSearchResultItems\n products={products}\n context={this.props.context}\n imageSettings={imageSettings}\n resources={resources}\n moduleType={this.props.typeName}\n moduleId={this.props.id}\n allowBackNavigation={allowBack}\n telemetryContent={this.telemetryContent}\n quickviewSlot={quickviewslot}\n channelInventoryConfigurationId={this.props.data.products.result?.channelInventoryConfigurationId}\n isPriceMinMaxEnabled={isPriceMinMaxFeatureState?.IsEnabled}\n productsDimensionAvailabilities={this.state.productsDimensionAvailabilities}\n />\n );\n };\n\n private readonly _updateSortByDropdown = (notification: ILabeledDropdownOnChangeNotification): void => {\n const { context } = this.props;\n const requestContext = context && context.request;\n const actionContext = context && context.actionContext;\n\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\n const error = `[sort-by-category] cannot sort without context: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\n this.props.telemetry.warning(error);\n }\n\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), undefined, [this._getSortColumnFromSelectedOption(notification.selectedOption)], undefined));\n transaction(() => {\n this.props.data.listPageState.result!.currentPageNumber = 0;\n this.props.data.listPageState.result!.sortingCritera = { Columns: [this._getSortColumnFromSelectedOption(notification.selectedOption)] };\n });\n };\n\n private readonly _getSortColumnFromSelectedOption = (option: ILabeledDropdownOption): SortColumn => {\n const { data } = this.props;\n\n if (!data.searchConfiguration.result) {\n return {};\n }\n\n const mappedConfiguration = data.searchConfiguration.result.find((searchConfiguration) => {\n return searchConfiguration.key === option.key;\n });\n\n if (mappedConfiguration) {\n return mappedConfiguration.sortColumn;\n }\n\n return {};\n };\n\n /**\n * Retrieves current sort criteria.\n * @returns Sort criteria column which is currently active or undefined if it's not specified.\n */\n private readonly _getSortCriteriaColumn = (): SortColumn | undefined => {\n const sortCriteria = this.props.data.listPageState.result?.sortingCritera;\n if (ArrayExtensions.hasElements(sortCriteria?.Columns)) {\n return sortCriteria!.Columns[0];\n }\n\n const queryColumns = parseQueryParam<SortColumn[]>('sorting', this.props.context.request);\n if (ArrayExtensions.hasElements(queryColumns)) {\n return queryColumns[0];\n }\n\n return undefined;\n };\n\n /**\n * Retrieves current selected dropdown option based on the sort criteria.\n * @returns Current dropdown option.\n */\n private readonly _getCurrentlySelectedOption = (): ILabeledDropdownOption | undefined => {\n const activeSortColumn = this._getSortCriteriaColumn();\n\n const searchConfiguration = this.props.data.searchConfiguration.result;\n\n if (!activeSortColumn || !searchConfiguration) {\n return undefined;\n }\n\n const activeMappedConfig = searchConfiguration.find(mappedSearchConfig => mappedSearchConfig.sortColumn.ColumnName === activeSortColumn.ColumnName &&\n mappedSearchConfig.sortColumn.IsDescending === activeSortColumn.IsDescending\n );\n if (!activeMappedConfig) {\n return undefined;\n }\n\n return this.sortByDropdownOptions.find(dropdownOption => dropdownOption.key === activeMappedConfig.key);\n };\n\n private readonly _onUpdateRefiners = (itemToggleNotification: IRefineItemToggleNotification): void => {\n const { context } = this.props;\n const requestContext = context && context.request;\n const actionContext = context && context.actionContext;\n\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\n const error = `Refine menu cannot refine search criteria: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\n this.props.telemetry.warning(error);\n }\n\n const updatedRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result && this.props.data.listPageState.result.activeFilters || []);\n\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), updatedRefinementCriteria));\n transaction(() => {\n this.props.data.listPageState.result!.currentPageNumber = 0;\n this.props.data.listPageState.result!.activeFilters = updatedRefinementCriteria;\n });\n };\n\n private readonly _buildRefinerUrl = (itemToggleNotification: IRefineItemToggleNotification): string => {\n if (this.props.data.listPageState.result) {\n const newRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result.activeFilters || []);\n\n return buildListPageUrl(getCurrentUrl(this.props.context.request), newRefinementCriteria);\n }\n this.props.telemetry.warning('[buildRefinerQueryString]List Page State Not available, unable to build refiner URL');\n return '';\n\n };\n\n private readonly _onChoiceClicked = (notification: IChoiceSummaryClickNotification): void => {\n const { data, telemetry } = this.props;\n\n if (!data.listPageState.result) {\n telemetry.warning('[choice-summary-by-category._onChoiceClicked]ListPageState unavailable, unable to update refiners.');\n return;\n }\n\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\n\n if (!notification.clearAll) {\n const selectedChoice = notification.choiceClicked;\n if (!selectedChoice) {\n telemetry.warning('[choice-summary-by-category._onChoiceClicked] Choice could not be determined');\n return;\n }\n currentRefinementCriteria = currentRefinementCriteria.filter(\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedChoice, selectedCriterion)\n );\n } else {\n currentRefinementCriteria = [];\n\n // Set focus to sort and filter\n const dropdownElementId = this._sortAndFilterContainerRef.current && this._sortAndFilterContainerRef.current.props.dropdownId;\n const dropdownElement = dropdownElementId && document.getElementById(dropdownElementId);\n setTimeout(() => {\n dropdownElement && dropdownElement.focus();\n },\n 50);\n }\n\n const fullUrl = getCurrentUrl(this.props.context.request);\n window.history.pushState({}, '', buildListPageUrl(fullUrl, currentRefinementCriteria));\n data.listPageState.result.currentPageNumber = 0;\n data.listPageState.result.activeFilters = currentRefinementCriteria;\n };\n\n private readonly _buildRefinerUrlForChoiceSummary = (selectedRefiner: ProductRefinerValue, isClearAll: boolean): string => {\n const { data, telemetry } = this.props;\n const fullUrl = getCurrentUrl(this.props.context.request);\n\n if (!data.listPageState.result) {\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl]ListPageState unavailable, unable to create refiner URL.');\n return fullUrl.href;\n }\n\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\n\n if (!isClearAll) {\n if (!selectedRefiner) {\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl] URL for Choice could not be determined');\n return fullUrl.href;\n }\n currentRefinementCriteria = currentRefinementCriteria.filter(\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedRefiner, selectedCriterion)\n );\n } else {\n currentRefinementCriteria = [];\n }\n\n return buildListPageUrl(fullUrl, currentRefinementCriteria);\n };\n\n private _getViewport(): GridSize {\n const { context } = this.props;\n\n // Always render in mobile viewport on a mobile device\n if (context.request && context.request.device && context.request.device.Type === 'Mobile') {\n return 'xs';\n }\n\n if (MsDyn365.isBrowser && window.innerWidth) {\n const gridSettings = context.request.gridSettings;\n if (gridSettings) {\n if (gridSettings.xs && window.innerWidth <= gridSettings.xs.w) {\n return 'xs';\n } else if (gridSettings.sm && window.innerWidth <= gridSettings.sm.w) {\n return 'sm';\n } else if (gridSettings.md && window.innerWidth <= gridSettings.md.w) {\n return 'md';\n } else if (gridSettings.lg && window.innerWidth <= gridSettings.lg.w) {\n return 'lg';\n }\n return 'xl';\n\n }\n }\n\n return 'lg';\n }\n\n private _toggleModal(): void {\n this.setState({\n modalIsOpen: !this.state.modalIsOpen\n });\n }\n\n private _updateViewport(): void {\n this._viewport = this._getViewport();\n\n if (this.state.modalIsOpen && !this.isMobile) {\n this._toggleModal();\n }\n }\n\n private readonly _getexpandRefinerCount = (validRefiners?: number, refinerCount?: expandRefinersCount): void => {\n switch (refinerCount) {\n case expandRefinersCount.all:\n this.expandrefinerCount = validRefiners;\n break;\n case expandRefinersCount.one:\n this.expandrefinerCount = 1;\n break;\n case expandRefinersCount.two:\n this.expandrefinerCount = 2;\n break;\n case expandRefinersCount.three:\n this.expandrefinerCount = 3;\n break;\n case expandRefinersCount.four:\n this.expandrefinerCount = 4;\n break;\n default:\n this.expandrefinerCount = 0;\n }\n };\n\n /**\n * Renders a Pagination previous text.\n * @param paginationPreviousText - Pagination previous text from resources.\n * @returns Previous text and flipper icon.\n */\n private readonly _renderPrev = (paginationPreviousText: string) => {\n return (\n <div className='msc-pagination__prev'>\n <span className='ms-search-result__pagination-left' aria-hidden='true' />\n <span className='prev-text'>\n {paginationPreviousText}\n </span>\n </div>\n );\n };\n\n /**\n * Renders a Pagination next text.\n * @param paginationNextText - Pagination next text from resources.\n * @returns Next text and flipper icon.\n */\n private readonly _renderNext = (paginationNextText: string) => {\n return (\n <div className='msc-pagination__next'>\n <span className='next-text'>\n {paginationNextText}\n </span>\n <span className='ms-search-result__pagination-right' aria-hidden='true' />\n </div>\n );\n };\n\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Module, Node } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchResultModalViewProps } from './components';\nimport { ICategoryHierarchyViewProps, IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from './search-result-container';\n\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps> = props => {\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\n refineMenu, categoryHierarchy, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, FeatureSearchContainer, similarLookProduct } = props;\n const isRecoSearchPage = props.context.actionContext.requestContext.query?.recommendation;\n if (isMobile) {\n return (\n <Module {...SearchResultContainer}>\n {renderCategoryHierarchy(categoryHierarchy)}\n {renderTitle(TitleViewProps)}\n {choiceSummary}\n {modalToggle}\n {createSearchResultModal(searchResultModal, refineMenu, sortByOptions, isRecoSearchPage)}\n <Node {...FeatureSearchContainer}>\n {similarLookProduct}\n </Node>\n <Node {...ProductsContainer}>\n {errorMessage}\n {products}\n </Node>\n {pagination}\n </Module>\n );\n }\n return (\n <Module {...SearchResultContainer}>\n <Node {...CategoryNavContainer}>\n {categoryHierarchy && renderCategoryHierarchy(categoryHierarchy)}\n {TitleViewProps && renderTitleCount(TitleViewProps)}\n </Node>\n <Node {...RefineAndProductSectionContainer}>\n {refineMenu && renderRefiner(refineMenu)}\n <Node {...ProductSectionContainer}>\n {TitleViewProps && renderTitle(TitleViewProps)}\n {choiceSummary}\n {sortByOptions && !isRecoSearchPage && renderSort(sortByOptions)}\n <Node {...FeatureSearchContainer}>\n {similarLookProduct}\n </Node>\n <Node {...ProductsContainer}>\n {errorMessage}\n {products}\n </Node>\n {pagination}\n </Node>\n </Node>\n </Module>\n );\n\n};\n\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps,\n sortByDropDown: ISortByViewProps, isRecoSearchPage?: string): JSX.Element => {\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader,\n createModalBody(modalProps, refineMenu, sortByDropDown, isRecoSearchPage), modalProps.modalFooter);\n};\n\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps,\n sortByDropDown: ISortByViewProps, isRecoSearchPage?: string): JSX.Element | null => {\n if (sortByDropDown) {\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, isRecoSearchPage), renderRefiner(refineMenu));\n }\n return null;\n};\n\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\n if (refiners) {\n return (\n <Node {...RefinerSectionContainer}>\n <Node {...RefineMenuContainer}>\n {refiners.map((submenu, index) => (\n <React.Fragment key={index}>\n {submenu}\n </React.Fragment>\n ))}\n </Node>\n </Node>\n );\n }\n return null;\n};\n\nconst renderSort = (props: ISortByViewProps, isRecoSearchPage?: string): JSX.Element | null => {\n const { SortingContainer, sortByDropDown } = props;\n if (sortByDropDown && !isRecoSearchPage) {\n return (\n <Node {...SortingContainer}>\n {sortByDropDown}\n </Node>\n );\n }\n return null;\n};\n\nconst renderCategoryHierarchy = (props: ICategoryHierarchyViewProps): JSX.Element | null => {\n const { CategoryHierarchyContainer, categoryHierarchyList, categoryHierarchySeparator } = props;\n if (categoryHierarchyList) {\n return (\n <Node {...CategoryHierarchyContainer}>\n {categoryHierarchyList.map((category, index) => (\n <React.Fragment key={index}>\n {category}\n {categoryHierarchyList && categoryHierarchyList[index + 1] && categoryHierarchySeparator}\n </React.Fragment>\n ))}\n </Node>\n );\n }\n\n return null;\n};\n\nconst renderTitle = (props: ITitleViewProps): JSX.Element | null => {\n const { title, TitleContainer } = props;\n if (title) {\n return (\n <Node {...TitleContainer}>\n <h2>\n {title.titlePrefix}\n {title.titleText}\n </h2>\n </Node>\n );\n }\n return null;\n};\n\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\n const { title, TitleContainer } = props;\n if (title) {\n return (\n <Node {...TitleContainer}>\n <h5>\n {title.titleCount}\n </h5>\n </Node>\n );\n }\n return null;\n};\n\nexport default SearchResultContainerView;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { createObservableDataAction, IAction, IActionInput, IAny, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\nimport { GenericInput, getGenericAction } from '@msdyn365-commerce-modules/retail-actions';\n\nimport { SearchState } from './search-state';\n\nexport function createSearchStateInput(result: SearchState): GenericInput<SearchState> {\n return new GenericInput<SearchState>('searchState', result, 'SearchState');\n}\n\nconst createsearchStateInputInternal = (inputData: ICreateActionContext<IGeneric<IAny>>): IActionInput => {\n return createSearchStateInput({ searchText: '' });\n};\n\nexport const getGenericActionDataAction = createObservableDataAction({\n action: <IAction<SearchState>>getGenericAction,\n input: createsearchStateInputInternal\n});\n\nexport default getGenericActionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { observable } from 'mobx';\n\n/**\n * State information related to what is needed to succesfully perform a autosuggest.\n */\nexport class SearchState {\n @observable public searchText?: string;\n\n @observable public defaultBasicSearchUrl?: string;\n\n @observable public searchQueryStringParameter?: string;\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Autosuggestions } from '@msdyn365-commerce/commerce-entities';\nimport {\n CacheType, createObservableDataAction, IAction, IActionContext, IActionInput,\n ICreateActionContext\n} from '@msdyn365-commerce/core';\nimport { SearchSuggestion, SearchSuggestionCriteria } from '@msdyn365-commerce/retail-proxy';\nimport {\n getSearchSuggestionsAsync\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\nimport { generateImageUrl } from '@msdyn365-commerce-modules/retail-actions';\n\nexport enum SuggestionType {\n Category = 'ScopedCategory',\n Keyword = 'Keyword',\n Product = 'Product',\n None = 'None'\n}\n\n/**\n * Input class for auto suggest search input.\n */\nexport class AutoSuggestInput implements IActionInput {\n public searchQuery?: string;\n\n public topResultsCount?: number;\n\n public suggestionType?: string;\n\n public hitPrefix?: string;\n\n public hitSuffix?: string;\n\n constructor(searchText?: string, top?: number, suggestionType?: string, hitPrefix?: string, hitSuffix?: string) {\n this.searchQuery = searchText;\n this.topResultsCount = top;\n this.suggestionType = suggestionType;\n this.hitPrefix = hitPrefix;\n this.hitSuffix = hitSuffix;\n }\n\n public getCacheKey = () => 'AutoSuggestSearchSuggestions';\n\n public getCacheObjectType = () => 'AutoSuggestSearchSuggestions';\n\n public dataCacheType = (): CacheType => 'none';\n}\n\nconst createInput = (inputData: ICreateActionContext) => {\n return new AutoSuggestInput();\n};\n\n/**\n * Calls the Retail API and returns a auto-suggest suggestions.\n * @param input\n * @param ctx\n */\nexport async function getSearchSuggestionsAction(input: AutoSuggestInput, ctx: IActionContext): Promise<Autosuggestions | null> {\n // If no input is provided fail out\n if (!input || !input.searchQuery) {\n throw new Error('[getSearchSuggestionsAction]No valid Input was provided, failing');\n }\n\n const autosuggest: Autosuggestions = {};\n\n const autoSuggestPromises = [_getAutoSuggest(input, autosuggest, ctx)];\n return Promise.all(autoSuggestPromises).then(() => {\n return autosuggest;\n });\n}\n\nasync function _getAutoSuggest(\n input: AutoSuggestInput,\n autosuggest: Autosuggestions,\n ctx: IActionContext\n): Promise<void> {\n const searchCriteria: SearchSuggestionCriteria = {\n ProductSearchCriteria: {\n SearchCondition: input.searchQuery && input.searchQuery.length > 0 ? input.searchQuery : '',\n Context: {\n ChannelId: +ctx.requestContext.apiSettings.channelId,\n CatalogId: +ctx.requestContext.apiSettings.catalogId\n }\n },\n HitPrefix: input.hitPrefix,\n HitSuffix: input.hitSuffix,\n SuggestionType: input.suggestionType\n };\n\n const searchSuggestions = await getSearchSuggestionsAsync(\n { callerContext: ctx, queryResultSettings: { Paging: { Top: input.topResultsCount } } },\n searchCriteria\n );\n\n if (searchSuggestions && searchSuggestions.length > 0) {\n // Generate image url\n searchSuggestions.map(\n (item: SearchSuggestion) => (item.ImageUrl = item.ImageUrl ? generateImageUrl(item.ImageUrl, ctx.requestContext.apiSettings) : '')\n );\n\n autosuggest.AllSearchResults = searchSuggestions;\n } else {\n ctx.telemetry.error(`[getSearchSuggestionsAction] unable to get availabilites for search with suggestion type ${searchCriteria.SuggestionType}`);\n }\n}\n\nexport const getSearchSuggestionsActionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search/get-auto-suggest-suggestions',\n action: <IAction<Autosuggestions>>getSearchSuggestionsAction,\n input: createInput\n});\n\nexport default getSearchSuggestionsActionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport MsDyn365, { getRichTextHtml } from '@msdyn365-commerce/core';\nimport { ProductRefiner, ProductRefinerValue, SearchSuggestion } from '@msdyn365-commerce/retail-proxy';\nimport { format, getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchData } from '../search.data';\nimport { ISearchProps } from '../search.props.autogenerated';\n\nexport interface ISearchCategorySuggestProps {\n searchCategorySuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: ISearchProps<ISearchData>;\n searchText: string;\n searchRefiners: ProductRefiner[] | undefined;\n suggestions: SearchSuggestion[] | undefined;\n telemetryContent?: ITelemetryContent;\n shouldShowFullPath?: boolean;\n}\n\nexport interface ISearchCategoryViewProps {\n title: React.ReactNode;\n text: React.ReactNode[];\n}\n\nlet payLoad: IPayLoad;\n\n/**\n * CategorySuggestionsComponent.\n * @param props\n */\nexport const CategorySuggestionsComponent = (props: ISearchCategorySuggestProps): ISearchCategoryViewProps | undefined => {\n const {\n suggestions,\n searchText,\n autoSuggestProps: {\n resources: { categorySuggestionHeading }\n }\n } = props;\n\n const reactNodes: React.ReactNode[] = [];\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, props));\n });\n\n const titleNode = _renderTitle(categorySuggestionHeading, searchText);\n\n return { title: titleNode, text: reactNodes };\n};\n\nconst _renderTitle = (categorySuggestionHeading: string, searchText: string) => {\n const categoryAutoSuggestionHeading = categorySuggestionHeading ? format(categorySuggestionHeading, searchText) : `Search \"${searchText}\" in categories`;\n\n return (<li className='msc-autoSuggest__categoryResults-title'>\n {categoryAutoSuggestionHeading}\n </li>);\n};\n\nconst _assembleNode = (item: SearchSuggestion, props: ISearchCategorySuggestProps) => {\n const { searchText, hitPrefix, hitSuffix, shouldShowFullPath } = props;\n\n const splitValue = shouldShowFullPath ? item.Value : item.Value && item.Value.split('|').pop();\n const ariaLabel = splitValue ? splitValue.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '') : item.Value && item.Value.replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n payLoad.contentAction.etext = item.Value;\n const attribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n return (\n <li className='msc-autoSuggest__categoryResults-item' key={item.Id}>\n <a aria-label={ariaLabel} href={_generateLink(item, searchText, props)} {...attribute}>\n {_generateLink(item, searchText, props) && _getHighlightedText(splitValue ? splitValue : '', hitPrefix, hitSuffix)}\n </a>\n </li>\n );\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, searchText: string, props: ISearchCategorySuggestProps): string => {\n return suggestion && suggestion.Id ? _getCategoryLink(suggestion.Id, searchText, props) : '';\n};\n\nconst _getCategoryLink = (id: string, searchText: string, props: ISearchCategorySuggestProps): string => {\n const { searchPageURL, searchQsp, searchRefiners } = props;\n\n if (!MsDyn365.isBrowser) {\n return '';\n }\n\n const queryUrl = new URL(searchPageURL, window.location.href);\n\n if (searchQsp && searchText) {\n queryUrl.searchParams.set(searchQsp, searchText);\n }\n\n const categoryRefiners = searchRefiners?.find(refiners => {\n return refiners.KeyName === 'Category';\n });\n const refiner = categoryRefiners?.Values?.find(item => {\n return item.RefinerRecordId === Number.parseInt(id, 10);\n });\n\n const encodedRefiner = refiner && JSON.stringify(compressRefiners([refiner]));\n if (encodedRefiner) {\n queryUrl.searchParams.set('refiners', encodedRefiner);\n }\n\n return queryUrl.href;\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '<strong>')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '</strong>');\n\n return <span dangerouslySetInnerHTML={getRichTextHtml(formattedText)} />;\n};\n\n// TODO: This code is currently duplicated in categoryautosuggest need to either remove one of these files\n// or move this code to a common place\nconst compressedRefinerKeys = ['DataTypeValue', 'LeftValueBoundString', 'RefinerRecordId', 'RefinerSourceValue', 'RightValueBoundString', 'UnitText'];\n\n/**\n * Compressed a list of refiners for use in URLs.\n * @param refiners The uncompressed refiners.\n */\nconst compressRefiners = (refiners: ProductRefinerValue[]) => {\n const compressedRefiners: (string | number)[][] = [];\n\n refiners.forEach((refiner) => {\n const compressedRefiner: (string | number)[] = [];\n compressedRefinerKeys.forEach((refinerKey) => {\n compressedRefiner.push(refiner[refinerKey]);\n });\n compressedRefiners.push(compressedRefiner);\n });\n\n return compressedRefiners;\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Button } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nexport interface ISearchFormProps {\n hideSearchLabel: boolean | undefined;\n isSearchFormExpanded?: boolean | undefined;\n disableSubmitSearch: boolean | undefined;\n searchTextInput: React.RefObject<HTMLInputElement>;\n maxChars: number;\n searchQsp: string;\n searchPlaceholder: string;\n query: string;\n ariaLabelCancel: string;\n ariaLabelSearch: string;\n ariaLabelSubmit: string;\n handleCancelSearchChange(): void;\n handleInputChange(query: string): void;\n}\n\nexport interface ISearchFormViewProps {\n input: React.ReactNode;\n submitBtn: React.ReactNode;\n cancelBtn: React.ReactNode;\n\n}\n\n/**\n * On Input Change functionality.\n * @param handleInputChange -Input change function.\n * @returns Set updated input value.\n */\nconst onInputChangeFunction = (handleInputChange: (query: string) => void) => (event: React.ChangeEvent<HTMLInputElement>) => {\n handleInputChange(event.target.value || '');\n};\nexport const FormComponent = (props: ISearchFormProps): ISearchFormViewProps => {\n const {\n searchQsp,\n searchPlaceholder,\n hideSearchLabel,\n searchTextInput,\n handleInputChange,\n maxChars,\n disableSubmitSearch,\n handleCancelSearchChange,\n query,\n ariaLabelCancel,\n ariaLabelSearch,\n ariaLabelSubmit\n } = props;\n\n const onInputChange = onInputChangeFunction(handleInputChange);\n\n const inputNode = !hideSearchLabel ? (\n <input\n className='ms-search__form-control'\n type='text'\n aria-label={ariaLabelSearch}\n name={searchQsp}\n placeholder={searchPlaceholder}\n ref={searchTextInput}\n onChange={onInputChange}\n maxLength={maxChars}\n value={query}\n />\n ) : (\n <input\n className='ms-search__form-control'\n type='text'\n aria-label={ariaLabelSearch}\n name={searchQsp}\n placeholder={searchPlaceholder}\n ref={searchTextInput}\n onChange={onInputChange}\n value={query}\n />\n );\n\n const submitBtnNode = !disableSubmitSearch && (\n <Button className='ms-search__form-submitSearch' aria-label={ariaLabelSubmit} />\n );\n\n const cancelBtNoden = (\n <Button\n className={!disableSubmitSearch ? 'ms-search__form-cancelSearch' : 'ms-search__form-cancelSearchNoSumbit'}\n aria-label={ariaLabelCancel}\n onClick={handleCancelSearchChange}\n type='button'\n />\n );\n\n return { input: inputNode, cancelBtn: cancelBtNoden, submitBtn: submitBtnNode };\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport MsDyn365, { getRichTextHtml } from '@msdyn365-commerce/core';\nimport { SearchSuggestion } from '@msdyn365-commerce/retail-proxy';\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchData } from '../search.data';\nimport { ISearchProps } from '../search.props.autogenerated';\n\nexport interface ISearchKeywordSuggestProps {\n searchKeywordSuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: ISearchProps<ISearchData>;\n searchText: string;\n suggestions: SearchSuggestion[] | undefined;\n telemetryContent?: ITelemetryContent;\n}\n\nexport interface ISearchKeywordViewProps {\n text: React.ReactNode[];\n}\n\nlet payLoad: IPayLoad;\n\n/**\n * KeywordSuggestionsComponent.\n * @param props\n */\nexport const KeywordSuggestionsComponent = (props: ISearchKeywordSuggestProps): ISearchKeywordViewProps | undefined => {\n const {\n suggestions,\n hitPrefix,\n hitSuffix\n } = props;\n\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n const reactNodes: React.ReactNode[] = [];\n\n suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, hitPrefix, hitSuffix, props));\n });\n\n return { text: reactNodes };\n};\n\nconst _assembleNode = (item: SearchSuggestion, hitPrefix: string, hitSuffix: string, props: ISearchKeywordSuggestProps) => {\n const ariaLabel = item.Value &&\n (item.Value).replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n payLoad.contentAction.etext = ariaLabel;\n const attribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n return (\n <li className='msc-autoSuggest__keywordResults-item' key={item.Id}>\n <a\n aria-label={ariaLabel}\n href={_generateLink(item, hitPrefix, hitSuffix, props)}\n {...attribute}\n >\n {_generateLink(item, hitPrefix, hitSuffix, props) &&\n _getHighlightedText(item.Value ? item.Value : '', hitPrefix, hitSuffix)}\n </a>\n </li>\n );\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, hitPrefix: string, hitSuffix: string, props: ISearchKeywordSuggestProps): string => {\n const { searchPageURL, searchQsp } = props;\n\n const formattedLink = (suggestion.Value as string)\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n if (!MsDyn365.isBrowser) {\n return '';\n }\n\n const queryUrl = new URL(searchPageURL, window.location.href);\n if (searchQsp && formattedLink) {\n queryUrl.searchParams.set(searchQsp, formattedLink);\n }\n\n return queryUrl.href;\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '<strong>')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '</strong>');\n\n return <span dangerouslySetInnerHTML={getRichTextHtml(formattedText)} />;\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Button, getPayloadObject, getTelemetryAttributes, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nexport interface ISearchLabelProps {\n isSearchFormExpanded: boolean;\n searchLabelClass: string;\n searchLabelArialLabel: string;\n searchtext: string;\n searchCollapsedLabel: React.RefObject<HTMLButtonElement>;\n hideSearchLabel?: boolean;\n telemetryContent: ITelemetryContent;\n handleCancelSearchChange(): void;\n}\n\nexport const LabelComponent = (props: ISearchLabelProps) => {\n const { searchLabelClass, searchLabelArialLabel, isSearchFormExpanded, searchtext, searchCollapsedLabel, hideSearchLabel, handleCancelSearchChange, telemetryContent } = props;\n const payLoad = getPayloadObject('click', telemetryContent, searchtext, '');\n const attributes = getTelemetryAttributes(telemetryContent, payLoad);\n\n return (\n <div className={searchLabelClass}>\n <Button\n className='ms-search__icon'\n aria-expanded={isSearchFormExpanded}\n aria-label={searchLabelArialLabel}\n onClick={handleCancelSearchChange}\n innerRef={searchCollapsedLabel}\n {...attributes}\n >\n {!hideSearchLabel && <span className='ms-search__icon-text' aria-hidden>\n {searchtext}\n </span>}\n </Button>\n </div>\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { PriceComponent } from '@msdyn365-commerce/components';\nimport { getRichTextHtml, IActionContext, IImageSettings, Image, ITelemetry } from '@msdyn365-commerce/core';\nimport { SearchSuggestion } from '@msdyn365-commerce/retail-proxy';\nimport { getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\nimport { getPayloadObject, getTelemetryAttributes, INodeProps, IPayLoad, ITelemetryContent, NodeTag } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchData } from '../search.data';\nimport { ISearchProps } from '../search.props.autogenerated';\n\nexport interface ISearchProductSuggestProps {\n searchProductSuggestClass: string;\n searchPageURL: string;\n searchQsp: string | undefined;\n hitPrefix: string;\n hitSuffix: string;\n autoSuggestProps: ISearchProps<ISearchData>;\n searchText: string;\n suggestions: SearchSuggestion[] | undefined;\n telemetry: ITelemetry;\n moduleType: string;\n moduleId: string;\n telemetryContent?: ITelemetryContent;\n}\n\nexport interface ISearchProductViewProps {\n title: React.ReactNode;\n items: ISearchProductItemViewProps[];\n}\n\nexport interface ISearchProductItemViewProps {\n text: React.ReactNode;\n thumbnail: React.ReactNode;\n price: React.ReactNode;\n LiProduct: INodeProps;\n AProduct: INodeProps;\n id: string | undefined;\n}\n\nlet payLoad: IPayLoad;\nlet telemetryContent: ITelemetryContent | undefined;\n\n/**\n * ProductSuggestionsComponent.\n * @param props\n */\nexport const ProductSuggestionsComponent = (props: ISearchProductSuggestProps): ISearchProductViewProps | undefined => {\n const {\n suggestions,\n hitSuffix,\n hitPrefix,\n autoSuggestProps: {\n context: { actionContext },\n resources: { productSuggestionHeading }\n },\n moduleType,\n moduleId\n } = props;\n const reactNodes: ISearchProductItemViewProps[] = [];\n telemetryContent = props.telemetryContent;\n payLoad = getPayloadObject('click', props.telemetryContent!, '');\n\n suggestions?.map(item => {\n reactNodes.push(_assembleNode(item, hitPrefix, hitSuffix, actionContext, props, moduleType, moduleId));\n });\n\n const titleNode = _renderTitle(productSuggestionHeading);\n\n return { title: titleNode, items: reactNodes };\n};\n\nconst _renderTitle = (productSuggestionHeading: string) => {\n const productAutoSuggestionHeading = productSuggestionHeading ? productSuggestionHeading : 'Go to products';\n\n return (<li className='msc-autoSuggest__productResults-title'>\n {productAutoSuggestionHeading}\n </li>);\n};\n\nconst _assembleNode = (\n item: SearchSuggestion,\n hitPrefix: string,\n hitSuffix: string,\n actionContext: IActionContext,\n props: ISearchProductSuggestProps,\n moduleType: string,\n moduleId: string\n): ISearchProductItemViewProps => {\n const altText =\n item.Value &&\n (item.Value).replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n return {\n text: _getHighlightedText(item.Value ? item.Value : '', hitPrefix, hitSuffix),\n thumbnail: _renderThumbnail(item, altText ? altText : '', props),\n price:\n item.Id &&\n item.Value3 &&\n item.Value3.Value &&\n item.Value3.Value.DecimalValue &&\n _renderPrice(item.Value3.Value.DecimalValue, item.Value3.Value.DecimalValue, moduleId, moduleType, props),\n LiProduct: _getLiWrapper(),\n AProduct: _getAWrapper(item, hitPrefix, hitSuffix, actionContext, props),\n id: item.Id\n };\n};\n\nconst _getLiWrapper = () => {\n return {\n className: 'msc-autoSuggest__productResults-item',\n tag: 'li' as NodeTag\n };\n};\n\nconst _getAWrapper = (item: SearchSuggestion, hitPrefix: string, hitSuffix: string, actionContext: IActionContext, props: ISearchProductSuggestProps) => {\n const {\n autoSuggestProps: { context }\n } = props;\n const ariaLabel = item.Value &&\n (item.Value).replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n\n payLoad.contentAction.recid = item.Id;\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\n const productPrice = context.cultureFormatter.formatCurrency(item.Value3!.Value!.DecimalValue!);\n\n return {\n className: 'msc-autoSuggest__productResults-item',\n tag: 'a' as NodeTag,\n 'aria-label': `${ariaLabel!} ${productPrice}`,\n href: _generateLink(item, hitPrefix, hitSuffix, actionContext),\n ...attribute\n };\n};\n\nconst _generateLink = (suggestion: SearchSuggestion, hitPrefix: string, hitSuffix: string, actionContext: IActionContext) => {\n const formattedLink = (suggestion.Value as string).replace(new RegExp(`[${hitPrefix}]`, 'gi'), '').replace(new RegExp(`[${hitSuffix}]`, 'gi'), '');\n return suggestion.Value && suggestion.Id ? getProductPageUrlSync(formattedLink, suggestion.Id as unknown as number, actionContext, undefined) : '';\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n const formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '<strong>')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '</strong>');\n\n return <span className='msc-price msc-autoSuggest__productResults-item-text' dangerouslySetInnerHTML={getRichTextHtml(formattedText)} />;\n};\n\nconst _renderPrice = (adjustedPrice: number, basePrice: number, moduleId: string, moduleType: string, props: ISearchProductSuggestProps): JSX.Element | null => {\n const {\n autoSuggestProps: { context }\n } = props;\n\n return (\n <PriceComponent\n id={moduleId}\n typeName={moduleType}\n context={context}\n data={{\n price: {\n CustomerContextualPrice: adjustedPrice,\n BasePrice: basePrice\n }\n }}\n className='msc-autoSuggest__productResults-item-price'\n />\n );\n};\n\nconst _renderThumbnail = (suggestion: SearchSuggestion, altText: string, props: ISearchProductSuggestProps): JSX.Element | null => {\n const {\n autoSuggestProps: {\n context: {\n request: { gridSettings }\n },\n config: { imageSettings }\n }\n } = props;\n if (imageSettings) {\n imageSettings.cropFocalRegion = true;\n }\n\n if (!suggestion || !suggestion.ImageUrl) {\n props.telemetry.error('Search suggestion content is empty, module wont render.');\n return null;\n }\n\n const defaultImageSettings: IImageSettings = {\n viewports: {\n xs: { q: 'w=40&h=40&m=6', w: 0, h: 0 },\n lg: { q: 'w=40&h=40&m=6', w: 0, h: 0 },\n xl: { q: 'w=40&h=40&m=6', w: 0, h: 0 }\n },\n lazyload: true,\n cropFocalRegion: true\n };\n\n return (\n <Image\n requestContext={props.autoSuggestProps.context.actionContext.requestContext}\n altText={altText}\n className='msc-autoSuggest__productResults-item-img'\n src={suggestion.ImageUrl}\n gridSettings={gridSettings!}\n imageSettings={imageSettings ? imageSettings : defaultImageSettings}\n loadFailureBehavior='hide'\n />\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Autosuggestions } from '@msdyn365-commerce/commerce-entities';\nimport MsDyn365, { getUrlSync } from '@msdyn365-commerce/core';\nimport { ProductRefiner } from '@msdyn365-commerce/retail-proxy';\nimport { getProductSearchRefinersAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\nimport { ArrayExtensions } from '@msdyn365-commerce-modules/retail-actions';\nimport { createSearchStateInput } from '@msdyn365-commerce-modules/search-utilities';\nimport { getTelemetryObject, IModuleProps, INodeProps, ITelemetryContent, KeyCodes } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport { debounce } from 'lodash';\nimport { Spinner, SpinnerSize } from 'office-ui-fabric-react';\nimport * as React from 'react';\n\nimport getSearchSuggestionsAction, { AutoSuggestInput, SuggestionType } from './actions/get-auto-suggest-suggestions';\nimport {\n CategorySuggestionsComponent,\n FormComponent,\n ISearchCategoryViewProps,\n ISearchKeywordViewProps,\n ISearchProductViewProps,\n KeywordSuggestionsComponent,\n LabelComponent,\n ProductSuggestionsComponent\n} from './components';\nimport { ISearchData } from './search.data';\nimport { ISearchProps, ISuggestionTypeCriterionData } from './search.props.autogenerated';\n\nexport interface ISearchState {\n isSearchFormExpanded: boolean;\n searchText: string;\n searchKeywordSuggestClass: string;\n searchProductSuggestClass: string;\n searchCategorySuggestClass: string;\n suggestions: Autosuggestions | undefined;\n searchRefiners?: ProductRefiner[] | undefined;\n autoSuggestAriaLabel: string;\n isInitialState: boolean;\n isLoadingAutoSuggest?: boolean;\n}\n\nexport interface ISearchViewProps extends ISearchProps<ISearchData> {\n Search: IModuleProps;\n AutoSuggestAriaLabel: INodeProps;\n AutoSuggestAriaLabelText: string;\n searchText: string;\n AutoSuggest: INodeProps;\n KeywordSuggest: INodeProps;\n ProductSuggest: INodeProps;\n CategorySuggest: INodeProps;\n SearchForm: INodeProps;\n FormWrapper: INodeProps;\n UlKeyword: INodeProps;\n UlProduct: INodeProps;\n UlCategory: INodeProps;\n label: React.ReactNode;\n form: React.ReactNode;\n autosuggestKeyword?: ISearchKeywordViewProps;\n autosuggestProduct?: ISearchProductViewProps;\n autosuggestCategory?: ISearchCategoryViewProps;\n callbacks: {\n handleCancelSearchChange(): void;\n };\n isSearchFormExpanded: boolean;\n isLoadingAutoSuggest?: boolean;\n isLoadingNode?: React.ReactNode;\n}\n\n/**\n *\n * Search module.\n * @extends {React.Component<ISearchProps<ISearchData>, ISearchState>}\n */\nclass Search extends React.Component<ISearchProps<ISearchData>, ISearchState> {\n private readonly searchTextInput: React.RefObject<HTMLInputElement>;\n\n private readonly searchCollapsedLabel: React.RefObject<HTMLButtonElement>;\n\n private readonly formReference: React.RefObject<HTMLButtonElement>;\n\n private readonly maxChars: number;\n\n private readonly inputSuggestionType?: ISuggestionTypeCriterionData[];\n\n private readonly topResultsCount?: number;\n\n private readonly hitPrefix: string = '{';\n\n private readonly hitSuffix: string = '}';\n\n private readonly waitTime: number = 500;\n\n private readonly autoSuggestResultScreenReaderDiv: React.RefObject<HTMLDivElement>;\n\n private readonly autoSuggestResultDiv: React.RefObject<HTMLDivElement>;\n\n private readonly searchFormClass: string;\n\n private readonly searchLabelClass: string;\n\n private readonly telemetryContent: ITelemetryContent;\n\n // @ts-expect-error\n private cancellabelDebounce: debounce;\n\n constructor(props: ISearchProps<ISearchData>) {\n super(props);\n this.searchTextInput = React.createRef();\n this.searchCollapsedLabel = React.createRef();\n this.autoSuggestResultScreenReaderDiv = React.createRef();\n this.autoSuggestResultDiv = React.createRef();\n this.formReference = React.createRef();\n this.state = {\n isSearchFormExpanded: false,\n searchText: '',\n searchKeywordSuggestClass: 'ms-search__autoSuggest__keyword',\n searchProductSuggestClass: 'ms-search__autoSuggest__product',\n searchCategorySuggestClass: 'ms-search__autoSuggest__category',\n suggestions: undefined,\n searchRefiners: undefined,\n autoSuggestAriaLabel: '',\n isInitialState: true,\n isLoadingAutoSuggest: false\n };\n this.maxChars =\n (this.props.context &&\n this.props.context.app &&\n this.props.context.app.config &&\n this.props.context.app.config.searchInputMaxLength) ||\n 50;\n this.inputSuggestionType = this.props.config && this.props.config.suggestionTypeCriterion;\n this.topResultsCount = this.props.config && this.props.config.topResultsCount ? this.props.config.topResultsCount : 5;\n this.searchFormClass = 'ms-search__form';\n this.searchLabelClass = 'ms-search__label';\n this.telemetryContent = getTelemetryObject(this.props.context.request.telemetryPageName!, this.props.friendlyName, this.props.telemetry);\n }\n\n public async componentDidMount(): Promise<void> {\n document.body && document.body.addEventListener('mousedown', this._focusOutTarget);\n window && window.addEventListener('keyup', this._keyup);\n }\n\n public componentWillUnmount(): void {\n document.body && document.body.removeEventListener('mousedown', this._focusOutTarget, false);\n window && window.removeEventListener('keyup', this._keyup, false);\n }\n\n public componentDidUpdate(): void {\n const {\n config: { hideSearchLabel }\n } = this.props;\n const { isSearchFormExpanded, isInitialState } = this.state;\n\n if (!this.props.context.request.params.isEditor) {\n if (!hideSearchLabel && isSearchFormExpanded) {\n this.searchTextInput && this.searchTextInput.current && this.searchTextInput.current.focus();\n } else if (!isInitialState) {\n this.searchCollapsedLabel && this.searchCollapsedLabel.current && this.searchCollapsedLabel.current.focus();\n }\n }\n }\n\n public shouldComponentUpdate(nextProps: ISearchProps<ISearchData>,\n nextState: ISearchState): boolean {\n if (this.state === nextState && this.props === nextProps) {\n return false;\n }\n return true;\n }\n\n // eslint-disable-next-line complexity -- ignore complexity.\n public render(): JSX.Element {\n const {\n context,\n resources: { searchtext, searchLabelArialLabel, cancelBtnAriaLabel, searchBtnAriaLabel, submitBtnAriaLabel },\n config: { hideSearchLabel, disableSubmitSearch, searchplaceholderText, shouldShowFullCategoryPath, className = '' }\n } = this.props;\n\n const {\n isSearchFormExpanded,\n searchText,\n searchKeywordSuggestClass,\n searchProductSuggestClass,\n searchCategorySuggestClass,\n suggestions,\n searchRefiners,\n isLoadingAutoSuggest\n } = this.state;\n\n const searchQsp = (context && context.app && context.app.config && context.app.config.searchQueryStringParameter) || 'q';\n const searchPageURL = getUrlSync('search', context && context.actionContext) || '';\n const searchURL = this._appendQueryParams(searchPageURL, searchText, searchQsp);\n const searchPlaceholder = searchplaceholderText && searchplaceholderText.length > 0 ? searchplaceholderText : 'Search in Fabrikam';\n\n const keywordSuggestions =\n suggestions &&\n suggestions.AllSearchResults &&\n suggestions.AllSearchResults.filter(\n i => i.SuggestionType === SuggestionType.Keyword || i.SuggestionType === SuggestionType.None\n );\n const productSuggestions =\n suggestions &&\n suggestions.AllSearchResults &&\n suggestions.AllSearchResults.filter(i => i.SuggestionType === SuggestionType.Product);\n const categorySuggestions =\n suggestions &&\n suggestions.AllSearchResults &&\n suggestions.AllSearchResults.filter(i => i.SuggestionType === SuggestionType.Category);\n\n const viewProps: ISearchViewProps = {\n ...(this.props as ISearchProps<ISearchData>),\n\n Search: {\n moduleProps: this.props,\n className: `${classnames('ms-search', className)} ${disableSubmitSearch ? 'no-submit' : 'with-submit'}`\n },\n AutoSuggestAriaLabel: {\n tag: 'div',\n className: 'msc-autoSuggest__screen-reader',\n 'aria-live': 'assertive',\n ref: this.autoSuggestResultScreenReaderDiv\n },\n AutoSuggestAriaLabelText: this.state.autoSuggestAriaLabel,\n searchText: this.state.searchText,\n AutoSuggest: {\n ref: this.autoSuggestResultDiv,\n className: 'ms-search__autoSuggest'\n },\n KeywordSuggest: {\n className: searchKeywordSuggestClass\n },\n ProductSuggest: {\n className: searchProductSuggestClass\n },\n CategorySuggest: {\n className: searchCategorySuggestClass\n },\n SearchForm: {\n className: `${this.searchFormClass} ${isSearchFormExpanded ? 'bx-show' : 'bx-hide'}`\n },\n FormWrapper: {\n tag: 'form',\n ref: this.formReference,\n className: 'ms-search__searchForm',\n 'aria-label': 'Search',\n name: 'searchForm',\n role: 'search',\n action: searchURL,\n autoComplete: 'off',\n onSubmit: this._handleSubmit\n },\n UlKeyword: {\n tag: 'ul',\n className: classnames('msc-autoSuggest__keywordResults-items', className)\n },\n UlProduct: {\n tag: 'ul',\n className: classnames('msc-autoSuggest__productResults-items', className)\n },\n UlCategory: {\n tag: 'ul',\n className: classnames('msc-autoSuggest__categoryResults-items', className)\n },\n label: LabelComponent({\n isSearchFormExpanded,\n searchLabelClass: `${this.searchLabelClass} ${isSearchFormExpanded ? 'bx-hide' : 'bx-show'}`,\n searchtext,\n searchLabelArialLabel,\n searchCollapsedLabel: this.searchCollapsedLabel,\n hideSearchLabel,\n handleCancelSearchChange: this._handleCancelSearchChange,\n telemetryContent: this.telemetryContent\n }),\n form: FormComponent({\n ariaLabelCancel: cancelBtnAriaLabel,\n ariaLabelSearch: searchBtnAriaLabel,\n ariaLabelSubmit: submitBtnAriaLabel,\n hideSearchLabel,\n searchTextInput: this.searchTextInput,\n disableSubmitSearch,\n handleInputChange: this._handleInputChange,\n handleCancelSearchChange: this._handleCancelSearchChange,\n maxChars: this.maxChars,\n searchQsp,\n searchPlaceholder,\n query: searchText\n }),\n autosuggestKeyword:\n searchText && searchText.length > 0 &&\n (isLoadingAutoSuggest || (keywordSuggestions && ArrayExtensions.hasElements(keywordSuggestions))) ? KeywordSuggestionsComponent({\n searchKeywordSuggestClass,\n searchPageURL,\n searchQsp,\n hitPrefix: this.hitPrefix,\n hitSuffix: this.hitSuffix,\n autoSuggestProps: this.props,\n searchText,\n suggestions: keywordSuggestions,\n telemetryContent: this.telemetryContent\n }) : undefined,\n autosuggestProduct:\n searchText && searchText.length > 0 &&\n (isLoadingAutoSuggest || (productSuggestions && ArrayExtensions.hasElements(productSuggestions))) ? ProductSuggestionsComponent({\n searchProductSuggestClass,\n searchPageURL,\n searchQsp,\n hitPrefix: this.hitPrefix,\n hitSuffix: this.hitSuffix,\n autoSuggestProps: this.props,\n searchText,\n suggestions: productSuggestions,\n telemetry: this.props.telemetry,\n moduleType: this.props.typeName,\n moduleId: this.props.id,\n telemetryContent: this.telemetryContent\n }) : undefined,\n autosuggestCategory:\n searchText && searchText.length > 0 &&\n (isLoadingAutoSuggest || (categorySuggestions && ArrayExtensions.hasElements(categorySuggestions))) ? CategorySuggestionsComponent({\n searchCategorySuggestClass,\n searchPageURL,\n searchQsp,\n hitPrefix: this.hitPrefix,\n hitSuffix: this.hitSuffix,\n autoSuggestProps: this.props,\n searchText,\n suggestions: categorySuggestions,\n searchRefiners,\n telemetryContent: this.telemetryContent,\n shouldShowFullPath: shouldShowFullCategoryPath\n }) : undefined,\n callbacks: {\n handleCancelSearchChange: this._handleCancelSearchChange\n },\n isSearchFormExpanded: this.state.isSearchFormExpanded,\n isLoadingAutoSuggest,\n isLoadingNode: this._isLoadingNode()\n };\n\n return this.props.renderView(viewProps) as React.ReactElement;\n }\n\n /**\n * Function to create the ReactNode for loading Autosuggest result.\n * @returns ReachNode for loading Autosuggest result.\n */\n private readonly _isLoadingNode = (): React.ReactNode => {\n const loadingText = this.props.resources.autoSuggestResultLoadingMessage;\n return (<Spinner\n className='msc-autoSuggest__loadingResult'\n label={loadingText}\n size={SpinnerSize.medium}\n labelPosition='right'\n />);\n };\n\n private readonly _focusOutTarget = (e: any): void => {\n const { suggestions } = this.state;\n\n if (\n suggestions &&\n suggestions.AllSearchResults &&\n e.target.closest('.ms-search') === null\n ) {\n this._clearAutoSuggestState();\n }\n };\n\n private readonly _keyup = (e: KeyboardEvent): void => {\n const { suggestions } = this.state;\n\n if (suggestions && suggestions.AllSearchResults && e.keyCode === KeyCodes.Escape) {\n this._clearAutoSuggestState();\n } else if (this.state.isSearchFormExpanded && e.keyCode === KeyCodes.Escape) {\n if (this.state.isSearchFormExpanded) {\n this.setState({ isSearchFormExpanded: false });\n }\n }\n\n if (!((this.formReference.current && this.formReference.current.contains(e.target as unknown as Node)) ||\n (this.autoSuggestResultDiv.current && this.autoSuggestResultDiv.current.contains(e.target as unknown as Node)))) {\n if (suggestions && suggestions.AllSearchResults) {\n this._clearAutoSuggestState();\n }\n\n if (this.state.isSearchFormExpanded) {\n this.setState({ isSearchFormExpanded: false });\n }\n }\n };\n\n private readonly _clearAutoSuggestState = (): void => {\n const {\n context: { actionContext },\n data: { searchState }\n } = this.props;\n\n if (this.searchTextInput.current && this.searchTextInput.current.value.length > 0) {\n searchState.searchText = '';\n searchState.defaultBasicSearchUrl = '';\n searchState.searchQueryStringParameter = '';\n actionContext ? actionContext.update(createSearchStateInput(searchState), searchState) : null;\n this.searchTextInput.current.value = '';\n }\n\n this.setState({ searchText: '', suggestions: undefined, searchRefiners: undefined });\n };\n\n private readonly _handleInputChange = (query: string): void => {\n if (!query || query.length <= this.maxChars) {\n this.setState({ searchText: query });\n }\n\n if (this.cancellabelDebounce) {\n this.cancellabelDebounce.cancel();\n }\n\n const {\n telemetry,\n context,\n data: { searchState }\n } = this.props;\n\n if (context) {\n if (query && query.length > 0) {\n if (query.length > this.maxChars) {\n return;\n }\n\n this.cancellabelDebounce = debounce(() => {\n this.setState({ isLoadingAutoSuggest: true });\n getSearchSuggestionsAction(\n new AutoSuggestInput(\n query,\n this.topResultsCount,\n this._getSuggestionType(this.inputSuggestionType),\n this.hitPrefix,\n this.hitSuffix\n ),\n context.actionContext\n )\n .then(results => {\n this._getSearchRefiners(query)\n .then(refiners => {\n this.setState({ suggestions: results, searchRefiners: refiners,\n autoSuggestAriaLabel: this._setAutoSuggestResultCount(results), isLoadingAutoSuggest: false });\n })\n .catch(error => {\n this.setState({ suggestions: results, searchRefiners: undefined,\n autoSuggestAriaLabel: this._setAutoSuggestResultCount(results) });\n telemetry.exception(error);\n telemetry.debug('Unable to get refiners results');\n });\n })\n .catch(error => {\n this.setState({ suggestions: undefined, searchRefiners: undefined,\n autoSuggestAriaLabel: this._setAutoSuggestResultCount() });\n telemetry.exception(error);\n telemetry.debug('Unable to get auto suggest results');\n });\n }, this.waitTime);\n\n setTimeout(() => {\n this.cancellabelDebounce();\n }, 0);\n\n searchState.searchText = query;\n } else {\n this.setState({ suggestions: undefined, searchRefiners: undefined });\n searchState.searchText = '';\n }\n context.actionContext.update(createSearchStateInput(searchState), searchState);\n }\n };\n\n private readonly _getSuggestionType = (suggestionTypes?: ISuggestionTypeCriterionData[]): string => {\n if (suggestionTypes && suggestionTypes.length > 0) {\n const distinctSuggestionTypes: string[] = [];\n suggestionTypes && suggestionTypes.forEach((suggestionTypeItem, index) => {\n suggestionTypeItem.SuggestionType && distinctSuggestionTypes.push(suggestionTypeItem.SuggestionType.charAt(0).toUpperCase() + suggestionTypeItem.SuggestionType.slice(1));\n });\n return distinctSuggestionTypes.join(',');\n }\n return 'Keyword, Product, ScopedCategory';\n };\n\n private async _getSearchRefiners(searchText: string): Promise<ProductRefiner[]> {\n const { actionContext: ctx } = this.props.context;\n return getProductSearchRefinersAsync(\n { callerContext: ctx },\n {\n SearchCondition: searchText,\n Context: {\n ChannelId: +ctx.requestContext.apiSettings.channelId,\n CatalogId: +ctx.requestContext.apiSettings.catalogId\n }\n }\n );\n }\n\n private readonly _handleSubmit = (\n e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement> | React.FormEvent<HTMLFormElement>\n ): void => {\n const {\n config: { disableSubmitSearch },\n context: {\n actionContext,\n app: {\n config: { searchQueryStringParameter }\n }\n }\n } = this.props;\n\n const query = this.searchTextInput.current && this.searchTextInput.current.value;\n e.preventDefault();\n\n if (!query || (query && query.length === 0) || disableSubmitSearch) {\n this.searchTextInput && this.searchTextInput.current && this.searchTextInput.current.focus();\n } else {\n const searchQsp = searchQueryStringParameter || 'q';\n const searchURL = this._appendQueryParams(getUrlSync('search', actionContext) || '', query, searchQsp);\n document.location.href = searchURL;\n }\n };\n\n private readonly _handleCancelSearchChange = (): void => {\n const { isSearchFormExpanded, suggestions } = this.state;\n\n if (!isSearchFormExpanded) {\n this.setState({\n isSearchFormExpanded: true,\n searchText: '',\n isInitialState: false\n });\n } else {\n if (suggestions && suggestions.AllSearchResults) {\n this._clearAutoSuggestState();\n }\n\n this.setState({ isSearchFormExpanded: false });\n }\n };\n\n private readonly _appendQueryParams = (route: string, query: string, qsp: string): string => {\n if (!MsDyn365.isBrowser) {\n return '';\n }\n\n const queryUrl = new URL(route, window.location.href);\n if (qsp && query) {\n queryUrl.searchParams.set(qsp, query);\n }\n\n return queryUrl.href;\n };\n\n private readonly _setAutoSuggestResultCount = (result?: Autosuggestions) => {\n if (this.autoSuggestResultScreenReaderDiv.current !== null) {\n const ariaLiveRegion = this.autoSuggestResultScreenReaderDiv.current;\n const suggestResultString = this.props.resources.autoSuggestFoundMessage;\n const emptyResultString = this.props.resources.noAutoSuggestionMessage;\n ariaLiveRegion.innerText = result && (result.AllSearchResults && result.AllSearchResults.length > 0) ? suggestResultString : emptyResultString;\n ariaLiveRegion.setAttribute('aria-live', 'assertive');\n return ariaLiveRegion.innerText;\n }\n return '';\n\n };\n}\n\nexport default Search;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { INodeProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { ISearchCategoryViewProps, ISearchFormViewProps, ISearchKeywordViewProps, ISearchProductViewProps } from './components';\nimport { ISearchViewProps } from './search';\n\nconst SearchView: React.FC<ISearchViewProps> = props => {\n const {\n Search,\n AutoSuggestAriaLabel,\n AutoSuggestAriaLabelText,\n searchText,\n AutoSuggest,\n KeywordSuggest,\n ProductSuggest,\n CategorySuggest,\n UlKeyword,\n UlProduct,\n UlCategory,\n form,\n autosuggestCategory,\n autosuggestKeyword,\n autosuggestProduct,\n SearchForm,\n FormWrapper,\n label,\n isLoadingAutoSuggest,\n isLoadingNode\n } = props;\n\n return (\n <Module {...Search}>\n {label}\n {_renderForm(form as ISearchFormViewProps, SearchForm, FormWrapper)}\n <Node {...AutoSuggest}>\n {searchText && searchText.length > 0 ? <Node {...AutoSuggestAriaLabel}>\n {AutoSuggestAriaLabelText}\n </Node> : ''}\n {_renderKeywordSuggestions(KeywordSuggest, UlKeyword, autosuggestKeyword, isLoadingAutoSuggest, isLoadingNode)}\n {_renderProductSuggestions(ProductSuggest, UlProduct, autosuggestProduct, isLoadingAutoSuggest, isLoadingNode)}\n {_renderCategorySuggestions(CategorySuggest, UlCategory, autosuggestCategory, isLoadingAutoSuggest, isLoadingNode)}\n </Node>\n </Module>\n );\n};\n\nconst _renderForm = (form: ISearchFormViewProps, SearchForm: INodeProps, FormWrapper: INodeProps) => {\n return (\n <Node {...SearchForm}>\n <Node {...FormWrapper}>\n {form.input}\n {form.cancelBtn}\n {form.submitBtn}\n </Node>\n </Node>\n );\n};\n\nconst _renderKeywordSuggestions = (\n KeywordSuggest: INodeProps,\n UlKeyword: INodeProps,\n keywordSuggestions?: ISearchKeywordViewProps,\n isLoadingAutoSuggest?: boolean,\n isLoadingNode?: React.ReactNode\n) => {\n return (\n keywordSuggestions && (\n <Node {...KeywordSuggest}>\n <Node {...UlKeyword}>\n {isLoadingAutoSuggest && isLoadingNode}\n {!isLoadingAutoSuggest && keywordSuggestions.text.map(text => {\n return text;\n })}\n </Node>\n </Node>\n )\n );\n};\n\nconst _renderProductSuggestions = (\n ProductSuggest: INodeProps,\n UlProduct: INodeProps,\n productSuggestions?: ISearchProductViewProps,\n isLoadingAutoSuggest?: boolean,\n isLoadingNode?: React.ReactNode\n) => {\n return (\n productSuggestions && (\n <Node {...ProductSuggest}>\n <Node {...UlProduct}>\n {productSuggestions.title}\n {isLoadingAutoSuggest && isLoadingNode}\n {!isLoadingAutoSuggest && productSuggestions.items.map((item, index) => {\n return (\n <Node {...item.LiProduct} key={item.id || index}>\n <Node {...item.AProduct}>\n {item.thumbnail}\n {item.text}\n {item.price}\n </Node>\n </Node>\n );\n })}\n </Node>\n </Node>\n )\n );\n};\n\nconst _renderCategorySuggestions = (\n CategorySuggest: INodeProps,\n UlCategory: INodeProps,\n categorySuggestions?: ISearchCategoryViewProps,\n isLoadingAutoSuggest?: boolean,\n isLoadingNode?: React.ReactNode\n) => {\n return (\n categorySuggestions && (\n <Node {...CategorySuggest}>\n <Node {...UlCategory}>\n {categorySuggestions.title}\n {isLoadingAutoSuggest && isLoadingNode}\n {!isLoadingAutoSuggest && categorySuggestions.text.map(text => {\n return text;\n })}\n </Node>\n </Node>\n )\n );\n};\n\nexport default SearchView;\n"],"names":["BaseCollectionInput","pageType","apiSettings","queryResultSettings","refiners","category","searchText","includeAttributes","isUpdateRefinerPanel","locale","catalogId","getCacheKey","this","Paging","Sorting","buildCacheKey","map","refiner","RefinerRecordId","LeftValueBoundString","RightValueBoundString","convertToString","getCacheObjectType","dataCacheType","createBaseCollectionInput","args","inputClassConstuctor","requestContext","urlTokens","query","categoryId","QueryResultSettings","queryRefiners","inputData","config","undefined","updateRefinerPanel","getUpdateRefinerPanel","sorting","Columns","JSON","parse","decodeURIComponent","itemId","q","productId","recommendation","stringify","ProductId","Recommendation","Error","ProductListInventoryFilteringOptions","GetFullProductsByCollectionInput","length","isOutOfStock","product","channelInventoryConfiguration","ArrayExtensions","AttributeValues","attribute","RecordId","InventoryProductAttributeRecordId","TextValue","InventoryOutOfStockAttributeValueText","returnProductsBasedOnInventoryInformation","products","context","ObjectExtensions","app","productListInventoryDisplay","HideOOS","filteredProducts","push","filterOutOfStockProducts","SortOOS","inStockProducts","outOfStockProducts","concat","sortsProductsBasedOnAvailability","async","returnProducts","productSearchResults","metadataCount","productSearchResultsWithImages","productSearchResult","newImageUrl","generateProductImageUrl","PrimaryImageUrl","inventoryLevel","InventoryLevels","enableStockCheck","count","getInventoryConfigurationAsync","callerContext","element","inventoryRanges","channelInventoryConfigurationId","actionDataAction","id","action","input","promise","searchProductId","searchCriteriaInput","Context","ChannelId","channelId","CatalogId","Refinement","IncludeAttributes","SkipVariantExpansion","CategoryIds","searchByCriteriaAsync","SearchCondition","searchObject","Number","isNaN","RecommendationListId","Ids","update","ListPageStateInput","totalProductCount","metadata","activeFilters","Top","itemsPerPage","skip","Skip","sortOptions","sortByOptionRelevanceDesc","sortByOptionRatingAsc","sortByOptionRatingDesc","sortByOptionNameAsc","sortByOptionNameDesc","sortByOptionPriceAsc","sortByOptionPriceDesc","sortByOptionBestSelling","sortByOptionNewScore","sortByOptionTrendingScore","MappedSearchInput","getMappedSearchConfiguration","ctx","getSearchConfigurationAsync","then","searchConfiguration","ProductSortColumns","sortColumn","key","ColumnName","toUpperCase","IsDescending","telemetry","warning","filter","Boolean","createInput","getMappedSearchConfigurationDataAction","DefaultValues","getProductRefinerHierarchy","searchCriteria","getProductSearchRefinersAsync","productRefiners","trace","result","productRefiner","RefinersByCollectionInput","defaultCategoryIdValue","defaultProductIdValue","compressedRefinerKeys","hydrateRefinersFromUrl","compressedRefinerArray","parseQueryParam","compressedRefiner","parsedRefiner","forEach","refinerKey","index","buildListPageUrl","fullUrl","sortingColumns","skipCount","searchParams","delete","sortedRefiners","sort","first","second","set","compressedRefiners","compressRefiners","href","toString","getCurrentUrl","URL","window","location","url","requestUrl","ListPageState","activeProducts","sortingCritera","currentPageNumber","pageSize","featureProduct","productPrices","listPageStateAction","createListPageInput","ProductRefinerValueDataTypeValue","ProductRefinerTypeValue","ProductRefinerSource","isRangeType","dataTypeValue","AttributeDataType","findMatchingRefinementCriterion","productRefinerValue","refinementCriteria","find","refinementCriterion","isMatchingRefinementCriterion","RefinerSourceValue","DataTypeValue","getUpdatedRefinementCriteria","itemToggleNotification","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","selectedCriterion","isSelecting","next","rangeStart","rangeEnd","parentProductRefinerHierarchy","RefinerTypeValue","RefinerType","Values","child","matchingIndex","findIndex","criterion","splice","ChoiceSummary","props","super","closeButtonGlyph","_onClick","e","preventDefault","stopPropagation","target","currentTarget","clearAll","getAttribute","includes","selectedRefiner","_getSelectedRefinerChoice","onChoiceClicked","itemClicked","choiceClicked","nextItemToFocus","nextSibling","payLoad","telemetryContent","selectedChoices","_getKeyForRefinerValue","value","clearAllText","label","classNames","choiceAriaLabel","closeAriaLabel","items","selectedRefinersMap","contentAction","etext","clearAllAttributes","className","item","listItemProps","urlBuilder","onClick","role","choiceFormat","choiceRangeValueFormat","refinerHierarchy","overallFormat","rangeFormat","refinerValueName","refinerName","parent","hierarchy","KeyName","replace","_formatPrice","UnitText","LeftValueBoundLocalizedString","amount","currency","cultureFormatter","formatCurrency","error","selected","textContent","trim","ErrorMessage","text","FeatureSearchResultItem","imageSettings","resources","productName","Name","productRecordId","productUrl","getProductPageUrlSync","actionContext","fallbackImage","getFallbackImageUrl","ItemId","heading","featureSimilarDescriptionTitle","featureSimilarLooksTitle","gridSettings","imageUrl","altText","img","src","imageProps","fallBackSrc","loadFailureBehavior","renderProductPlacementImage","request","title","Link","ariaLabel","ModalToggle","innerRef","ref","modalNode","autoFocus","applicationNode","returnFocusRef","returnRef","isOpen","toggle","onModalToggle","zIndex","modalHeaderNode","modalTitle","modalFooterNode","modalCloseButtonText","getInventoryLabel","inventoryAttribute","ProductSearchResultItems","moduleType","moduleId","allowBackNavigation","quickviewSlot","isPriceMinMaxEnabled","productsDimensionAvailabilities","priceResources","priceRangeSeparator","ProductComponent","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","allowBack","typeName","data","quickViewButton","inventoryLabel","dimensionAvailabilities","dimensionAvailability","masterProductId","MasterProductId","RangeRefineItem","_formattedPriceReverseLookup","Map","getLabels","sliderId","minPrice","maxPrice","labelId","labelString","labelPositioning","getSliderThumbs","sliderKey","selectedMin","selectedMinPrice","selectedMax","selectedMaxPrice","minValueSliderThumbAriaLabel","currencyCode","ariaValueText","maxValueSliderThumbAriaLabel","_onRangeUpdate","bind","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","minInput","maxInput","selectedRefinementCriterion","initialMin","initialMax","String","minValue","maxValue","labels","sliderKeyString","sliderThumbs","state","isChecked","validationErrorMin","validationErrorMax","touchedMin","touchedMax","nextProps","nextState","previousProps","updateSliderProps","refineItemCommonProps","rangeType","_renderInputFields","_renderSlider","setState","isDisabled","formAttrs","rangeNameFormat","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onChange","onFocus","onBlur","maxLabel","placeholder","placeholderTextMax","ariaAttributes","inForm","min","max","step","orientation","showLabels","showTooltip","onChangeEnd","handleTooltipText","event","_changeValue","inputType","selectedKey","touchedKey","_getInputWithoutFormatting","selectedMinValue","minTouched","onToggle","maxNum","validationErrorNaN","_focus","_validateRange","selectedMaxValue","maxTouched","minNum","setTimeout","current","focus","touched","validationError","validationErrorRange","inputAsNum","get","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","document","getElementById","tooltip","RefineItem","anchorType","productCountAriaLabel","singleProductCountAriaLabel","children","attrs","isSingleSelect","itemTypeClassName","SourceValue","_renderRating","_getRefinerUrl","tabIndex","_renderSwatch","Count","dimensionType","toLocaleLowerCase","hasColor","StringExtensions","SwatchColorHexCode","hasImage","SwatchImageUrl","swatchItems","checkIfShouldDisplayAsSwatch","colorHexCode","SwatchComponent","list","isSelectionEnabled","ratingUserCountAriaLabel","ratingSingleUserCountAriaLabel","refinerRating","parseInt","ratingRefiner","selectedRefinerValues","selectedRating","defaultChkProductCount","ratingComponentClass","productCountAriaLabelValue","isMobileView","avgRating","ratingCount","hideCount","readOnly","moduleTypeName","RefineSubmenu","_onToggleItem","_onToggleSubmenu","isExpanded","isExpandedOnInitialLoad","expanded","productRefinerHierarchy","hideRating","timeout","_renderChildItems","_renderRange","_renderSingleMultiSelect","isMobile","refinerValuesList","listItems","selectedValue","DisplayTemplateValue","DisplayTemplate","_getRangeType","onUpdateRefiners","prevState","Separator","separator","Title","SearchResultContainer","sortByDropdownOptions","_pageType","expandrefinerCount","defaultPageNumber","_getProductsDimensionsAvailabilities","productsList","listPageState","_getActivePrice","_getSearchResultModal","modal","modalHeader","modalFooter","modalBody","SearchResultModal","modalIsOpen","_modalToggleRef","_toggleModal","_getCollectionTitle","collectionTitle","getFriendlyName","NameTranslations","productCountNumber","productCountText","format","numberOfProducts","oneProduct","pageName","telemetryPageName","toLowerCase","titlePrefix","searchTextPrefix","titleText","titleCount","TitleContainer","_getCategoryHierarchy","categoryHierarchy","CategoryHierarchyContainer","tag","categoryHierarchyList","categoryLinkAriaLabel","Url","categoryHierarchySeparator","_getSortingDropDown","activeDropdown","_getCurrentlySelectedOption","sortingState","selectedSortByOption","dropdwonOptions","dropdownOption","SortingContainer","sortByDropDown","labelClassname","labelText","sortByDropdownLabel","dropdownId","dropdownClassname","toggleColor","dropdownOptions","selectedOption","onSelectOption","_updateSortByDropdown","_sortAndFilterContainerRef","_getPagination","totalItems","previousText","flipperPrevious","nextText","flipperNext","paginationAriaLabel","qsp","startingItem","_renderPrev","_renderNext","previousAriaLabel","nextAriaLabel","_getRefineMenu","tempRangeTypeTODO","inputRange","validRefiners","activeRefiners","_getexpandRefinerCount","expandRefinersCount","expandedRefiners","RefineMenuContainer","RefinerSectionContainer","_refineItemCommonProps","_onUpdateRefiners","_buildRefinerUrl","_getChoiceSummary","selectedRefiners","choiceSummaryLabel","_onChoiceClicked","_buildRefinerUrlForChoiceSummary","_getProducts","breaCrumbType","breadcrumbType","quickviewslot","slots","quickview","isPriceMinMaxFeatureState","featureState","IsEnabled","notification","history","pushState","_getSortColumnFromSelectedOption","option","mappedConfiguration","_getSortCriteriaColumn","sortCriteria","queryColumns","activeSortColumn","activeMappedConfig","mappedSearchConfig","newRefinementCriteria","dropdownElementId","dropdownElement","selectedChoice","isClearAll","refinerCount","paginationPreviousText","paginationNextText","_viewport","device","Type","_updateViewport","pending","validationErrorNotNumber","validationErrorNotRange","friendlyName","querySorting","Math","productResults","enableAffiliationBasedPricing","user","isAuthenticated","refinerInput","catch","listPageStateFeature","nameTranslations","nameTranslation","Language","Text","addEventListener","dimensionsToDisplayOnProductCard","dimensionsInProductCard","dimensionsToDisplayAsSwatch","dimensionsAsSwatchType","DimensionTypes","removeEventListener","searchProduct","errorText","resultCategoryNotFoundText","resultSearchNotFoundText","productsComponent","featureComponent","searchResultContainerViewProps","TitleViewProps","disableHierarchy","refineMenu","moduleProps","sortByOptions","pagination","ProductsContainer","ProductSectionContainer","CategoryNavContainer","RefineAndProductSectionContainer","choiceSummary","modalToggle","searchResultModal","errorMessage","FeatureSearchContainer","similarLookProduct","renderView","innerWidth","xs","w","sm","md","lg","_getViewport","createSearchResultModal","modalProps","isRecoSearchPage","createModalBody","renderSort","renderRefiner","Node","submenu","renderCategoryHierarchy","renderTitle","renderTitleCount","Module","createSearchStateInput","getGenericActionDataAction","SearchState","SuggestionType","AutoSuggestInput","top","suggestionType","hitPrefix","hitSuffix","searchQuery","topResultsCount","_getAutoSuggest","autosuggest","ProductSearchCriteria","HitPrefix","HitSuffix","searchSuggestions","getSearchSuggestionsAsync","ImageUrl","generateImageUrl","AllSearchResults","autoSuggestPromises","Promise","all","CategorySuggestionsComponent","suggestions","autoSuggestProps","categorySuggestionHeading","reactNodes","_assembleNode","_renderTitle","categoryAutoSuggestionHeading","shouldShowFullPath","splitValue","Value","split","pop","RegExp","Id","_generateLink","_getHighlightedText","suggestion","_getCategoryLink","searchPageURL","searchQsp","searchRefiners","queryUrl","categoryRefiners","encodedRefiner","formattedText","dangerouslySetInnerHTML","FormComponent","searchPlaceholder","hideSearchLabel","searchTextInput","handleInputChange","maxChars","disableSubmitSearch","handleCancelSearchChange","ariaLabelCancel","ariaLabelSearch","ariaLabelSubmit","onInputChange","onInputChangeFunction","inputNode","type","name","maxLength","submitBtnNode","cancelBtn","submitBtn","KeywordSuggestionsComponent","formattedLink","LabelComponent","searchLabelClass","searchLabelArialLabel","isSearchFormExpanded","searchtext","searchCollapsedLabel","attributes","ProductSuggestionsComponent","productSuggestionHeading","productAutoSuggestionHeading","thumbnail","_renderThumbnail","price","Value3","DecimalValue","_renderPrice","LiProduct","_getLiWrapper","AProduct","_getAWrapper","recid","productPrice","adjustedPrice","basePrice","PriceComponent","CustomerContextualPrice","BasePrice","cropFocalRegion","viewports","h","xl","lazyload","Search","waitTime","_isLoadingNode","loadingText","autoSuggestResultLoadingMessage","Spinner","size","labelPosition","_focusOutTarget","closest","_clearAutoSuggestState","_keyup","keyCode","formReference","contains","autoSuggestResultDiv","searchState","defaultBasicSearchUrl","searchQueryStringParameter","_handleInputChange","cancellabelDebounce","cancel","isLoadingAutoSuggest","_getSuggestionType","inputSuggestionType","results","_getSearchRefiners","autoSuggestAriaLabel","_setAutoSuggestResultCount","exception","debug","suggestionTypes","distinctSuggestionTypes","suggestionTypeItem","charAt","slice","join","_handleSubmit","searchURL","_appendQueryParams","_handleCancelSearchChange","isInitialState","route","autoSuggestResultScreenReaderDiv","ariaLiveRegion","suggestResultString","autoSuggestFoundMessage","emptyResultString","noAutoSuggestionMessage","innerText","setAttribute","searchKeywordSuggestClass","searchProductSuggestClass","searchCategorySuggestClass","searchInputMaxLength","suggestionTypeCriterion","searchFormClass","body","params","isEditor","cancelBtnAriaLabel","searchBtnAriaLabel","submitBtnAriaLabel","searchplaceholderText","shouldShowFullCategoryPath","keywordSuggestions","i","Keyword","None","productSuggestions","Product","categorySuggestions","Category","viewProps","AutoSuggestAriaLabel","AutoSuggestAriaLabelText","AutoSuggest","KeywordSuggest","ProductSuggest","CategorySuggest","SearchForm","FormWrapper","autoComplete","onSubmit","UlKeyword","UlProduct","UlCategory","form","autosuggestKeyword","autosuggestProduct","autosuggestCategory","callbacks","isLoadingNode","_renderForm","_renderKeywordSuggestions","_renderProductSuggestions","_renderCategorySuggestions"],"sourceRoot":""}