{"version":3,"sources":["webpack:///src/modules/search-result-container/actions/get-mapped-search-configuration.ts?978c","webpack:///src/modules/search-result-container/components/title.tsx?365d","webpack:///src/modules/search-result-container/components/utilities.ts?41e3","webpack:///src/modules/search-result-container/search-result-container.tsx?97e0","webpack:///src/modules/search-result-container/components/error-message.tsx?c0c2","webpack:///src/modules/search-result-container/actions/url-utils.ts?6091","webpack:///src/modules/search-result-container/actions/base-collection-action.ts?32fc","webpack:///src/modules/text-block/text-block.view.tsx?8d9b","webpack:///src/modules/search-result-container/search-result-container.view.tsx?3d61","webpack:///src/modules/search-result-container/components/refine-item.tsx?b232","webpack:///src/modules/search-result-container/components/index.ts?cc7a","webpack:///src/modules/tab-item/tab-item.tsx?d2c1","webpack:///src/modules/search-result-container/components/product-search-result-items.tsx?1766","webpack:///src/modules/search-result-container/components/choice-summary.tsx?f4a7","webpack:///src/modules/search/search.view.tsx?e62d","webpack:///src/modules/search-result-container/components/refine-submenu.tsx?1e62","webpack:///src/modules/search-result-container/components/separator.tsx?7b76","webpack:///src/modules/search-result-container/actions/get-product-refiner-hierarchy.ts?bc3c","webpack:///src/modules/search-result-container/actions/get-refiners-for-collection.ts?3c89","webpack:///src/modules/search-result-container/actions/get-full-products-by-collection.ts?5cc2","webpack:///src/modules/search-result-container/components/range-refine-item.tsx?6e24","webpack:///src/modules/search-result-container/components/link.tsx?d3ce","webpack:///src/search-state-data-action.ts?8823","webpack:///src/modules/search-result-container/components/modal.tsx?afdd","webpack:///src/modules/search-result-container/list-page-state.ts?90c8","webpack:///src/modules/search-result-container/components/feature-search-result-item.tsx?98c1","webpack:///src/search-state.ts?b5d7","webpack:///src/modules/search/actions/get-auto-suggest-suggestions.ts?6ade","webpack:///src/modules/search/components/search.categorysuggest.tsx?3bc4","webpack:///src/modules/search/components/search.form.tsx?3c4b","webpack:///src/modules/search/components/search.keywordsuggest.tsx?59ca","webpack:///src/modules/search/components/search.label.tsx?91cb","webpack:///src/modules/search/components/search.productsuggest.tsx?d6fa","webpack:///src/modules/search/search.tsx?3f45"],"names":["sortOptions","sortByOptionRelevanceDesc","sortByOptionRatingAsc","sortByOptionRatingDesc","sortByOptionNameAsc","sortByOptionNameDesc","sortByOptionPriceAsc","sortByOptionPriceDesc","MappedSearchInput","apiSettings","getCacheKey","this","getCacheObjectType","dataCacheType","async","getMappedSearchConfiguration","input","ctx","callerContext","then","searchConfiguration","ProductSortColumns","map","sortColumn","key","ColumnName","toUpperCase","IsDescending","telemetry","warning","filter","Boolean","createInput","inputData","requestContext","getMappedSearchConfigurationDataAction","id","action","Title","text","className","isRangeType","dataTypeValue","findMatchingRefinementCriterion","productRefinerValue","refinementCriteria","find","refinementCriterion","isMatchingRefinementCriterion","RefinerRecordId","RefinerSourceValue","DataTypeValue","LeftValueBoundString","getUpdatedRefinementCriteria","itemToggleNotification","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","forEach","selectedCriterion","isSelecting","next","undefined","rangeStart","RightValueBoundString","rangeEnd","push","parentProductRefinerHierarchy","RefinerTypeValue","Values","child","matchingIndex","findIndex","criterion","splice","formatPrice","amount","currency","locale","trace","priceAmount","Number","result","Intl","NumberFormat","style","currencyDisplay","minimumFractionDigits","format","error","props","state","super","sortByDropdownOptions","value","resources","_pageType","context","request","urlTokens","pageType","expandrefinerCount","_getActivePrice","products","data","listPageState","activeProducts","productRecIds","hasElements","prod","RecordId","projectDomain","ChannelId","channelId","CatalogId","catalogId","affliations","customerInput","actionContext","customer","CustomerAffiliations","affliation","aff","AffiliationId","RetailAffiliationId","CustomerId","AccountNumber","queryResultSettings","Date","activePricesResponse","productPrices","activePrice","price","ProductId","Price","CustomerContextualPrice","BasePrice","Math","max","TradeAgreementPrice","AdjustedPrice","catch","message","exception","debug","Error","_getSearchResultModal","modalCloseButtonText","modalTitle","isOpen","modalIsOpen","returnRef","_modalToggleRef","onModalToggle","_toggleModal","_getCollectionTitle","collectionTitle","query","q","category","getFriendlyName","NameTranslations","Name","productCountNumber","productCountText","totalProductCount","count","numberOfProducts","oneProduct","TitleContainer","title","titlePrefix","searchTextPrefix","titleText","titleCount","_getCategoryHierarchy","categoryHierarchy","CategoryHierarchyContainer","tag","categoryHierarchyList","index","ariaLabel","categoryLinkAriaLabel","href","Url","categoryHierarchySeparator","separator","_getSortingDropDown","activeDropdown","_getCurrentlySelectedOption","sortingState","selectedSortByOption","dropdwonOptions","app","config","hideRating","dropdownOption","SortingContainer","sortByDropDown","labelClassname","labelText","sortByDropdownLabel","dropdownId","dropdownClassname","toggleColor","dropdownOptions","selectedOption","onSelectOption","_updateSortByDropdown","ref","_sortAndFilterContainerRef","_getPagination","fullUrl","itemsPerPage","skipCount","currentPageNumber","skip","totalItems","previousText","flipperPrevious","nextText","flipperNext","role","paginationAriaLabel","url","qsp","items","startingItem","previousAriaLabel","nextAriaLabel","telemetryContent","_getRefineMenu","tempRangeTypeTODO","inputRange","validRefiners","refiners","refiner","length","activeRefiners","activeFilters","_getexpandRefinerCount","expandRefinersCount","expandedRefiners","RefineMenuContainer","RefinerSectionContainer","productRefinerHierarchy","selectedRefinerValues","refineItemCommonProps","_refineItemCommonProps","minValueSliderThumbAriaLabel","maxValueSliderThumbAriaLabel","onUpdateRefiners","_onUpdateRefiners","urlBuilder","_buildRefinerUrl","isDisabled","isExpandedOnInitialLoad","moduleId","moduleTypeName","typeName","_getChoiceSummary","selectedRefiners","classNames","clearAllText","label","choiceSummaryLabel","selectedChoices","refinerHierarchy","choiceFormat","choiceRangeValueFormat","onChoiceClicked","_onChoiceClicked","_buildRefinerUrlForChoiceSummary","choiceAriaLabel","_getProducts","imageSettings","allowBackNavigation","breaCrumbType","breadcrumbType","allowBack","quickviewslot","slots","quickview","moduleType","quickviewSlot","notification","window","history","pushState","_getSortColumnFromSelectedOption","sortingCritera","Columns","option","mappedConfiguration","sortCriteria","activeSortColumn","activeMappedConfig","mappedSearchConfig","newRefinementCriteria","clearAll","dropdownElementId","current","dropdownElement","document","getElementById","setTimeout","focus","selectedChoice","choiceClicked","selectedRefiner","isClearAll","refinerCount","_viewport","device","Type","bind","_updateViewport","pending","placeholderTextMax","minLabel","maxLabel","rangeNameFormat","validationErrorNaN","validationErrorNotNumber","validationErrorRange","validationErrorNotRange","telemetryPageName","friendlyName","querySorting","sorting","JSON","parse","decodeURIComponent","pageSize","Paging","Top","Skip","Sorting","itemId","stringify","productId","Recommendation","recommendation","includeAttributes","productResults","enableAffiliationBasedPricing","user","isAuthenticated","featureProduct","listPageStateFeature","nameTranslations","nameTranslation","item","Language","toLowerCase","Text","isBrowser","addEventListener","removeEventListener","searchProduct","errorText","resultCategoryNotFoundText","resultSearchNotFoundText","productsComponent","featureComponent","product","searchResultContainerViewProps","TitleViewProps","disableHierarchy","refineMenu","SearchResultContainer","moduleProps","sortByOptions","pagination","ProductsContainer","ProductSectionContainer","CategoryNavContainer","RefineAndProductSectionContainer","choiceSummary","modalToggle","innerRef","onClick","searchResultModal","isMobile","errorMessage","FeatureSearchContainer","similarLookProduct","renderView","innerWidth","gridSettings","xs","w","sm","md","lg","setState","_getViewport","ErrorMessage","compressedRefinerKeys","hydrateRefinersFromUrl","compressedRefinerArray","parseQueryParam","compressedRefiner","parsedRefiner","refinerKey","buildListPageUrl","sortingColumns","searchParams","delete","set","compressedRefiners","compressRefiners","toString","getCurrentUrl","URL","location","requestUrl","BaseCollectionInput","searchText","createBaseCollectionInput","args","inputClassConstuctor","categoryId","fromInputData","QueryResultSettings","queryRefiners","getIncludeAttributes","renderModuleAttributes","paragraph","createSearchResultModal","modalProps","modal","modalHeader","createModalBody","modalFooter","modalBody","renderSort","renderRefiner","submenu","renderCategoryHierarchy","renderTitle","renderTitleCount","RefineItem","_onClick","e","preventDefault","selectedRefinementCriterion","onToggle","anchorType","isChecked","payLoad","children","attrs","isSingleSelect","itemTypeClassName","inputType","SourceValue","contentAction","etext","LeftValueBoundLocalizedString","attribute","refinerRating","parseInt","ratingRefiner","selectedRating","ratingComponentClass","KeyName","_getRefinerUrl","avgRating","ratingCount","hideCount","readOnly","Count","tabIndex","TabItemType","TabItem","moduleContentClassName","moduleHeaderClassName","_renderTabHeader","isSelected","itemIndex","contentID","getContentID","tabId","activeContentIDResult","activeTabState","shown","activeContentIndex","TabContentContainer","TabHeaderContainer","TabItemContent","tabHeader","tabSlots","tabItemTitle","ProductSearchResultItems","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","quickViewButton","ChoiceSummary","closeButtonGlyph","stopPropagation","target","currentTarget","getAttribute","includes","_getSelectedRefinerChoice","itemClicked","nextItemToFocus","nextSibling","_getKeyForRefinerValue","selectedRefinersMap","clearAllAttributes","listItemProps","overallFormat","rangeFormat","refinerValueName","refinerName","parent","hierarchy","replace","_formatPrice","UnitText","selected","textContent","trim","_renderForm","form","SearchForm","FormWrapper","submitBtn","cancelBtn","_renderKeywordSuggestions","KeywordSuggest","UlKeyword","keywordSuggestions","_renderProductSuggestions","ProductSuggest","UlProduct","productSuggestions","LiProduct","AProduct","thumbnail","_renderCategorySuggestions","CategorySuggest","UlCategory","categorySuggestions","Search","AutoSuggestAriaLabel","AutoSuggestAriaLabelText","AutoSuggest","autosuggestCategory","autosuggestKeyword","autosuggestProduct","_onToggleItem","_onToggleSubmenu","isExpanded","expanded","timeout","_renderChildItems","_renderRange","_renderSingleMultiSelect","refinerValuesList","listItems","selectedValue","DisplayTemplateValue","rangeType","_getRangeType","prevState","Separator","getProductRefinerHierarchy","searchCriteria","productRefiners","productRefiner","actionDataAction","searchProductId","CategoryIds","Context","SearchCondition","searchObject","isNaN","RecommendationListId","Ids","GetFullProductsByCollectionInput","productSearchResults","promise","searchCriteriaInput","Refinement","IncludeAttributes","SkipVariantExpansion","mappedProducts","productSearchResult","newImageUrl","PrimaryImageUrl","update","metadata","RangeRefineItem","_formattedPriceReverseLookup","Map","_onRangeUpdate","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","minInput","maxInput","initialMin","initialMax","validationErrorMin","validationErrorMax","selectedMin","selectedMax","touchedMin","touchedMax","_renderInputFields","_renderSlider","formAttrs","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","onChange","onFocus","onBlur","placeholder","min","sliderId","ariaAttributes","minPrice","maxPrice","selectedMinPrice","selectedMaxPrice","inForm","step","orientation","labels","labelId","labelString","labelPositioning","showLabels","showTooltip","sliderThumbs","currencyCode","ariaValueText","onChangeEnd","handleTooltipText","event","_changeValue","selectedKey","touchedKey","_getInputWithoutFormatting","selectedMinValue","minTouched","maxNum","_focus","_validateRange","selectedMaxValue","maxTouched","minNum","touched","validationError","has","inputAsNum","get","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","element","tooltip","Link","createSearchStateInput","getGenericActionDataAction","ModalToggle","SearchResultModal","modalNode","modalHeaderNode","modalFooterNode","autoFocus","applicationNode","returnFocusRef","toggle","zIndex","ListPageState","ListPageStateInput","listPageStateAction","createListPageInput","FeatureSearchResultItem","productName","productRecordId","productUrl","fallbackImage","ItemId","heading","featureSimilarDescriptionTitle","featureSimilarLooksTitle","imageUrl","altText","img","src","imageProps","fallBackSrc","loadFailureBehavior","renderProductPlacementImage","renderProductTitle","SearchState","AutoSuggestInput","top","suggestionType","hitPrefix","hitSuffix","searchQuery","topResultsCount","_getAutoSuggest","autosuggest","ProductSearchCriteria","HitPrefix","HitSuffix","SuggestionType","searchSuggestions","ImageUrl","AllSearchResults","autoSuggestPromises","Promise","all","CategorySuggestionsComponent","suggestions","autoSuggestProps","categorySuggestionHeading","reactNodes","_assembleNode","_renderTitle","categoryAutoSuggestionHeading","splitValue","Value","split","pop","RegExp","Id","_generateLink","_getHighlightedText","suggestion","_getCategoryLink","searchPageURL","searchQsp","searchRefiners","route","urlPath","categoryRefiners","encodedRefiner","encodeURIComponent","formattedText","dangerouslySetInnerHTML","FormComponent","searchPlaceholder","hideSearchLabel","isSearchFormExpanded","searchTextInput","handleInputChange","maxChars","disableSubmitSearch","handleCancelSearchChange","ariaLabelCancel","ariaLabelSearch","ariaLabelSubmit","onInputChange","inputNode","type","name","maxLength","submitBtnNode","KeywordSuggestionsComponent","formattedLink","LabelComponent","searchLabelClass","searchLabelArialLabel","searchtext","searchCollapsedLabel","attributes","ProductSuggestionsComponent","productSuggestionHeading","productAutoSuggestionHeading","_renderThumbnail","Value3","DecimalValue","_renderPrice","_getLiWrapper","_getAWrapper","recid","adjustedPrice","basePrice","cropFocalRegion","viewports","h","xl","lazyload","waitTime","_focusOutTarget","closest","_clearAutoSuggestState","_keyup","keyCode","formReference","contains","autoSuggestResultDiv","searchState","defaultBasicSearchUrl","searchQueryStringParameter","_handleInputChange","cancellabelDebounce","cancel","_getSuggestionType","inputSuggestionType","results","_getSearchRefiners","autoSuggestAriaLabel","_setAutoSuggestResultCount","suggestionTypes","distinctSuggestionTypes","suggestionTypeItem","charAt","slice","join","_handleSubmit","searchURL","_appendQueryParams","_handleCancelSearchChange","isInitialState","autoSuggestResultScreenReaderDiv","ariaLiveRegion","suggestResultString","autoSuggestFoundMessage","emptyResultString","noAutoSuggestionMessage","innerText","setAttribute","searchKeywordSuggestClass","searchProductSuggestClass","searchCategorySuggestClass","searchInputMaxLength","suggestionTypeCriterion","searchFormClass","body","params","isEditor","cancelBtnAriaLabel","searchBtnAriaLabel","submitBtnAriaLabel","searchplaceholderText","i","viewProps","autoComplete","onSubmit","callbacks"],"mappings":"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","file":"static/js/2.a4ad1e43b694aaf7.chunk.js","sourcesContent":["/*--------------------------------------------------------------\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};\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 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 * 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 { 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 const 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 const 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 const 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 { CategoryHierarchy as CategoryHierarchyData, IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport MsDyn365 from '@msdyn365-commerce/core';\nimport { format, ProductPrice, ProductRefinerValue, ProjectionDomain, SortColumn, TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\nimport {\n getActivePricesAsync\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\nimport { AffiliationLoyaltyTier, CustomerAffiliation } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\nimport { ArrayExtensions, getCustomer, GetCustomerInput } from '@msdyn365-commerce-modules/retail-actions';\nimport { getTelemetryObject, ILabeledDropdownOnChangeNotification, ILabeledDropdownOption, IModuleProps, 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, getCurrentUrl, GetFullProductsByCollectionInput, parseQueryParam, sortOptions } from './actions';\nimport {\n ErrorMessage, FeatureSearchResultItem, getUpdatedRefinementCriteria, IChoiceSummaryClickNotification,\n IRefineItemCommonProps, IRefineItemToggleNotification, ISearchResultModalViewProps, isMatchingRefinementCriterion, 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}\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 ];\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 productPrices: ProductPrice[];\n\n public static getFriendlyName(locale: string, nameTranslations?: TextValueTranslation[]): string | undefined {\n let nameTranslation: TextValueTranslation | undefined;\n if (locale && nameTranslations && nameTranslations.length > 0) {\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\n }\n\n return nameTranslation && nameTranslation.Text;\n }\n\n 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 };\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\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.context.request.locale\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 );\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 }\n this._updateViewport();\n }\n\n public componentDidMount(): void {\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\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 private readonly _getActivePrice = async (): Promise => {\n let products = (this.props.data.listPageState.result && this.props.data.listPageState.result.activeProducts) || [];\n const productRecIds = ArrayExtensions.hasElements(products) ? products.map(prod => prod.RecordId) : [];\n const projectDomain: ProjectionDomain = { ChannelId: this.props.context.request.apiSettings.channelId, CatalogId: this.props.context.request.apiSettings.catalogId };\n const affliations: AffiliationLoyaltyTier[] = [];\n const customerInput = new GetCustomerInput(this.props.context.actionContext.requestContext.apiSettings);\n const customer = await getCustomer(customerInput, this.props.context.actionContext);\n\n if (customer && customer.CustomerAffiliations) {\n customer.CustomerAffiliations.forEach((affliation: CustomerAffiliation) => {\n const aff: AffiliationLoyaltyTier = { AffiliationId: affliation.RetailAffiliationId, CustomerId: customer.AccountNumber };\n affliations.push(aff);\n });\n }\n\n await getActivePricesAsync(\n { callerContext: this.props.context.actionContext, queryResultSettings: {} },\n projectDomain,\n productRecIds,\n new Date(),\n null,\n affliations,\n true\n ).then((activePricesResponse: ProductPrice[]) => {\n this.productPrices = activePricesResponse;\n products = products.map(prod => {\n const activePrice = activePricesResponse.find(price => price.ProductId === prod.RecordId);\n if (activePrice) {\n prod.Price = activePrice.CustomerContextualPrice ?? prod.Price;\n prod.BasePrice = Math.max(activePrice.BasePrice || 0, activePrice.TradeAgreementPrice || 0, activePrice.AdjustedPrice || 0);\n }\n return prod;\n });\n this.props.data.listPageState.then((listPageState) => {\n listPageState.activeProducts = products;\n });\n }).catch((error: Error) => {\n this.props.context.actionContext.trace(error.message);\n this.props.context.actionContext.telemetry.exception(error);\n this.props.context.actionContext.telemetry.debug('[get Affiliation based price on search result container ]Error executing action');\n throw new Error('[get Affiliation based price on search result container]Error executing action');\n });\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 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' },\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 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={<div className='msc-pagination__prev'>\n <span className='ms-search-result__pagination-left' aria-hidden='true' />\n <span className='prev-text'>\n {previousText}\n </span>\n </div>}\n nextText={<div className='msc-pagination__next'>\n <span className='next-text'>\n {nextText}\n </span>\n <span className='ms-search-result__pagination-right' aria-hidden='true' />\n </div>}\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 = data.refiners.result && data.refiners.result.filter(refiner => {\n return refiner.Values.length > 0;\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 />\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 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 />\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\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 />\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 private readonly _getCurrentlySelectedOption = (): ILabeledDropdownOption | undefined => {\n const { data } = this.props;\n const sortCriteria = data.listPageState.result && data.listPageState.result.sortingCritera;\n\n const activeSortColumn =\n (sortCriteria && sortCriteria.Columns && sortCriteria.Columns[0]) ||\n (parseQueryParam<SortColumn[]>('sorting', this.props.context.request) || [])[0];\n\n if (activeSortColumn && data.searchConfiguration.result) {\n const activeMappedConfig = data.searchConfiguration.result.find((mappedSearchConfig) => {\n return (mappedSearchConfig.sortColumn.ColumnName === activeSortColumn.ColumnName) &&\n (mappedSearchConfig.sortColumn.IsDescending === activeSortColumn.IsDescending);\n });\n if (activeMappedConfig) {\n return this.sortByDropdownOptions.find((dropdownOption) => dropdownOption.key === activeMappedConfig.key);\n }\n }\n\n return;\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 * 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<IErrorMessage> = ({ text }) => {\n return (\n <span className='ms-search-result-container__no-results-message'>\n <h5 className='error-text'>\n {' '}\n {text}\n {' '}\n </h5>\n </span>\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 <ProductRefinerValue[]>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 fullUrl.searchParams.set('refiners', JSON.stringify(compressRefiners(refiners)));\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 = <T>(key: string, requestContext: IRequestContext): T | null => {\n if (requestContext.query && requestContext.query[key]) {\n return <T>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(<string><unknown>(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 {\n CacheType,\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\nexport type listPageType = 'Category' | 'Search' | 'Unknown';\n\n/**\n * Get include attributes from config.\n * @param inputData\n */\nfunction getIncludeAttributes(inputData: ICreateActionContext<IGeneric<IAny>, IGeneric<IAny>>): 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 * 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 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 locale?: string\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.locale = locale;\n }\n\n public getCacheKey = () => {\n const queryResultSettings = {\n ...this.queryResultSettings.Paging,\n ...toJS(this.queryResultSettings.Sorting)\n };\n\n const cacheKey = buildCacheKey(\n `${this.pageType}-${this.locale}-${this.category || this.searchText}-${this.refiners.map(refiner => `${refiner.RefinerRecordId + (refiner.LeftValueBoundString || '') + (refiner.RightValueBoundString || '')}-`)}-${convertToString(queryResultSettings)}`,\n 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 locale?: string\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\n if (args.requestContext.query && args.requestContext.query.sorting) {\n queryResultSettings.Sorting = { Columns: <SortColumn[]>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 args.requestContext.locale\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 args.requestContext.locale\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 args.requestContext.locale\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 * as React from 'react';\n\nimport { ITextBlockViewProps } from './text-block';\n\nconst TextBlockView: React.FC<ITextBlockViewProps> = props => (\n <div className={props.className} id={props.id} {...props.renderModuleAttributes(props)}>\n {props.paragraph}\n </div>\n);\n\nexport default TextBlockView;\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 if (isMobile) {\n return (\n <Module {...SearchResultContainer}>\n {renderCategoryHierarchy(categoryHierarchy)}\n {renderTitle(TitleViewProps)}\n {choiceSummary}\n {modalToggle}\n {createSearchResultModal(searchResultModal, refineMenu, sortByOptions)}\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 && 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, sortByDropDown: ISortByViewProps): JSX.Element => {\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown), modalProps.modalFooter);\n};\n\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps): JSX.Element | null => {\n if (sortByDropDown) {\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown), 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): JSX.Element | null => {\n const { SortingContainer, sortByDropDown } = props;\n if (sortByDropDown) {\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 { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { RatingComponent } from '@msdyn365-commerce/components';\nimport { ICoreContext } from '@msdyn365-commerce/core';\nimport { ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\nimport { 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\n /** The telemetry content */\n telemetryContent?: ITelemetryContent;\n onToggle(notfication: Readonly<IRefineItemToggleNotification>): 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<IRefineItemProps, IRefineItemState> {\n private readonly anchorType: React.RefObject<HTMLAnchorElement>;\n\n private readonly payLoad: IPayLoad;\n\n 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 render(): JSX.Element | undefined {\n const {\n isDisabled,\n refineItemCommonProps,\n parentProductRefinerHierarchy,\n productRefinerValue,\n selectedRefinementCriterion,\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 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 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 return (\n <li\n className='ms-refine-submenu-item'\n role='radio'\n aria-checked={isChecked}\n id={`${parentProductRefinerHierarchy.KeyName!}_${index}`}\n aria-label={`${parentProductRefinerHierarchy.KeyName!}_${index}`}\n >\n <a\n href={this._getRefinerUrl()}\n aria-label={`${parentProductRefinerHierarchy.KeyName!}_${productRefinerValue.LeftValueBoundLocalizedString}`}\n onClick={this._onClick}\n {...attribute}\n >\n <RatingComponent\n className={ratingComponentClass}\n avgRating={refinerRating}\n ratingCount={productRefinerValue.LeftValueBoundLocalizedString ?? productRefinerValue.LeftValueBoundString}\n hideCount={false}\n readOnly\n ariaLabel=''\n context={context}\n id={this.props.moduleId}\n typeName={this.props.moduleTypeName}\n data={{}}\n />\n <span className='refine-submenu-item__rating'>\n {productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}\n </span>\n </a>\n </li>\n );\n }\n return undefined;\n\n }\n this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString;\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\n return (\n <li className='ms-refine-submenu-item' id={`${parentProductRefinerHierarchy.KeyName!}_${index}`}>\n <a\n key={selectedRefinementCriterion ? 'true' : 'false'}\n ref={this.anchorType}\n href={this._getRefinerUrl()}\n tabIndex={0}\n onClick={this._onClick}\n className={itemTypeClassName}\n role={inputType}\n aria-checked={!!selectedRefinementCriterion}\n {...attribute}\n {...attrs}\n >\n <span className='ms-refine-submenu-item__label'>\n {productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}\n {productRefinerValue.Count !== undefined && ` (${productRefinerValue.Count})`}\n </span>\n </a>\n </li>\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<HTMLAnchorElement | HTMLInputElement>): 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","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './choice-summary';\nexport * from './choice-summary.props';\nexport * from './error-message';\nexport * from './feature-search-result-item';\nexport * from './link';\nexport * from './modal';\nexport * from './product-search-result-items';\nexport * from './range-refine-item';\nexport * from './refine-item';\nexport * from './refine-item.props.common';\nexport * from './refine-item-toggle-notification';\nexport * from './refine-submenu';\nexport * from './separator';\nexport * from './title';\nexport * from './utilities';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IModuleProps, INodeProps, NodeTag } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { ITabItemData } from './tab-item.data';\nimport { ITabItemProps } from './tab-item.props.autogenerated';\n\nexport interface ITabItemViewProps {\n TabContentContainer: IModuleProps;\n TabHeaderContainer: IModuleProps;\n tabSlots: INodeProps;\n TabItemContent: INodeProps;\n tabItemType?: TabItemType;\n tabHeader: React.ReactNode;\n}\n\nexport interface ITabItemExtentedProps extends ITabItemProps<ITabItemData> {\n tabItemType?: TabItemType;\n isSelected?: boolean;\n itemIndex?: number;\n tabId?: string;\n}\n\nexport enum TabItemType {\n TabHeader,\n TabContent\n}\n\n/**\n *\n * TabItem component.\n * @extends {React.Component<ITabItemExtentedProps>}\n */\n@observer\nclass TabItem extends React.Component<ITabItemExtentedProps> {\n private readonly moduleContentClassName: string = 'ms-tab-item-content';\n\n private readonly moduleHeaderClassName: string = 'ms-tab-item-header';\n\n constructor(props: ITabItemProps<ITabItemData>) {\n super(props);\n this._renderTabHeader = this._renderTabHeader.bind(this);\n }\n\n public render(): JSX.Element {\n const { slots, renderView, config, data, isSelected, itemIndex } = this.props;\n const index = itemIndex || 0;\n const contentID = getContentID(index, this.props.tabId || '');\n const activeContentIDResult = data && data.activeTabState && data.activeTabState.result;\n const shown = activeContentIDResult && activeContentIDResult.tabId === this.props.tabId && activeContentIDResult.activeContentIndex !== undefined ? activeContentIDResult.activeContentIndex === index : isSelected || false;\n const viewProps = {\n ...this.props,\n TabContentContainer: {\n moduleProps: this.props,\n className: classnames(this.moduleContentClassName, config.className)\n },\n TabHeaderContainer: {\n moduleProps: this.props,\n className: classnames(this.moduleHeaderClassName, config.className)\n },\n TabItemContent: {\n className: 'ms-tab-item-content__content',\n tag: 'section' as NodeTag,\n 'aria-hidden': !shown,\n role: 'tabpanel',\n tabIndex: shown ? 0 : -1,\n id: contentID\n },\n tabHeader: this._renderTabHeader(),\n tabSlots: slots\n };\n return renderView(viewProps) as React.ReactElement;\n\n }\n\n private _renderTabHeader(): React.ReactNode {\n return (\n <>\n {this.props.config.tabItemTitle}\n </>\n );\n }\n\n}\n\nexport const getContentID = (index: number, id: string) => {\n return `tab-item-content-${id}-${index}`;\n};\n\nexport default TabItem;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ProductComponent } from '@msdyn365-commerce/components';\nimport { ICoreContext, IImageSettings } from '@msdyn365-commerce/core';\nimport { ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\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}\n\nexport const ProductSearchResultItems: React.FC<IProductSearchResultItems> = ({\n products,\n context,\n imageSettings,\n resources,\n moduleType,\n moduleId,\n allowBackNavigation,\n telemetryContent,\n quickviewSlot\n}) => {\n\n return (\n\n <ul className='list-unstyled'>\n {products.map((product: ProductSearchResult, index: number) => (\n <li className='ms-product-search-result__item' key={index}>\n <ProductComponent\n context={context}\n telemetryContent={telemetryContent}\n imageSettings={imageSettings}\n freePriceText={resources.priceFree}\n originalPriceText={resources.originalPriceText}\n currentPriceText={resources.currentPriceText}\n ratingAriaLabel={resources.ratingAriaLabel}\n allowBack={allowBackNavigation}\n id={moduleId}\n typeName={moduleType}\n data={{ product }}\n quickViewButton={quickviewSlot}\n />\n </li>\n ))}\n </ul>\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 { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport { get } from 'lodash';\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.Component<IChoiceSummaryProps> {\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<IChoiceSummaryProps>) {\n super(props);\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\n }\n\n public render(): JSX.Element {\n const { clearAllText, label, classNames, choiceAriaLabel } = 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 <div className='msc-choice-summary'>\n {items.length > 0 && label && <span className='msc-choice-summary__label'>\n {label}\n </span>}\n <ul className={classnames(classNames, 'msc-choice-summary__list', 'list-unstyled')}>\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 <li className='msc-choice-summary__list-item' key={item.key} {...listItemProps}>\n <a\n className='msc-choice-summary__item'\n href={this.props.urlBuilder(item.value, false)}\n aria-label={`${item.key} ${choiceAriaLabel}`}\n onClick={this._onClick}\n {...attribute}\n >\n {item.key}\n <span className={`${this.closeButtonGlyph} msc-choice-summary__glyph`} />\n </a>\n </li>\n );\n })}\n </ul>\n {items.length > 0 && clearAllText && <a\n href={this.props.urlBuilder({}, true)} className='msc-choice-summary__clear-all' {...clearAllAttributes}\n onClick={this._onClick}>\n {clearAllText}\n </a>}\n </div>\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 const priceAmount = (amount && Number(amount)) || 0;\n const locale = get(this.props, 'context.request.locale', 'en-US');\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 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<HTMLAnchorElement>): 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 { 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 } = 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)}\n {_renderProductSuggestions(ProductSuggest, UlProduct, autosuggestProduct)}\n {_renderCategorySuggestions(CategorySuggest, UlCategory, autosuggestCategory)}\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.submitBtn}\n {form.input}\n {form.cancelBtn}\n </Node>\n </Node>\n );\n};\n\nconst _renderKeywordSuggestions = (\n KeywordSuggest: INodeProps,\n UlKeyword: INodeProps,\n keywordSuggestions?: ISearchKeywordViewProps\n) => {\n return (\n keywordSuggestions && (\n <Node {...KeywordSuggest}>\n <Node {...UlKeyword}>\n {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) => {\n return (\n productSuggestions && (\n <Node {...ProductSuggest}>\n <Node {...UlProduct}>\n {productSuggestions.title}\n {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) => {\n return (\n categorySuggestions && (\n <Node {...CategorySuggest}>\n <Node {...UlCategory}>\n {categorySuggestions.title}\n {categorySuggestions.text.map(text => {\n return text;\n })}\n </Node>\n </Node>\n )\n );\n};\n\nexport default SearchView;\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<IGeneric<IAny>>;\n moduleId: string;\n moduleTypeName: string;\n\n /** The telemetry content */\n telemetryContent?: ITelemetryContent;\n onUpdateRefiners(notfication: Readonly<IRefineItemToggleNotification>): 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<IRefineSubmenuProps>}\n */\nclass RefineSubmenu extends React.Component<IRefineSubmenuProps, IRefineSubmenuState> {\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 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 <div className={`ms-refine-submenu list-group ${productRefinerHierarchy.KeyName}`}>\n <Button\n className={this.state.expanded ? 'ms-refine-submenu__toggle_expanded' : 'ms-refine-submenu__toggle_collapsed'}\n aria-label={productRefinerHierarchy.KeyName || 'refiner.Name'}\n onClick={this._onToggleSubmenu}\n aria-expanded={this.state.expanded}\n >\n {productRefinerHierarchy.KeyName}\n </Button>\n <Collapse isOpen={this.state.expanded} timeout={350}>\n {this._renderChildItems(productRefinerHierarchy)}\n </Collapse>\n </div>\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 } = 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 <RefineItem\n parentProductRefinerHierarchy={productRefinerHierarchy}\n productRefinerValue={child}\n selectedRefinementCriterion={selectedRefinementCriterion}\n selectedRefinerValues={selectedRefinerValues.filter(selectedValue => 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 />\n );\n });\n return (\n <ul className={`ms-refine-submenu__list ${productRefinerHierarchy.KeyName}`} {...role} aria-label={productRefinerHierarchy.KeyName}>\n {listItems}\n </ul>\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 <li className={`${submenuClassNamePrefix}--range`} key={index}>\n <RangeRefineItem\n parentProductRefinerHierarchy={productRefinerHierarchy}\n productRefinerValue={child}\n selectedRefinementCriterion={selectedRefinementCriterion}\n refineItemCommonProps={refineItemCommonProps}\n onToggle={this._onToggleItem}\n urlBuilder={this.props.urlBuilder}\n isDisabled={isDisabled}\n rangeType={rangeType}\n key={key}\n context={context}\n minValueSliderThumbAriaLabel={minValueSliderThumbAriaLabel}\n maxValueSliderThumbAriaLabel={maxValueSliderThumbAriaLabel}\n moduleId={this.props.moduleId}\n moduleTypeName={this.props.moduleTypeName}\n />\n </li>\n );\n });\n return (<ul className={`ms-refine-submenu__list list-unstyled ${productRefinerHierarchy.KeyName}`}>\n {listItems}\n </ul>);\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<ISeparator> = ({ separator }) => (<span>\n {' '}\n {separator}\n {' '}\n</span>);\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<IProductRefinerHierarchy[]> {\n return getProductSearchRefinersAsync({ callerContext: ctx, queryResultSettings }, searchCriteria).then((productRefiners: ProductRefiner[]) => {\n if (!productRefiners) {\n ctx.trace('[getRefinersByCriteriaAction] returned no refiners');\n return <IProductRefinerHierarchy[]>[];\n }\n\n const result = (productRefiners || []).map((productRefiner: ProductRefiner) => <IProductRefinerHierarchy>productRefiner);\n\n if (result.length === 0) {\n ctx.trace('[getRefinersByCriteriaAction] returned no IProductRefinerHierarchy objects');\n return <IProductRefinerHierarchy[]>[];\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 { 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 * 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<IProductRefinerHierarchy[]> {\n let searchProductId;\n if (input.pageType === 'Category') {\n if (input.category) {\n return getProductRefinerHierarchy(\n {\n CategoryIds: [input.category],\n Context: {\n ChannelId: input.apiSettings.channelId,\n CatalogId: input.apiSettings.catalogId\n }\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.apiSettings.catalogId\n }\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.apiSettings.catalogId\n },\n RecommendationListId: searchObject.Recommendation,\n Ids: [searchProductId || 0]\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: <IAction<IProductRefinerHierarchy[]>>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 MsDyn365, {\n createObservableDataAction,\n IAction,\n IActionContext,\n IActionInput,\n ICreateActionContext\n} from '@msdyn365-commerce/core';\nimport { AsyncResult, ProductSearchCriteria, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\nimport { generateProductImageUrl } 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 public getCacheObjectType = () => 'FullProductSearchResult';\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\nexport interface IFullProductsSearchResultsWithCount {\n products: ProductSearchResult[];\n count: number;\n}\n\n/**\n * CreateInput function which creates and actionInput used to fetch products for a list page.\n * @param args\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 * Action function to fetch products for a list page.\n * @param input\n * @param ctx\n */\nasync function action(\n input: GetFullProductsByCollectionInput,\n ctx: IActionContext\n): Promise<IFullProductsSearchResultsWithCount> {\n let productSearchResults: ProductSearchResult[];\n let promise: AsyncResult<ProductSearchResult[]>;\n let searchProductId;\n const searchCriteriaInput: ProductSearchCriteria = {};\n searchCriteriaInput.Context = { ChannelId: ctx.requestContext.apiSettings.channelId, CatalogId: ctx.requestContext.apiSettings.catalogId };\n searchCriteriaInput.Refinement = input.refiners;\n searchCriteriaInput.IncludeAttributes = input.includeAttributes;\n searchCriteriaInput.SkipVariantExpansion = true;\n\n if (input.pageType === 'Category' || (ctx.requestContext.query && ctx.requestContext.query.categoryId)) {\n if (input.category) {\n searchCriteriaInput.CategoryIds = [input.category || 0];\n promise = searchByCriteriaAsync(\n {\n callerContext: ctx,\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 && (ctx.requestContext.query && ctx.requestContext.query.q)) {\n searchCriteriaInput.SearchCondition = input.searchText;\n promise = searchByCriteriaAsync(\n {\n callerContext: ctx,\n queryResultSettings: input.queryResultSettings\n },\n searchCriteriaInput\n );\n } else if (input.searchText && (ctx.requestContext.query && ctx.requestContext.query.productId && ctx.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 || 0];\n promise = searchByCriteriaAsync(\n {\n callerContext: ctx,\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 productSearchResults = await promise;\n\n const mappedProducts = productSearchResults.map(productSearchResult => {\n const newImageUrl = generateProductImageUrl(\n productSearchResult,\n ctx.requestContext.apiSettings\n );\n\n if (newImageUrl) {\n productSearchResult.PrimaryImageUrl = newImageUrl;\n }\n\n return (productSearchResult);\n });\n\n // Update ListPageState For SSR\n if (!MsDyn365.isBrowser) {\n ctx.update(new ListPageStateInput(), { totalProductCount: promise.metadata.count || 0, activeFilters: input.refiners });\n\n }\n\n return {\n products: mappedProducts,\n count: promise.metadata.count || 0\n };\n}\n\nexport const actionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/search-result-container/get-full-products-by-collection',\n action: <IAction<IFullProductsSearchResultsWithCount>>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 { 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';\nimport { formatPrice } from './utilities';\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}\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}\n\n/**\n * RangeRefineItem component (controlled by RefineSubmenu).\n */\n@observer\nexport default class RangeRefineItem extends React.Component<IRangeRefineItemProps, IRangeRefineItemState> {\n private readonly _formattedPriceReverseLookup: Map<string, string> = new Map();\n\n private readonly minInput: React.RefObject<HTMLInputElement>;\n\n private readonly maxInput: React.RefObject<HTMLInputElement>;\n\n @computed get currencyCode(): string {\n return this.props.productRefinerValue.UnitText || '';\n }\n\n 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<HTMLInputElement>();\n this.maxInput = React.createRef<HTMLInputElement>();\n\n const { selectedRefinementCriterion } = this.props;\n const initialMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\n const initialMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\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 };\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 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 <form className='ms-refine-submenu__input-range-refiner' {...formAttrs}>\n <label className={minLabelClassName}>\n {refineItemCommonProps.minLabel}\n <input\n className={minInputClassName}\n onChange={this._changeMin}\n onFocus={this._changeMin}\n onBlur={this._finishChangeMin}\n value={formattedSelectedMin}\n ref={this.minInput}\n />\n </label>\n <label className={maxLabelClassName}>\n {refineItemCommonProps.maxLabel}\n <input\n className={maxInputClassName}\n placeholder={formattedSelectedMax ? undefined : refineItemCommonProps.placeholderTextMax}\n onChange={this._changeMax}\n onFocus={this._changeMax}\n onBlur={this._finishChangeMax}\n value={formattedSelectedMax}\n ref={this.maxInput}\n />\n </label>\n {validationErrorMin &&\n <span className='ms-refine-submenu__input-range-error-text refine-submenu__input-range-min-error-text'>\n {validationErrorMin}\n </span>}\n {validationErrorMax && validationErrorMin !== validationErrorMax &&\n <span className='ms-refine-submenu__input-range-error-text refine-submenu__input-range-max-error-text'>\n {validationErrorMax}\n </span>}\n </form>\n );\n }\n\n private _renderSlider(): JSX.Element | undefined {\n const { isDisabled, productRefinerValue, parentProductRefinerHierarchy, selectedRefinementCriterion } = this.props;\n const min = productRefinerValue.LeftValueBoundString;\n const max = productRefinerValue.RightValueBoundString;\n const selectedMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || productRefinerValue.LeftValueBoundString || '0';\n const selectedMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || productRefinerValue.RightValueBoundString || max;\n const sliderId = `slider_${parentProductRefinerHierarchy.RecordId}_${productRefinerValue.RefinerRecordId}`;\n const ariaAttributes = {\n 'aria-disabled': isDisabled\n };\n\n const minPrice = this._formatPrice(min);\n const maxPrice = this._formatPrice(max);\n const selectedMinPrice = this._formatPrice(selectedMin);\n const selectedMaxPrice = this._formatPrice(selectedMax);\n\n return (\n <Slider\n className='ms-refine-submenu__range-refiner'\n key={sliderId}\n id={sliderId}\n inForm={false}\n min={min && Number(min) || undefined}\n max={max && Number(max) || undefined}\n step={1}\n orientation='horizontal'\n labels={[\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 showLabels\n showTooltip\n sliderThumbs={[\n {\n id: `${sliderId}_slider_thumb_start`,\n value: selectedMin && Number(selectedMin) || 0,\n ariaLabel: `${this.props.minValueSliderThumbAriaLabel} ${this.currencyCode}`,\n ariaValueText: `${selectedMinPrice}`\n },\n {\n id: `${sliderId}_slider_thumb_end`,\n value: Number(selectedMax) || Number(maxPrice),\n ariaLabel: `${this.props.maxValueSliderThumbAriaLabel} ${this.currencyCode}`,\n ariaValueText: `${selectedMaxPrice}`\n }\n ]}\n onChangeEnd={this._onRangeUpdateEnd}\n onChange={debounce(this._onRangeUpdate, 500)}\n handleTooltipText={this._handleRangeTooltipText}\n {...ariaAttributes}\n />\n );\n }\n\n private _changeMin(event: React.FocusEvent<HTMLInputElement>): void {\n this._changeValue(event, 'Min');\n }\n\n private _changeMax(event: React.FocusEvent<HTMLInputElement>): void {\n this._changeValue(event, 'Max');\n }\n\n private _changeValue(event: React.FocusEvent<HTMLInputElement>, 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<HTMLInputElement>): 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<HTMLInputElement>): 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 locale = this.props.refineItemCommonProps.locale;\n const result = formatPrice(amount, this.currencyCode, locale, this.props.refineItemCommonProps.telemetry);\n\n if (amount !== undefined && !this._formattedPriceReverseLookup.has(result)) {\n this._formattedPriceReverseLookup.set(result, amount);\n }\n\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 * 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<ILink> = ({ text, className, href, ariaLabel }) => (<a className={className} href={href} aria-label={ariaLabel}>\n {' '}\n {text}\n {' '}\n</a>);\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 {\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<HTMLButtonElement> | 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<HTMLButtonElement> | undefined;\n onModalToggle(): void;\n}\n\nexport const ModalToggle: React.FC<IModalToggleProps> = (props: IModalToggleProps) => {\n const { text, onClick, ariaLabel, innerRef, id } = props;\n return (<button\n id={id} className='msc-button' aria-label={ariaLabel}\n onClick={onClick} ref={innerRef}>\n {text}\n </button>);\n};\n\nexport const SearchResultModal = (props: ISearchResultModalProps): ISearchResultModalViewProps => {\n return {\n modal: modalNode(props),\n modalHeader: modalHeaderNode(props),\n modalFooter: modalFooterNode(props),\n modalBody: <ModalBody className='msc-review-modal-body' />\n };\n};\n\nconst modalNode = (props: ISearchResultModalProps) => {\n return (\n <Modal\n autoFocus\n applicationNode='renderPage'\n returnFocusRef={props.returnRef}\n isOpen={props.isOpen}\n toggle={props.onModalToggle}\n className='msc-search-result-modal'\n zIndex={1050}\n />\n );\n};\n\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\n return (\n <ModalHeader toggle={props.onModalToggle}>\n {props.resources.modalTitle}\n </ModalHeader>\n );\n};\n\nconst modalFooterNode = (props: ISearchResultModalProps) => {\n return (\n <ModalFooter>\n <Button onClick={props.onModalToggle} className='ms-sort-and-filter-modal-close'>\n {props.resources.modalCloseButtonText}\n </Button>\n </ModalFooter>\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 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 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<ListPageState> {\n return new ListPageState();\n}\n\n/**\n * Create new input for create action.\n * @param inputData\n */\nexport const createListPageInput = (\n inputData: ICreateActionContext<IGeneric<IAny>>\n): IActionInput => {\n return new ListPageStateInput();\n};\n\n/**\n * ListPageState - create action.\n */\nexport default createObservableDataAction<ListPageState>({\n action: <IAction<ListPageState>>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 { 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<IFeatureSearchResultItem> = ({\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 <div className='ms-feature-search-result__item'>\n <a\n href={productUrl} onClick={onTelemetryClick(telemetryContent!, payLoad, product.Name!)} {...attribute}\n aria-label={product.Name}>\n <div className='msc-feature-search-result__item__image'>\n {renderProductPlacementImage(\n imageSettings, context.request.gridSettings, product.PrimaryImageUrl,\n product.Name, fallbackImage, context.actionContext.requestContext)}\n </div>\n </a>\n <div className='msc-feature-search-result__item__detail'>\n <p className='msc-feature-search-result__item__heading'>\n {heading}\n </p>\n {renderProductTitle(product?.Name)}\n </div>\n </div>\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 <Image\n {...img} {...imageProps} loadFailureBehavior='empty'\n requestContext={context}\n />\n );\n}\n\nfunction renderProductTitle(title?: string): JSX.Element | null {\n return (<h1 className='msc-feature-search-result__item__product-title'>\n {title}\n </h1>);\n}\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 const 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 { 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}\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 if (!suggestions) {\n return undefined;\n }\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 } = props;\n\n const splitValue = 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(item.Value ? item.Value : '', 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 const route = searchPageURL || '';\n const urlPath = `${route}${!route.includes('?') ? '?' : '&'}${searchQsp}=${searchText}`;\n const categoryRefiners =\n searchRefiners &&\n searchRefiners.find(refiners => {\n return refiners.KeyName === 'Category';\n });\n const refiner =\n categoryRefiners &&\n categoryRefiners.Values &&\n categoryRefiners.Values.find(item => {\n return item.RefinerRecordId === Number.parseInt(id, 10);\n });\n\n const encodedRefiner = refiner && encodeURIComponent(JSON.stringify(compressRefiners([refiner])));\n\n return encodedRefiner ? `${urlPath}&refiners=${encodedRefiner}` : urlPath;\n};\n\nconst _getHighlightedText = (suggestion: string, hitPrefix: string, hitSuffix: string): JSX.Element => {\n let formattedText = suggestion\n .replace(new RegExp(`[${hitPrefix}]`, 'gi'), '<strong>')\n .replace(new RegExp(`[${hitSuffix}]`, 'gi'), '</strong>');\n formattedText = formattedText.split('|').pop() || '';\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\nexport const FormComponent = (props: ISearchFormProps): ISearchFormViewProps => {\n const {\n searchQsp,\n searchPlaceholder,\n hideSearchLabel,\n isSearchFormExpanded,\n searchTextInput,\n handleInputChange,\n maxChars,\n disableSubmitSearch,\n handleCancelSearchChange,\n query,\n ariaLabelCancel,\n ariaLabelSearch,\n ariaLabelSubmit\n } = props;\n\n const onInputChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n handleInputChange(e.target.value || '');\n };\n\n const inputNode = !hideSearchLabel ? (\n <input\n className='ms-search__form-control'\n type='text'\n aria-label={isSearchFormExpanded ? 'Search expanded' : 'Search collapsed'}\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 { 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 if (!suggestions) {\n return undefined;\n }\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 const route = searchPageURL || '';\n return formattedLink && formattedLink.length > 0 ? `${route}${!route.includes('?') ? '?' : '&'}${searchQsp}=${formattedLink}` : route;\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 if (!suggestions) {\n return undefined;\n }\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),\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) => {\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\n return {\n className: 'msc-autoSuggest__productResults-item',\n tag: 'a' as NodeTag,\n 'aria-label': ariaLabel,\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 { getUrlSync } from '@msdyn365-commerce/core';\nimport { ProductRefiner } from '@msdyn365-commerce/retail-proxy';\nimport { getProductSearchRefinersAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\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 * 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}\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}\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 };\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 render(): JSX.Element {\n const {\n context,\n resources: { searchtext, searchLabelArialLabel, cancelBtnAriaLabel, searchBtnAriaLabel, submitBtnAriaLabel },\n config: { hideSearchLabel, disableSubmitSearch, searchplaceholderText, className = '' }\n } = this.props;\n\n const {\n isSearchFormExpanded,\n searchText,\n searchKeywordSuggestClass,\n searchProductSuggestClass,\n searchCategorySuggestClass,\n suggestions,\n searchRefiners\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 isSearchFormExpanded,\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 && keywordSuggestions && keywordSuggestions.length > 0 ? 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 && productSuggestions && productSuggestions.length > 0 ? 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 && categorySuggestions && categorySuggestions.length > 0 ? 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 }) : undefined,\n callbacks: {\n handleCancelSearchChange: this._handleCancelSearchChange\n },\n isSearchFormExpanded: this.state.isSearchFormExpanded\n };\n\n return this.props.renderView(viewProps) as React.ReactElement;\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 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) });\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 (route && route.length > 0) {\n return query && query.length > 0 ? `${route}${!route.includes('?') ? '?' : '&'}${qsp}=${query}` : route;\n }\n return '';\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"],"sourceRoot":""}