{"version":3,"sources":["webpack:///./src/modules/smwe-product-collection/smwe-product-collection.props.autogenerated.ts?697c","webpack:///./src/Utilities/single-slide-carousel.tsx?f065","webpack:///./src/modules/smwe-product-collection/smwe-product-collection.tsx?f93a","webpack:///./src/modules/elicit-subscriptions/components/modal.tsx?345a","webpack:///./src/modules/elicit-subscriptions/components/refine-item.tsx?9653","webpack:///./src/modules/smwe-search-result-container/components/title.tsx?b71f","webpack:///./src/modules/smwe-search-result-container/components/utilities.ts?6641","webpack:///./src/modules/elicit-subscriptions/components/link.tsx?679e","webpack:///./src/modules/smwe-search-result-container/components/range-refine-item.tsx?65bc","webpack:///./src/modules/elicit-subscriptions/components/utilities.ts?5532","webpack:///./src/modules/elicit-subscriptions/elicit-subscriptions.tsx?b039","webpack:///./src/themes/fth/views/smwe-search-result-container.view.tsx?db42","webpack:///./src/modules/smwe-search-result-container/components/modal.tsx?afe2","webpack:///./src/Utilities/product-lightbox.tsx?a7c0","webpack:///./src/components/product.component.tsx?d9d6","webpack:///./src/modules/elicit-subscriptions/components/index.ts?cb68","webpack:///./src/modules/elicit-subscriptions/components/error-message.tsx?eba5","webpack:///./src/modules/elicit-subscriptions/components/choice-summary.tsx?41db","webpack:///./src/modules/elicit-subscriptions/components/refine-submenu.tsx?dbe0","webpack:///./src/modules/smwe-search-result-container/components/refine-pulldown.tsx?8e80","webpack:///./src/modules/smwe-search-result-container/components/smwe-pagination.tsx?1a37","webpack:///./src/modules/smwe-search-result-container/smwe-search-result-container.tsx?8098","webpack:///./src/Utilities/refiners.ts?59e9","webpack:///./src/dataActions/search-result-container/index.ts?e779","webpack:///./src/modules/smwe-search-result-container/components/refine-item.tsx?893c","webpack:///./src/modules/elicit-subscriptions/components/product-search-result-items.tsx?3d57","webpack:///./src/themes/patzhall/views/smwe-search-result-container.view.tsx?4245","webpack:///./src/modules/smwe-search-result-container/components/index.ts?6cb7","webpack:///./src/themes/blend/views/smwe-search-result-container.view.tsx?17e4","webpack:///./src/modules/smwe-search-result-container/components/link.tsx?3108","webpack:///./src/modules/elicit-subscriptions/components/separator.tsx?501c","webpack:///./src/modules/elicit-subscriptions/elicit-subscriptions.view.tsx?e3eb","webpack:///./src/modules/smwe-search-result-container/components/separator.tsx?bafa","webpack:///./src/Utilities/event-bus.tsx?eb5b","webpack:///./src/modules/elicit-subscriptions/components/title.tsx?f8cb","webpack:///./src/themes/emp/views/smwe-search-result-container.view.tsx?c361","webpack:///./src/modules/smwe-search-result-container/smwe-search-result-container.view.tsx?6069","webpack:///./src/themes/conn-creek/views/smwe-search-result-container.view.tsx?3355","webpack:///./src/modules/smwe-search-result-container/components/choice-summary.tsx?0632","webpack:///./src/themes/elicit/views/smwe-search-result-container.view.tsx?4578","webpack:///./src/modules/smwe-search-result-container/components/product-search-result-items.tsx?265d","webpack:///./src/modules/smwe-product-collection/smwe-product-collection.view.tsx?4b91","webpack:///./src/modules/elicit-subscriptions/components/range-refine-item.tsx?f6b4","webpack:///./src/modules/smwe-search-result-container/components/error-message.tsx?6625","webpack:///./src/modules/smwe-search-result-container/components/refine-submenu.tsx?b934"],"names":["layout","HeadingTag","SingleSlideCarousel","React","constructor","props","super","carouselSize","slideSize","itemSize","_onResized","this","_onCarouselResized","_nextSlide","bind","_previousSlide","_handleTouchStart","_handleTouchEnd","_onFocus","state","showPrevious","showNext","offset","activeItem","ref","slideRef","itemRef","direction","id","parentId","scrollThreshold","undefined","touchScrollThreshold","componentDidUpdate","carousel","current","slide","item","_setSizes","_updateFlippers","componentDidMount","vertical","resizeThrottledEventHandler","window","addThrottledEvent","componentWillUnmount","removeEventListener","render","isVert","slidePositionStyle","modifiedChildren","_getClonedChildren","carouselClass","carouselSlideClass","overflowClass","previousFlipperGlyph","nextFlipperGlyph","previousFlipperClassName","nextFlipperClassName","disableClassName","className","onTouchStart","onTouchEnd","Flipper","tabIndex","glyphProps","onClick","flipperPrevLabel","disabled","displayTooltip","length","style","role","useTabList","flipperNextLabel","map","children","child","index","castChild","verticalItemsSelector","itemsSelector","onFocus","_moveSingleSlide","evt","touches","scrollStart","screenY","screenX","changedTouches","delta","_setActiveItem","setState","Math","abs","round","next","currentOffset","parseInt","getCSS","maxScrollCount","floor","directionModifier","isNaN","max","maxScrollDistance","distanceToEdge","scrollHeight","scrollWidth","_calculateCarouselSize","carouselStyle","getComputedStyle","padding","parseFloat","paddingTop","paddingBottom","paddingLeft","paddingRight","clientHeight","clientWidth","_canScrollPrevious","_canScrollNext","_scrollItemIntoView","offsetTop","offsetLeft","updateOffset","left","top","setTimeout","parentElement","scrollTop","scrollLeft","event","target","currentTarget","min","ProductCollection","_getProduct","product","imageSettings","showPrice","config","addToCart","resources","passedProps","categoryHierarchy","availibity","productAvailability","find","ProductId","RecordId","clubPrice","clubPricing","showQuantityAsDropdown","ProductContainer","tag","key","productComponent","ProductCard","context","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","format","AverageRating","typeName","data","parentProps","addToCartText","addToCartMessage","giftCardText","cart","displayQuantitySlider","availability","products","productCollection","_getClubPricing","_getProductavailabilty","impressions","attributes","CommerceAttributesParser","getParsedAttributes","AttributeValues","publish","list","category","heading","text","isCarousel","headingComponent","Heading","headingTag","productCollectionViewProps","SingleSlideCarouselComponentProps","flipperPrevious","flipperNext","ProductCollectionContainer","moduleProps","classnames","GridComponentProps","renderView","projectDomain","ChannelId","request","apiSettings","channelId","CatalogId","catalogId","affiliations","app","affiliationId","AffiliationId","productIds","forEach","push","clubPricingAll","getActivePricesAsync","callerContext","actionContext","Date","formattedResponse","getEstimatedAvailabilityAsync","ProductIds","DefaultWarehouseOnly","ProductWarehouseInventoryAvailabilities","AvailableQuantity","PhysicalAvailable","ExtensionProperties","ModalToggle","ariaLabel","innerRef","SearchResultModal","modal","modalNode","modalHeader","modalHeaderNode","modalFooter","modalFooterNode","modalBody","ModalBody","Modal","autoFocus","applicationNode","returnFocusRef","returnRef","isOpen","toggle","onModalToggle","zIndex","ModalHeader","modalTitle","ModalFooter","Button","modalCloseButtonText","RefineItem","_onClick","e","preventDefault","parentProductRefinerHierarchy","productRefinerValue","selectedRefinementCriterion","onToggle","isSelecting","anchorType","focus","isChecked","isDisabled","refineItemCommonProps","attrs","telemetry","error","LeftValueBoundString","warning","JSON","stringify","isSingleSelect","RefinerTypeValue","ProductRefinerTypeValue","Single","itemTypeClassName","inputType","SourceValue","ProductRefinerSource","Rating","KeyName","LeftValueBoundLocalizedString","href","_getRefinerUrl","RatingComponent","avgRating","ratingCount","hideCount","readOnly","moduleId","moduleTypeName","Count","urlBuilder","Title","ProductRefinerValueDataTypeValue","findMatchingRefinementCriterion","refinementCriteria","refinementCriterion","isMatchingRefinementCriterion","RefinerRecordId","RefinerSourceValue","DataTypeValue","Range","getUpdatedRefinementCriteria","itemToggleNotification","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","selectedCriterion","rangeStart","RightValueBoundString","rangeEnd","List","Boolean","Values","matchingIndex","findIndex","criterion","splice","formatPrice","amount","currency","locale","trace","priceAmount","Number","result","Intl","NumberFormat","currencyDisplay","minimumFractionDigits","Link","RangeRefineItem","_formattedPriceReverseLookup","Map","_onRangeUpdate","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","minInput","maxInput","initialMin","initialMax","validationErrorMin","validationErrorMax","selectedMin","selectedMax","touchedMin","touchedMax","UnitText","rangeType","_renderInputFields","_renderSlider","formAttrs","rangeNameFormat","replace","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onChange","onBlur","value","maxLabel","placeholder","placeholderTextMax","sliderId","ariaAttributes","minPrice","_formatPrice","maxPrice","selectedMinPrice","selectedMaxPrice","Slider","Object","inForm","step","orientation","labels","labelId","labelString","labelPositioning","showLabels","showTooltip","sliderThumbs","minValueSliderThumbAriaLabel","currencyCode","ariaValueText","maxValueSliderThumbAriaLabel","onChangeEnd","debounce","handleTooltipText","_changeValue","selectedKey","touchedKey","_getInputWithoutFormatting","selectedMinValue","minTouched","maxNum","validationErrorNaN","_focus","_validateRange","selectedMaxValue","maxTouched","minNum","selected","touched","validationError","validationErrorRange","has","set","input","inputAsNum","get","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","element","document","getElementById","tooltip","__decorate","computed","observer","SmweSearchResultContainer","sortByDropdownOptions","showSortByDropdown","_pageType","urlTokens","pageType","_refinersFiltered","_initialProductResultCount","usePNGImageSetting","viewports","modifiedViewports","xs","q","sm","md","lg","xl","_addSortByDropdownOptions","showSortingByRelevance","sortOptions","sortByOptionRelevanceDesc","showSortingByName","sortByOptionNameAsc","sortByOptionNameDesc","showSortingByPrice","sortByOptionPriceAsc","sortByOptionPriceDesc","showSortingByRating","sortByOptionRatingDesc","_getSearchResultModal","modalIsOpen","_modalToggleRef","_toggleModal","_getCollectionTitle","collectionTitle","query","SmweSearchResultContainer_1","getFriendlyName","NameTranslations","Name","productCountNumber","productCountText","listPageState","totalProductCount","count","numberOfProducts","oneProduct","TitleContainer","title","titlePrefix","searchTextPrefix","titleText","titleCount","_getCategoryHierarchy","CategoryHierarchyContainer","categoryHierarchyList","categoryLinkAriaLabel","Url","categoryHierarchySeparator","Separator","separator","_getSortingDropDown","activeDropdown","_getCurrentlySelectedOption","sortingState","selectedSortByOption","SortingContainer","sortByDropDown","LabeledDropdown","labelClassname","labelText","sortByDropdownLabel","dropdownId","dropdownClassname","toggleColor","dropdownOptions","selectedOption","onSelectOption","_updateSortByDropdown","_sortAndFilterContainerRef","_getPagination","fullUrl","getCurrentUrl","itemsPerPage","skipCount","currentPageNumber","skip","totalItems","previousText","nextText","totalActiveProducts","activeProducts","UncontrolledPagination","paginationAriaLabel","url","qsp","items","startingItem","previousAriaLabel","nextAriaLabel","_getRefineMenu","tempRangeTypeTODO","inputRange","validRefiners","refiners","filter","refiner","activeRefiners","activeFilters","RefineMenuContainer","RefinerSectionContainer","productRefinerHierarchy","RefineSubmenu","highestLevelRefinerText","highestLevelItem","selectedRefinerValues","_refineItemCommonProps","refinerMinimizeText","refinerExpandText","minimizedRefiners","onUpdateRefiners","_onUpdateRefiners","_buildRefinerUrl","isExpandedOnInitialLoad","collapseRefiners","_getChoiceSummary","selectedRefiners","ChoiceSummary","classNames","clearAllText","label","choiceSummaryLabel","selectedChoices","refinerHierarchy","choiceFormat","choiceRangeValueFormat","onChoiceClicked","_onChoiceClicked","_buildRefinerUrlForChoiceSummary","choiceAriaLabel","notification","requestContext","history","pushState","buildListPageUrl","_getSortColumnFromSelectedOption","transaction","sortingCritera","Columns","option","searchConfiguration","mappedConfiguration","sortColumn","sortCriteria","activeSortColumn","parseQueryParam","activeMappedConfig","mappedSearchConfig","ColumnName","IsDescending","dropdownOption","newRefinementCriteria","clearAll","dropdownElementId","dropdownElement","selectedChoice","choiceClicked","selectedRefiner","isClearAll","_viewport","device","Type","_updateViewport","checkoutState","modifiedImageSettings","pending","validationErrorNotNumber","validationErrorNotRange","reaction","CartLines","then","querySorting","sorting","parse","decodeURIComponent","pageSize","hydrateRefinersFromUrl","filterInvalidCategories","refinerRemappers","_emitImpressionEvent","GetFullProductsByCollectionInput","Paging","Top","Skip","Sorting","itemId","getCollectionProducts","productResults","catch","exception","nameTranslations","nameTranslation","Language","toLowerCase","Text","addEventListener","paragraph","showPagination","errorText","resultCategoryNotFoundText","resultSearchNotFoundText","productsComponent","ProductSearchResultItems","disableQuantitySlider","_shouldDisableQuantityAddition","maxAdditionLimit","_subscriptionQuantityLimit","moduleType","categoryDescription","_getCategoryDescription","searchResultContainerViewProps","TitleViewProps","refineMenu","SearchResultContainer","sortByOptions","showSortBy","pagination","ProductsContainer","ProductSectionContainer","CategoryNavContainer","RefineAndProductSectionContainer","choiceSummary","modalToggle","searchResultModal","isMobile","errorMessage","ErrorMessage","_getViewport","MsDyn365","isBrowser","innerWidth","gridSettings","w","RichTextComponent","quantityLimit","filteredLines","filterCartLines","checkoutCart","subscriptionLines","line","Quantity","observable","createSearchResultModal","modalProps","createModalBody","renderSort","renderRefiner","Node","submenu","renderRefinerPulldown","pulldownText","activeRefinersText","getActiveRefinersText","dynamicPulldownText","getPulldownText","togglePulldown","buttonText","buttonElement","spanElement","innerText","expanded","getAttribute","classList","pulldownElement","contains","setAttribute","formatedActiveRefiners","substring","renderTitle","showResultPrefix","categoryNamePrefix","renderTitleCount","SearchResultContainerView","showRefiners","showResultCount","Module","pulldownRefiners","ProductLightbox","onMessage","async","isTrusted","origin","iframeSrcObj","URL","iframeSrc","cartInput","GlobalStateInput","BaseCartState","newCart","getCartState","update","refreshCart","_closeModal","prevState","_openModal","lightboxClassName","iframeClassName","iframeId","_launchLightboxButton","fade","horizontalPosition","verticalPosition","src","width","height","qtyAddedToCart","renderAttribute","attribute","TextValue","renderPrice","price","toFixed","ProductComponent","msdyn365Commerce","createComponentOverride","component","savingsText","subscriptionBtnText","showStarRating","launchLightboxButtonText","productLightboxHref","productLightboxWidth","productLightboxHeight","productLightboxClassName","productLightboxIframeClassName","cardBanner","recordId","productLightboxProps","domainUrl","urlParts","split","indexOf","_getEndpoint","requestUrl","toString","tastingNotes","appellation","banner","productType","imageProductClass","productUrl","getProductPageUrlSync","isGiftCard","ItemId","imageUrl","PrimaryImageUrl","giftCardImage","altText","img","imageProps","Image","loadFailureBehavior","renderProductPlacementImage","Price","AcclaimRatingsDisplay","productID","numberToShow","showReviewer","showDate","renderAcclaim","totalRatings","numRatings","renderRating","TotalRatings","Fragment","renderProductLightboxButton","ProductComponentWrapper","Component","_generateMenu","quantity","nodes","i","_generateQuantityControl","productId","maxQuantity","currentQuantity","showAsDropdown","_onQuantityChange","type","disable","cartMessage","_decreaseCartQuantity","_increaseCartQuantity","_onClickAddToCart","_onClickAddToSubscription","addToCartSubId","bus","subscribe","finishAddToCartSubId","unsubscribe","bottleSize","outOfStock","outOfStockThreshold","quantityControl","CustomerContextualPrice","hidden","htmlFor","_isAdditionInvalid","cartQty","TotalItems","CartUtilities","elicitAddItemIdToCart","onAddToCartAction","mixedCart","IsGiftCardLine","DeliveryMode","elicitAddSubscriptionItemIdToCart","onSubscribeAction","cartQuantity","countCartLineAmount","LoadBus","closeButtonGlyph","stopPropagation","_getSelectedRefinerChoice","itemClicked","nextItemToFocus","nextSibling","_getKeyForRefinerValue","selectedRefinersMap","listItemProps","overallFormat","rangeFormat","refinerValueName","refinerName","parent","hierarchy","RangeInput","trim","isMinimizedRefiner","_onToggleItem","_onToggleSubmenu","_expandCategoryRefiner","isExpanded","minimizedRefinersList","some","keyName","toLocaleLowerCase","_renderChildItems","Collapse","timeout","_renderRange","_renderSingleMultiSelect","listItems","_getSortedValueList","sortedList","sort","nextOption","curOption","curOptionName","nextOptionName","localeCompare","dividedList","options","topLevel","minimizedElement","textContent","RefinePulldown","_handleClickOutsidePulldown","pulldown","_getPulldownText","_getActiveRefinersText","body","SMWEPagination","activePage","maxPages","ceil","qsps","splitUrl","secondSplit","hash","parsedQsps","qspPair","baseUrl","listClassName","cssModule","size","Tag","listTag","ListTag","activeQsp","paginationClasses","mapToCssModules","listpaginationClasses","_generatePageLinks","_generateUrl","page","keys","qspUrl","_generatePaginationArrow","tooltipId","nextId","prevId","ariaDescribedBy","nextAreaDescribed","prevAreaDescribed","placement","PaginationItem","PaginationLink","previous","telemetryContent","UncontrolledTooltip","_generatePaginationItem","active","_generateEllipse","leftDistance","rightDistance","leftEllipse","pagesDisplayed","rightEllipse","pages","displayedPagesOnLeft","startingIndex","endIndex","subMenus","pulldownButtonText","remappers","categoryRemapper","remapRecord","originalName","categoryRefinerName","newName","categoryRefiners","entry","categoryIDs","Children","elicitSubscriptions_buyboxSubscriptionBtnTxt","addToBoxMessagePlp","SmweSearchResultContainerView","EventBusLoader","_buses","getBus","busNamespace","BusLoader","deleteBus","purge","_subscriptions","subName","onPublish","IdGenerator","_readyForDeletion","_purgeById","args","idValue","Loader","eventNamespace","CHILD_COMP","prototype","addToCartTextPlp","addToCartMessagePlp","_renderCarousel","carouselContainer","_renderProduct","_renderGrid","gridContainer","ProductCollectionView"],"mappings":"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","file":"static/js/25.34c49a2d8c908b3bc3ef.chunk.js","sourcesContent":["/**\r\n * Copyright (c) Microsoft Corporation\r\n * All rights reserved. See License.txt in the project root for license information.\r\n * ISmweProductCollection contentModule Interface Properties\r\n * THIS FILE IS AUTO-GENERATED - MANUAL MODIFICATIONS WILL BE LOST\r\n */\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\n\r\nexport const enum layout {\r\n carousel = 'carousel',\r\n grid = 'grid'\r\n}\r\n\r\nexport interface ISmweProductCollectionConfig extends Msdyn365.IModuleConfig {\r\n addToCart?: boolean;\r\n productCollection: Msdyn365.IProductList;\r\n heading?: IHeadingData;\r\n layout?: layout;\r\n imageSettings?: Msdyn365.IImageSettings;\r\n className?: string;\r\n showPrice?: boolean;\r\n showStarRating?: boolean;\r\n launchLightboxButtonText?: string;\r\n productLightboxHref: string;\r\n productLightboxWidth: number;\r\n productLightboxHeight: number;\r\n productLightboxClassName?: string;\r\n productLightboxIframeClassName?: string;\r\n cardBanner?: string;\r\n showQuantityAsDropdown?: boolean;\r\n}\r\n\r\nexport interface ISmweProductCollectionResources {\r\n priceFree: string;\r\n ratingAriaLabel: string;\r\n flipperNext: string;\r\n flipperPrevious: string;\r\n originalPriceText: string;\r\n currentPriceText: string;\r\n addToCartText: string;\r\n addToCartMessage: string;\r\n giftCardText: string;\r\n}\r\n\r\nexport const enum HeadingTag {\r\n h1 = 'h1',\r\n h2 = 'h2',\r\n h3 = 'h3',\r\n h4 = 'h4',\r\n h5 = 'h5',\r\n h6 = 'h6'\r\n}\r\n\r\nexport interface IHeadingData {\r\n text: string;\r\n tag?: HeadingTag;\r\n}\r\n\r\nexport interface ISmweProductCollectionProps extends Msdyn365.IModule {\r\n resources: ISmweProductCollectionResources;\r\n config: ISmweProductCollectionConfig;\r\n}\r\n","import { addThrottledEvent, Flipper, getCSS } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\ninterface ISingleSlideCarouselState {\r\n showPrevious: boolean;\r\n showNext: boolean;\r\n offset: number;\r\n activeItem: number;\r\n}\r\n\r\ninterface ISingleSlideCarouselProps {\r\n flipperNextLabel?: string;\r\n flipperPrevLabel?: string;\r\n vertical?: boolean;\r\n touchScrollThreshold?: number;\r\n parentId?: string;\r\n useTabList?: boolean;\r\n}\r\n\r\n/**\r\n * SingleSlideCarousel\r\n */\r\nexport default class SingleSlideCarousel extends React.PureComponent {\r\n private static itemsSelector: string = 'msc-ss-carousel-item';\r\n private static verticalItemsSelector: string = 'msc-ss-carousel-vert-item';\r\n private direction: string;\r\n private item: HTMLElement | undefined;\r\n private slide: HTMLElement | undefined;\r\n private carousel: HTMLElement | undefined;\r\n private carouselSize: number = 0;\r\n private slideSize: number = 0;\r\n private itemSize: number = 0;\r\n private resizeThrottledEventHandler?: (event: Event) => void;\r\n private ref: React.RefObject;\r\n private slideRef: React.RefObject;\r\n private itemRef: React.RefObject;\r\n private id: string;\r\n private scrollStart: number | undefined;\r\n private scrollThreshold: number;\r\n\r\n constructor (props: ISingleSlideCarouselProps) {\r\n super(props);\r\n this._nextSlide = this._nextSlide.bind(this);\r\n this._previousSlide = this._previousSlide.bind(this);\r\n this._handleTouchStart = this._handleTouchStart.bind(this);\r\n this._handleTouchEnd = this._handleTouchEnd.bind(this);\r\n this._onFocus = this._onFocus.bind(this);\r\n this._onResized = this._onResized.bind(this);\r\n this.state = { showPrevious: false, showNext: false, offset: 0, activeItem: 0 };\r\n this.ref = React.createRef();\r\n this.slideRef = React.createRef();\r\n this.itemRef = React.createRef();\r\n this.direction = 'left';\r\n this.id = props.parentId || '';\r\n this.scrollThreshold = this.props.touchScrollThreshold !== undefined ? this.props.touchScrollThreshold : 100;\r\n }\r\n\r\n public componentDidUpdate (): void {\r\n this.carousel = this.ref.current!;\r\n this.slide = this.slideRef.current!;\r\n this.item = this.itemRef.current!;\r\n this._setSizes();\r\n this._updateFlippers(this.state.offset);\r\n }\r\n\r\n public componentDidMount (): void {\r\n this.direction = this.props.vertical ? 'top' : 'left';\r\n this.carousel = this.ref.current!;\r\n this.slide = this.slideRef.current!;\r\n this.item = this.itemRef.current!;\r\n this._setSizes();\r\n this.resizeThrottledEventHandler =\r\n window && addThrottledEvent(window, 'resize', this._onResized as EventListener);\r\n this._updateFlippers(0);\r\n }\r\n\r\n public componentWillUnmount (): void {\r\n window && window.removeEventListener('resize', this.resizeThrottledEventHandler!, false);\r\n }\r\n\r\n public render (): JSX.Element {\r\n const isVert: boolean = this.props.vertical === true;\r\n const slidePositionStyle = {} as React.CSSProperties;\r\n const modifiedChildren = this._getClonedChildren(isVert);\r\n slidePositionStyle[this.direction] = `${this.state.offset}px`;\r\n const carouselClass = (isVert) ? 'msc-ss-carousel-vert' : 'msc-ss-carousel';\r\n const carouselSlideClass = (isVert) ? 'msc-ss-carousel-vert-slide' : 'msc-ss-carousel-slide';\r\n const overflowClass = (isVert) ? 'msc-ss-carousel-vert-strip' : 'msc-ss-carousel-strip';\r\n const previousFlipperGlyph = (isVert) ? 'msi-chevron-up' : 'msi-chevron-left';\r\n const nextFlipperGlyph = (isVert) ? 'msi-chevron-down' : 'msi-chevron-right';\r\n const previousFlipperClassName = (isVert) ? 'msc-ss-carousel-vert__flipper' : 'msc-ss-carousel__flipper';\r\n const nextFlipperClassName = (isVert) ? 'msc-ss-carousel-vert__flipper msc-ss-carousel-vert__flipper--next' : 'msc-ss-carousel__flipper msc-ss-carousel__flipper--next';\r\n const disableClassName = !this.state.showPrevious || !this.state.showNext ? 'disabled' : null;\r\n return (\r\n \r\n 0 ? true : false}\r\n />\r\n
\r\n
    \r\n {modifiedChildren}\r\n
\r\n
\r\n 0 ? true : false}\r\n />\r\n \r\n );\r\n }\r\n\r\n private _getClonedChildren (isVert: boolean): React.DetailedReactHTMLElement, HTMLElement>[] {\r\n return React.Children.map(this.props.children, (child: React.ReactNode, index: number) => {\r\n const castChild = (child as React.ReactChild) as React.ReactElement;\r\n if (index === 1) {\r\n return React.cloneElement(castChild, {\r\n className: `${isVert ? SingleSlideCarousel.verticalItemsSelector : SingleSlideCarousel.itemsSelector} ${(this.state.activeItem) === index ? 'active' : ''} ${castChild.props.className}`,\r\n // @ts-ignore\r\n ref: this.itemRef,\r\n onFocus: this._onFocus\r\n });\r\n }\r\n return React.cloneElement(castChild, {\r\n className: `${isVert ? SingleSlideCarousel.verticalItemsSelector : SingleSlideCarousel.itemsSelector} ${(this.state.activeItem) === index ? 'active' : ''} ${castChild.props.className}`,\r\n // @ts-ignore\r\n onFocus: this._onFocus\r\n });\r\n });\r\n }\r\n\r\n private _nextSlide (): void {\r\n this._moveSingleSlide(true);\r\n }\r\n\r\n private _previousSlide (): void {\r\n this._moveSingleSlide(false);\r\n }\r\n\r\n private _handleTouchStart(evt: React.TouchEvent): void {\r\n if (evt.touches.length === 0) {\r\n this.scrollStart = undefined;\r\n } else {\r\n this.scrollStart = this.props.vertical === true ? evt.touches[0].screenY : evt.touches[0].screenX;\r\n }\r\n }\r\n\r\n private _handleTouchEnd(evt: React.TouchEvent): void {\r\n if (evt.changedTouches.length > 0 && this.scrollStart !== undefined) {\r\n const newTarget: number = this.props.vertical === true ? evt.changedTouches[0].screenY : evt.changedTouches[0].screenX;\r\n\r\n const delta = newTarget - this.scrollStart;\r\n\r\n if (delta > this.scrollThreshold) {\r\n this._previousSlide();\r\n }\r\n\r\n if (delta < -this.scrollThreshold) {\r\n this._nextSlide();\r\n }\r\n }\r\n\r\n this.scrollStart = undefined;\r\n\r\n return;\r\n }\r\n\r\n private _setActiveItem (offset: number): void {\r\n if (offset === 0) {\r\n this.setState({ activeItem: 0 });\r\n } else {\r\n this.setState({ activeItem: Math.abs(Math.round(offset / this.itemSize)) });\r\n }\r\n }\r\n\r\n private _moveSingleSlide (next: boolean): void {\r\n let currentOffset = parseInt(getCSS(this.slide!, this.direction), 10);\r\n const carouselSize = this.carouselSize;\r\n\r\n let maxScrollCount = Math.floor(carouselSize / (this.itemSize));\r\n const directionModifier = next ? -1 : 1;\r\n currentOffset = !isNaN(currentOffset) && typeof currentOffset === 'number' ? currentOffset : 0;\r\n\r\n if (maxScrollCount === 0) {\r\n maxScrollCount = 1;\r\n }\r\n\r\n maxScrollCount = carouselSize % (this.itemSize) === 0 ? maxScrollCount - 1 : maxScrollCount;\r\n maxScrollCount = Math.max(maxScrollCount, 1);\r\n const maxScrollDistance = maxScrollCount * (this.itemSize);\r\n\r\n let distanceToEdge = next ? this.slideSize - carouselSize + currentOffset : Math.abs(currentOffset);\r\n distanceToEdge = Math.max(0, distanceToEdge);\r\n\r\n const offset =\r\n maxScrollDistance <= distanceToEdge\r\n ? maxScrollDistance * directionModifier + currentOffset\r\n : distanceToEdge * directionModifier + currentOffset;\r\n\r\n this._setActiveItem(offset);\r\n this._updateFlippers(offset);\r\n }\r\n\r\n private _setSizes (): void {\r\n const item = this.item;\r\n if (!!item) {\r\n this.itemSize = this.props.vertical ? item.scrollHeight : item.scrollWidth;\r\n } else {\r\n this.itemSize = 0;\r\n }\r\n\r\n this.carouselSize = this._calculateCarouselSize();\r\n this.slideSize = this.slide ? (this.props.vertical ? this.slide.scrollHeight : this.slide.scrollWidth) : 0;\r\n }\r\n\r\n private _calculateCarouselSize (): number {\r\n if (!this.carousel) {\r\n return 0;\r\n }\r\n\r\n const carouselStyle = getComputedStyle(this.carousel);\r\n\r\n const padding = this.props.vertical ? parseFloat(carouselStyle.paddingTop || '') + parseFloat(carouselStyle.paddingBottom || '')\r\n : parseFloat(carouselStyle.paddingLeft || '') + parseFloat(carouselStyle.paddingRight || '');\r\n\r\n return this.props.vertical ? this.carousel.clientHeight - padding : this.carousel.clientWidth - padding;\r\n }\r\n\r\n private _canScrollPrevious (offset: number): boolean {\r\n return !isNaN(offset) && offset !== 0;\r\n }\r\n\r\n private _canScrollNext (offset: number): boolean {\r\n if (this.carouselSize + Math.abs(offset) >= this.slideSize) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _updateFlippers (offset: number): void {\r\n this.setState({\r\n showPrevious: this._canScrollPrevious(offset),\r\n showNext: this._canScrollNext(offset),\r\n offset: offset\r\n });\r\n }\r\n\r\n private _scrollItemIntoView (item: HTMLElement): void {\r\n const carouselSize = this.carouselSize;\r\n let offset = (this.props.vertical) ? item.offsetTop : item.offsetLeft;\r\n let updateOffset = false;\r\n\r\n const left = parseInt(getCSS(this.slide!, 'left'), 10) || 0;\r\n const top = parseInt(getCSS(this.slide!, 'top'), 10) || 0;\r\n\r\n if (this.props.vertical) {\r\n if (top < 0 && -top > offset) {\r\n if (offset !== 0) {\r\n offset = -offset + 1;\r\n }\r\n updateOffset = true;\r\n } else if (top + offset > carouselSize - this.itemSize) {\r\n offset = carouselSize - this.itemSize - offset - 1;\r\n updateOffset = true;\r\n }\r\n } else if (this.direction === 'left') {\r\n if (left < 0 && -left > offset) {\r\n if (offset !== 0) {\r\n offset = -offset + 1;\r\n }\r\n updateOffset = true;\r\n } else if (left + offset > carouselSize - this.itemSize) {\r\n offset = carouselSize - this.itemSize - offset - 1;\r\n updateOffset = true;\r\n }\r\n }\r\n\r\n if (updateOffset) {\r\n this._updateFlippers(offset);\r\n\r\n if (this.props.vertical) {\r\n setTimeout(() => {\r\n (this.slide as Node).parentElement!.scrollTop = 0;\r\n }, 0);\r\n } else {\r\n setTimeout(() => {\r\n (this.slide as Node).parentElement!.scrollLeft = 0;\r\n }, 0);\r\n }\r\n }\r\n }\r\n\r\n private _onFocus (event: React.FocusEvent): void {\r\n const target = event.currentTarget as HTMLElement;\r\n this._scrollItemIntoView(target);\r\n }\r\n\r\n private _onCarouselResized (): void {\r\n this._setSizes();\r\n let offset = parseInt(getCSS(this.slide!, this.direction), 10);\r\n\r\n // Ensure the carousel slide fits across the entire alotted space\r\n if (!isNaN(offset) && offset < 0 && this.slideSize + offset < this.carouselSize) {\r\n offset = Math.min(0, this.carouselSize - this.slideSize);\r\n }\r\n\r\n this._updateFlippers(offset);\r\n }\r\n\r\n private _onResized = (): void => {\r\n this._onCarouselResized();\r\n };\r\n}\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { format, Heading, IComponentNodeProps, IModuleProps, INodeProps, ISingleSlideCarouselProps, NodeTag } from '@msdyn365-commerce-modules/utilities';\r\nimport { AffiliationLoyaltyTier, ProductAvailableQuantity, ProductPrice, ProductSearchResult, ProjectionDomain } from '@msdyn365-commerce/retail-proxy';\r\nimport { getActivePricesAsync, getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\n\r\nimport ProductCard from '../../components/product.component';\r\nimport { publish } from '../../Utilities/analytics/analytics-dispatcher';\r\nimport CommerceAttributesParser from '../../Utilities/commerce-attributes-parser';\r\nimport SingleSlideCarousel from '../../Utilities/single-slide-carousel';\r\n\r\nimport { ISmweProductCollectionData } from './smwe-product-collection.data';\r\nimport { ISmweProductCollectionProps, layout } from './smwe-product-collection.props.autogenerated';\r\n\r\nexport interface IProductCollectionViewProps extends ISmweProductCollectionProps {\r\n heading?: React.ReactNode;\r\n ProductCollectionContainer: IModuleProps;\r\n SingleSlideCarouselComponentProps: INodeProps;\r\n GridComponentProps: INodeProps;\r\n products: IProductComponentViewProps[];\r\n isCarousel: boolean;\r\n}\r\n\r\nexport interface IProductComponentViewProps {\r\n ProductContainer: INodeProps;\r\n productComponent: React.ReactNode;\r\n}\r\n\r\nexport interface IProductCollectionState {\r\n clubPricing: ProductPrice[] | undefined;\r\n productAvailability: ProductAvailableQuantity[] | undefined;\r\n}\r\n\r\n/**\r\n * ProductCollection component\r\n */\r\nclass ProductCollection extends React.PureComponent, IProductCollectionState> {\r\n\r\n constructor(props: ISmweProductCollectionProps, state: IProductCollectionState) {\r\n super(props);\r\n\r\n this.state = {\r\n clubPricing: undefined,\r\n productAvailability: undefined\r\n };\r\n }\r\n\r\n public componentDidMount(): void {\r\n const products = this.props.config.productCollection.products;\r\n\r\n if (products && products.length) {\r\n void this._getClubPricing(products);\r\n void this._getProductavailabilty(products);\r\n\r\n const impressions = products.map(product => ({\r\n product,\r\n attributes: CommerceAttributesParser.getParsedAttributes(product.AttributeValues || []),\r\n }));\r\n\r\n publish('impression', {\r\n products: impressions,\r\n\r\n list: 'Product Collection', // Could be Search Results if we ever enable search results pages\r\n category: this.props.config.heading?.text,\r\n context: this.props.context,\r\n });\r\n\r\n }\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { heading, productCollection, className } = this.props.config;\r\n const { resources } = this.props;\r\n const products = productCollection && productCollection.products;\r\n const isCarousel = this.props.config.layout === layout.carousel;\r\n const headingComponent = heading && heading.text && ;\r\n\r\n const productCollectionViewProps = {\r\n ...this.props,\r\n heading: headingComponent,\r\n SingleSlideCarouselComponentProps: {\r\n tag: SingleSlideCarousel,\r\n className: '',\r\n flipperPrevLabel: resources.flipperPrevious,\r\n flipperNextLabel: resources.flipperNext,\r\n parentId: this.props.id\r\n } as IComponentNodeProps,\r\n ProductCollectionContainer: {\r\n moduleProps: this.props,\r\n className: classnames('ms-product-collection ms-search-result-container', className)\r\n },\r\n GridComponentProps: {\r\n tag: 'ul' as NodeTag,\r\n className: 'ms-product-collection__items',\r\n },\r\n isCarousel: isCarousel,\r\n products: products && products.length > 0 && products.map((item: ProductSearchResult, index: number) => this._getProduct(item, index)),\r\n };\r\n return this.props.renderView(productCollectionViewProps) as React.ReactElement;\r\n }\r\n\r\n private async _getClubPricing(products:ProductSearchResult[]): Promise {\r\n const projectDomain: ProjectionDomain = { ChannelId: +this.props.context.request.apiSettings.channelId, CatalogId: +this.props.context.request.apiSettings.catalogId };\r\n let affiliations: AffiliationLoyaltyTier[];\r\n if (this.props.context.app.config.affiliationId) {\r\n affiliations = [\r\n {\r\n AffiliationId: this.props.context.app.config.affiliationId\r\n }\r\n ];\r\n } else {\r\n affiliations = [];\r\n }\r\n const productIds: number[] = [];\r\n products.forEach((product) => {\r\n productIds.push(product.RecordId);\r\n });\r\n const clubPricingAll = await getActivePricesAsync(\r\n { callerContext: this.props.context.actionContext },\r\n projectDomain,\r\n productIds,\r\n new Date(),\r\n '',\r\n affiliations,\r\n true\r\n );\r\n this.setState({clubPricing: clubPricingAll});\r\n }\r\n\r\n private async _getProductavailabilty(products: ProductSearchResult[]): Promise {\r\n if (products && products.length && products.length > 0) {\r\n const productIds: number[] = [];\r\n products.forEach((product) => {\r\n productIds.push(product.RecordId);\r\n });\r\n const availabilityAll = await getEstimatedAvailabilityAsync({ callerContext: this.props.context.actionContext }, { ProductIds: productIds, DefaultWarehouseOnly: true});\r\n const formattedResponse = availabilityAll.ProductWarehouseInventoryAvailabilities?.map((product) => {\r\n return {ProductId: product.ProductId, AvailableQuantity: product.PhysicalAvailable, ExtensionProperties: product.ExtensionProperties};\r\n }) as ProductAvailableQuantity[];\r\n this.setState({productAvailability: formattedResponse});\r\n }\r\n }\r\n\r\n private _getProduct = (product: ProductSearchResult, index: number): IProductComponentViewProps => {\r\n const { imageSettings, showPrice } = this.props.config;\r\n const addToCart = this.props.config.addToCart || false;\r\n const resources = this.props.resources;\r\n const categoryHierarchy = undefined;\r\n const passedProps = { ...this.props, categoryHierarchy };\r\n const availibity = this.state.productAvailability?.find((item) => {\r\n return item.ProductId === product.RecordId;\r\n });\r\n const clubPrice = this.state.clubPricing?.find((item) => {\r\n return item.ProductId === product.RecordId;\r\n });\r\n const showQuantityAsDropdown = this.props.config.showQuantityAsDropdown || false;\r\n\r\n return {\r\n ProductContainer: {\r\n tag: 'li' as NodeTag,\r\n className: 'ms-product-collection__item ms-product-search-result__item',\r\n role: 'listitem',\r\n key: index,\r\n },\r\n productComponent: (\r\n \r\n )\r\n };\r\n };\r\n}\r\n\r\nexport default ProductCollection;\r\n","import {\r\n Button,\r\n Modal,\r\n ModalBody,\r\n ModalFooter,\r\n ModalHeader\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport React from 'react';\r\n\r\nexport interface ISearchResultModalViewProps {\r\n modal: React.ReactElement;\r\n modalHeader: React.ReactElement;\r\n modalFooter: React.ReactElement;\r\n modalBody: React.ReactElement;\r\n}\r\n\r\ninterface IModalToggleProps {\r\n innerRef: React.RefObject | undefined;\r\n id: string;\r\n text: string;\r\n ariaLabel: string;\r\n onClick(): void;\r\n}\r\n\r\nexport interface ISearchResultModalResources {\r\n modalTitle: string;\r\n modalCloseButtonText: string;\r\n}\r\n\r\nexport interface ISearchResultModalProps {\r\n resources: ISearchResultModalResources;\r\n isOpen: boolean;\r\n returnRef: React.RefObject | undefined;\r\n onModalToggle():void;\r\n}\r\n\r\nexport const ModalToggle: React.FC = (props: IModalToggleProps) => {\r\n const {text, onClick, ariaLabel, innerRef, id} = props;\r\n return ;\r\n};\r\n\r\nexport const SearchResultModal = (props: ISearchResultModalProps):ISearchResultModalViewProps => {\r\n return {\r\n modal: modalNode(props),\r\n modalHeader: modalHeaderNode(props),\r\n modalFooter: modalFooterNode(props),\r\n modalBody: \r\n };\r\n};\r\n\r\nconst modalNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n {props.resources.modalTitle}\r\n \r\n );\r\n};\r\n\r\nconst modalFooterNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n \r\n \r\n );\r\n};","import { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { RatingComponent } from '@msdyn365-commerce/components';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { ProductRefinerSource, ProductRefinerTypeValue } from './utilities';\r\n\r\n/**\r\n * RefineItem properties\r\n */\r\nexport interface IRefineItemProps {\r\n\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\r\n productRefinerValue: ProductRefinerValue;\r\n selectedRefinementCriterion: ProductRefinerValue | undefined;\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n context: ICoreContext;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n onToggle(notfication: Readonly): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine item state\r\n */\r\nexport interface IRefineItemState extends React.ComponentState {\r\n isChecked: boolean;\r\n renderingError?: object;\r\n}\r\n\r\n/**\r\n * Single-select and multi-select refine item component (controlled by RefineSubmenu)\r\n */\r\nexport default class RefineItem extends React.Component {\r\n private anchorType: React.RefObject;\r\n\r\n constructor(props: IRefineItemProps) {\r\n super(props);\r\n this._onClick = this._onClick.bind(this);\r\n this.state = {\r\n isChecked: !!this.props.selectedRefinementCriterion\r\n };\r\n this.anchorType = React.createRef();\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n selectedRefinementCriterion,\r\n children,\r\n onToggle,\r\n context,\r\n ...attrs\r\n } = this.props;\r\n if (!productRefinerValue) {\r\n refineItemCommonProps.telemetry.error('[refine-item] Cannot render refineItem without productRefinerValue');\r\n return undefined;\r\n }\r\n if (!productRefinerValue.LeftValueBoundString) {\r\n refineItemCommonProps.telemetry.warning(`[refine-item] RefineItem without LeftValueBoundString: ${JSON.stringify(productRefinerValue)}`);\r\n }\r\n const isSingleSelect = parentProductRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single;\r\n let itemTypeClassName = isSingleSelect ? 'single-select' : 'multi-select';\r\n itemTypeClassName = `ms-refine-submenu-item ${itemTypeClassName}`;\r\n const inputType = isSingleSelect ? 'radio' : 'checkbox';\r\n const role = isSingleSelect ? 'radio' : undefined;\r\n itemTypeClassName = !!selectedRefinementCriterion ? `${itemTypeClassName}-checked` : itemTypeClassName;\r\n if (parentProductRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) {\r\n if (productRefinerValue.LeftValueBoundString) {\r\n return (\r\n \r\n \r\n \r\n {productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}\r\n \r\n \r\n );\r\n } else {\r\n return undefined;\r\n }\r\n } else {\r\n return (\r\n
  • \r\n \r\n \r\n {productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}\r\n \r\n \r\n
  • \r\n );\r\n }\r\n }\r\n\r\n private _getRefinerUrl(): string {\r\n const { urlBuilder, parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n\r\n if (productRefinerValue) {\r\n return urlBuilder({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n }\r\n\r\n return '';\r\n }\r\n\r\n private _onClick = (e: React.MouseEvent): void => {\r\n e.preventDefault();\r\n\r\n const { parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n if (productRefinerValue) {\r\n this.props.onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n\r\n setTimeout(\r\n () => {\r\n this.anchorType.current && this.anchorType.current.focus();\r\n },\r\n 0\r\n );\r\n }\r\n };\r\n}","import * as React from 'react';\r\ninterface ITitle {\r\n className: string;\r\n text: string;\r\n}\r\n\r\nexport const Title: React.FC = ({ text, className }) => ( {text} );\r\n","import { ITelemetry } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\n/**\r\n * Types of product refiner values\r\n */\r\nexport const enum ProductRefinerValueDataTypeValue {\r\n /**\r\n * Range slider is used for selections like price\r\n */\r\n Range = 1,\r\n\r\n /**\r\n * Range input is a different way to specify ranges and can be expressed with input boxes\r\n * as well as a set of discrete single-select type values\r\n */\r\n RangeInput = 4,\r\n\r\n /**\r\n * This is a discrete list item, either multi-select or single-select\r\n */\r\n List = 5,\r\n\r\n /**\r\n * Boolean types allows only single-select\r\n */\r\n Boolean = 6\r\n}\r\n\r\n/**\r\n * Types of product refiners\r\n */\r\nexport const enum ProductRefinerTypeValue {\r\n /**\r\n * Refiner values are single-select\r\n */\r\n Single = 0,\r\n\r\n /**\r\n * Refiner values are multi-select\r\n */\r\n Multi = 1\r\n}\r\n\r\n/**\r\n * ProductRefinerSource enum type.\r\n */\r\nexport const enum ProductRefinerSource {\r\n /**\r\n * The None member.\r\n */\r\n None = 0,\r\n /**\r\n * The Attribute member.\r\n */\r\n Attribute = 1,\r\n /**\r\n * The Category member.\r\n */\r\n Category = 2,\r\n /**\r\n * The Price member.\r\n */\r\n Price = 3,\r\n /**\r\n * The Rating member.\r\n */\r\n Rating = 4\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value\r\n * @param productRefinerValue product refiner value to match\r\n * @param refinementCriteria selected refinement criteria\r\n */\r\nexport function findMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue | undefined {\r\n // if the value is a range, then match only on data type value; otherwise match on item string\r\n return refinementCriteria.find(\r\n (refinementCriterion: ProductRefinerValue) => isMatchingRefinementCriterion(productRefinerValue, refinementCriterion)\r\n );\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value\r\n * @param productRefinerValue product refiner value to match\r\n * @param refinementCriteria selected refinement criteria\r\n */\r\nexport function isMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriterion: ProductRefinerValue\r\n): boolean {\r\n // if the value is a range, then match only on data type value; otherwise match on item string\r\n return (\r\n refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\r\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\r\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\r\n (refinementCriterion.DataTypeValue === ProductRefinerValueDataTypeValue.Range ||\r\n refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString)\r\n );\r\n}\r\n\r\nexport function getUpdatedRefinementCriteria(\r\n itemToggleNotification: IRefineItemToggleNotification,\r\n currentRefinementCriteria: ProductRefinerValue[]): ProductRefinerValue[] {\r\n const updatedRefinementCriteria: ProductRefinerValue[] = [];\r\n let toggledItemFound = false;\r\n currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\r\n if (isMatchingRefinementCriterion(itemToggleNotification.productRefinerValue, selectedCriterion)) {\r\n toggledItemFound = true;\r\n if (itemToggleNotification.isSelecting) {\r\n const next = {\r\n ...selectedCriterion,\r\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || selectedCriterion.LeftValueBoundString,\r\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || selectedCriterion.RightValueBoundString,\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n } // else the item is being de-selected, so omit it from the refinement criteria\r\n } else {\r\n // keep existing criterion because it is not in the item toggle notification\r\n updatedRefinementCriteria.push(selectedCriterion);\r\n }\r\n });\r\n\r\n if (!toggledItemFound) {\r\n const next = {\r\n ...itemToggleNotification.productRefinerValue,\r\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || itemToggleNotification.productRefinerValue.LeftValueBoundString,\r\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || itemToggleNotification.productRefinerValue.RightValueBoundString,\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n // If single select, then deselect any others in the parent refiner group\r\n if ((itemToggleNotification.productRefinerValue.DataTypeValue === ProductRefinerValueDataTypeValue.List || itemToggleNotification.productRefinerValue.DataTypeValue === ProductRefinerValueDataTypeValue.Boolean) &&\r\n itemToggleNotification.parentProductRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single) {\r\n itemToggleNotification.parentProductRefinerHierarchy.Values.forEach((child: ProductRefinerValue) => {\r\n if (child.RefinerRecordId === next.RefinerRecordId && child.LeftValueBoundString === next.LeftValueBoundString) {\r\n // do nothing\r\n } else {\r\n const matchingIndex = updatedRefinementCriteria.findIndex((criterion: ProductRefinerValue) => isMatchingRefinementCriterion(child, criterion));\r\n if (matchingIndex > -1) {\r\n updatedRefinementCriteria.splice(matchingIndex, 1);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return updatedRefinementCriteria;\r\n}\r\n\r\nexport function formatPrice(\r\n amount: string | undefined,\r\n currency: string | undefined,\r\n locale: string | undefined,\r\n telemetry: ITelemetry): string {\r\n if (!amount || !currency) {\r\n telemetry.trace(`[refine-menu.utilities.formatPrice] could not format price for ${amount} ${currency}`);\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency: currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (e) {\r\n result = `${priceAmount} ${currency}`;\r\n telemetry.warning(`[refine-menu.utilities.formatPrice] Failed to format price for ${result}: ${e}`);\r\n }\r\n\r\n return result;\r\n}","import * as React from 'react';\r\ninterface ILink {\r\n className?: string;\r\n text?: string;\r\n href?: string;\r\n ariaLabel?: string;\r\n}\r\n\r\nexport const Link: React.FC = ({ text, className, href, ariaLabel }) => ( {text} );","import { Slider } from '@msdyn365-commerce-modules/utilities';\r\nimport debounce from 'lodash/debounce';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport { formatPrice } from './utilities';\r\n\r\ntype InputType = 'Min' | 'Max';\r\n\r\nimport { IRefineItemProps, IRefineItemState } from './refine-item';\r\n\r\nexport type RangeRefineItemType = 'slider' | 'input';\r\n\r\n/**\r\n * Range refine item properties\r\n */\r\nexport interface IRangeRefineItemProps extends IRefineItemProps {\r\n rangeType: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n}\r\n\r\n/**\r\n * Range refine item state\r\n */\r\nexport interface IRangeRefineItemState extends IRefineItemState {\r\n validationErrorMin: string | undefined;\r\n validationErrorMax: string | undefined;\r\n selectedMin: string | undefined;\r\n selectedMax: string | undefined;\r\n touchedMin: boolean;\r\n touchedMax: boolean;\r\n}\r\n\r\n/**\r\n * RangeRefineItem component (controlled by RefineSubmenu)\r\n */\r\n@observer\r\nexport default class RangeRefineItem extends React.Component {\r\n private _formattedPriceReverseLookup: Map = new Map();\r\n\r\n private minInput: React.RefObject;\r\n private maxInput: React.RefObject;\r\n\r\n @computed get currencyCode(): string {\r\n return this.props.productRefinerValue.UnitText || '';\r\n }\r\n\r\n constructor(props: IRangeRefineItemProps) {\r\n super(props);\r\n this._onRangeUpdate = this._onRangeUpdate.bind(this);\r\n this._onRangeUpdateEnd = this._onRangeUpdateEnd.bind(this);\r\n this._handleRangeTooltipText = this._handleRangeTooltipText.bind(this);\r\n this._changeMin = this._changeMin.bind(this);\r\n this._changeMax = this._changeMax.bind(this);\r\n this._finishChangeMin = this._finishChangeMin.bind(this);\r\n this._finishChangeMax = this._finishChangeMax.bind(this);\r\n\r\n this.minInput = React.createRef();\r\n this.maxInput = React.createRef();\r\n\r\n const { selectedRefinementCriterion } = this.props;\r\n const initialMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\r\n const initialMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\r\n this.state = {\r\n isChecked: false,\r\n validationErrorMin: undefined,\r\n validationErrorMax: undefined,\r\n selectedMin: initialMin,\r\n selectedMax: initialMax,\r\n touchedMin: false,\r\n touchedMax: false\r\n };\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const { productRefinerValue, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerValue || !parentProductRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render refine value range without productRefinerValue and parentProductRefinerHierarchy');\r\n return undefined;\r\n }\r\n\r\n if (this.props.rangeType === 'input') {\r\n return this._renderInputFields();\r\n }\r\n\r\n return this._renderSlider();\r\n }\r\n\r\n private _renderInputFields(): JSX.Element | undefined {\r\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n const { selectedMin, selectedMax, touchedMin, touchedMax, validationErrorMin, validationErrorMax } = this.state;\r\n\r\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', (parentProductRefinerHierarchy.KeyName || ''));\r\n const formAttrs = {\r\n 'aria-label': rangeAriaLabel,\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n // To enable price formatting of selected fields, this is the approach:\r\n // initial value: min=0 formatted as price, max=undefined\r\n // onFocus/onChange: convert to number (unformat) and mark as touched to indicate value is being edited\r\n // onBlur: validate and format entered value as price\r\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${validationErrorMin ? 'refine-submenu__input-range--error' : ''}`;\r\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${validationErrorMax ? 'refine-submenu__input-range--error' : ''}`;\r\n const minLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-min';\r\n const maxLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-max';\r\n const formattedSelectedMin = this._getFormattedSelectedValue(selectedMin, touchedMin, validationErrorMin);\r\n const formattedSelectedMax = this._getFormattedSelectedValue(selectedMax, touchedMax, validationErrorMax);\r\n return (\r\n
    \r\n \r\n \r\n {validationErrorMin &&\r\n {validationErrorMin}\r\n }\r\n {validationErrorMax && validationErrorMin !== validationErrorMax &&\r\n {validationErrorMax}\r\n }\r\n
    \r\n );\r\n }\r\n\r\n private _renderSlider(): JSX.Element | undefined {\r\n const { isDisabled, productRefinerValue, parentProductRefinerHierarchy, selectedRefinementCriterion } = this.props;\r\n const min = productRefinerValue.LeftValueBoundString;\r\n const max = productRefinerValue.RightValueBoundString;\r\n const selectedMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || productRefinerValue.LeftValueBoundString || '0';\r\n const selectedMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || productRefinerValue.RightValueBoundString || max;\r\n const sliderId = `slider_${parentProductRefinerHierarchy.RecordId}_${productRefinerValue.RefinerRecordId}`;\r\n const ariaAttributes = {\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n const minPrice = this._formatPrice(min);\r\n const maxPrice = this._formatPrice(max);\r\n const selectedMinPrice =this._formatPrice(selectedMin);\r\n const selectedMaxPrice =this._formatPrice(selectedMax);\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n private _changeMin(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Min');\r\n }\r\n\r\n private _changeMax(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Max');\r\n }\r\n\r\n private _changeValue(event: React.FocusEvent, inputType: InputType): void {\r\n const selectedKey = `selected${inputType}`;\r\n const touchedKey = `touched${inputType}`;\r\n this.setState({\r\n [selectedKey]: this._getInputWithoutFormatting(event.currentTarget.value),\r\n [touchedKey]: true\r\n });\r\n }\r\n\r\n private _finishChangeMin(event: React.FocusEvent): boolean {\r\n const selectedMinValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMin: selectedMinValue,\r\n minTouched: false\r\n });\r\n const minInput = Number(selectedMinValue);\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\r\n const max = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\r\n\r\n const maxNum = max ? Number(max) : undefined;\r\n\r\n if (isNaN(minInput)) {\r\n this.setState({validationErrorMin: refineItemCommonProps.validationErrorNaN});\r\n this._focus('Min');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minInput, maxNum)) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minInput,\r\n rangeEnd: maxNum\r\n });\r\n return true;\r\n } else {\r\n this._focus('Min');\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _finishChangeMax(event: React.FocusEvent): boolean {\r\n const selectedMaxValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMax: selectedMaxValue,\r\n maxTouched: false\r\n });\r\n const maxInput = Number(selectedMaxValue);\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\r\n const min = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\r\n\r\n const minNum = Number(min);\r\n\r\n if (isNaN(maxInput)) {\r\n this.setState({validationErrorMax: refineItemCommonProps.validationErrorNaN});\r\n this._focus('Max');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minNum, maxInput)) {\r\n if (productRefinerValue) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minNum,\r\n rangeEnd: maxInput\r\n });\r\n } else {\r\n this._focus('Max');\r\n }\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _focus(inputType: InputType): void {\r\n const ref = inputType === 'Max' ? this.maxInput : this.minInput;\r\n\r\n setTimeout(() => {\r\n if (ref && ref.current) {\r\n ref.current.focus();\r\n }\r\n }, 50);\r\n }\r\n\r\n private _getFormattedSelectedValue(selected: string | undefined, touched: boolean, validationError: string | undefined): string | undefined {\r\n if (touched || validationError || selected === undefined) {\r\n return selected;\r\n }\r\n return this._formatPrice(selected);\r\n }\r\n\r\n private _validateRange(min: number, max: number | undefined): boolean {\r\n const { refineItemCommonProps } = this.props;\r\n if (max === undefined) {\r\n return true;\r\n }\r\n\r\n if (min > max) {\r\n this.setState({\r\n validationErrorMin: refineItemCommonProps.validationErrorRange,\r\n validationErrorMax: refineItemCommonProps.validationErrorRange\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _formatPrice(amount: string | undefined): string {\r\n const locale = this.props.refineItemCommonProps.locale;\r\n const result = formatPrice(amount, this.currencyCode, locale, this.props.refineItemCommonProps.telemetry);\r\n\r\n if (amount !== undefined && !this._formattedPriceReverseLookup.has(result)) {\r\n this._formattedPriceReverseLookup.set(result, amount);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNum = Number(input);\r\n if (!isNaN(inputAsNum)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\r\n return reverseLookupResult || input;\r\n }\r\n\r\n // NOTE: Fix types once Shared Components build pipeline bug fixed\r\n // tslint:disable-next-line:no-any\r\n private _onRangeUpdate(sliderChangeNotification: any): void {\r\n // Need to filter out mousemove events as these cause errors after the menu updates and slider re-renders\r\n if (sliderChangeNotification.eventType !== 'mousemove') {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n }\r\n\r\n // tslint:disable-next-line\r\n private _onRangeUpdateEnd(sliderChangeNotification: any): void {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n\r\n // tslint:disable-next-line\r\n private _focusOnSliderThumb(sliderChangeNotification: any): void {\r\n if (sliderChangeNotification.id) {\r\n const element = document.getElementById(sliderChangeNotification.id);\r\n if (!!element) {\r\n setTimeout(\r\n () => {\r\n element.focus();\r\n }, 0);\r\n }\r\n }\r\n }\r\n\r\n private _handleRangeTooltipText(tooltip: number): string {\r\n return this._formatPrice(`${tooltip}`);\r\n }\r\n}","import { ITelemetry } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\n/**\r\n * Types of product refiner values\r\n */\r\nexport const enum ProductRefinerValueDataTypeValue {\r\n /**\r\n * Range slider is used for selections like price\r\n */\r\n Range = 1,\r\n\r\n /**\r\n * Range input is a different way to specify ranges and can be expressed with input boxes\r\n * as well as a set of discrete single-select type values\r\n */\r\n RangeInput = 4,\r\n\r\n /**\r\n * This is a discrete list item, either multi-select or single-select\r\n */\r\n List = 5,\r\n\r\n /**\r\n * Boolean types allows only single-select\r\n */\r\n Boolean = 6\r\n}\r\n\r\n/**\r\n * Types of product refiners\r\n */\r\nexport const enum ProductRefinerTypeValue {\r\n /**\r\n * Refiner values are single-select\r\n */\r\n Single = 0,\r\n\r\n /**\r\n * Refiner values are multi-select\r\n */\r\n Multi = 1\r\n}\r\n\r\n/**\r\n * ProductRefinerSource enum type.\r\n */\r\nexport const enum ProductRefinerSource {\r\n /**\r\n * The None member.\r\n */\r\n None = 0,\r\n /**\r\n * The Attribute member.\r\n */\r\n Attribute = 1,\r\n /**\r\n * The Category member.\r\n */\r\n Category = 2,\r\n /**\r\n * The Price member.\r\n */\r\n Price = 3,\r\n /**\r\n * The Rating member.\r\n */\r\n Rating = 4\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value\r\n * @param productRefinerValue product refiner value to match\r\n * @param refinementCriteria selected refinement criteria\r\n */\r\nexport function findMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue | undefined {\r\n // if the value is a range, then match only on data type value; otherwise match on item string\r\n return refinementCriteria.find(\r\n (refinementCriterion: ProductRefinerValue) => isMatchingRefinementCriterion(productRefinerValue, refinementCriterion)\r\n );\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value\r\n * @param productRefinerValue product refiner value to match\r\n * @param refinementCriteria selected refinement criteria\r\n */\r\nexport function isMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriterion: ProductRefinerValue\r\n): boolean {\r\n // if the value is a range, then match only on data type value; otherwise match on item string\r\n return (\r\n refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\r\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\r\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\r\n (refinementCriterion.DataTypeValue === ProductRefinerValueDataTypeValue.Range ||\r\n refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString)\r\n );\r\n}\r\n\r\nexport function getUpdatedRefinementCriteria(\r\n itemToggleNotification: IRefineItemToggleNotification,\r\n currentRefinementCriteria: ProductRefinerValue[]): ProductRefinerValue[] {\r\n const updatedRefinementCriteria: ProductRefinerValue[] = [];\r\n let toggledItemFound = false;\r\n currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\r\n if (isMatchingRefinementCriterion(itemToggleNotification.productRefinerValue, selectedCriterion)) {\r\n toggledItemFound = true;\r\n if (itemToggleNotification.isSelecting) {\r\n const next = {\r\n ...selectedCriterion,\r\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || selectedCriterion.LeftValueBoundString,\r\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || selectedCriterion.RightValueBoundString,\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n } // else the item is being de-selected, so omit it from the refinement criteria\r\n } else {\r\n // keep existing criterion because it is not in the item toggle notification\r\n updatedRefinementCriteria.push(selectedCriterion);\r\n }\r\n });\r\n\r\n if (!toggledItemFound) {\r\n const next = {\r\n ...itemToggleNotification.productRefinerValue,\r\n LeftValueBoundString: itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}` || itemToggleNotification.productRefinerValue.LeftValueBoundString,\r\n RightValueBoundString: itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}` || itemToggleNotification.productRefinerValue.RightValueBoundString,\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n // If single select, then deselect any others in the parent refiner group\r\n if ((itemToggleNotification.productRefinerValue.DataTypeValue === ProductRefinerValueDataTypeValue.List || itemToggleNotification.productRefinerValue.DataTypeValue === ProductRefinerValueDataTypeValue.Boolean) &&\r\n itemToggleNotification.parentProductRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single) {\r\n itemToggleNotification.parentProductRefinerHierarchy.Values.forEach((child: ProductRefinerValue) => {\r\n if (child.RefinerRecordId === next.RefinerRecordId && child.LeftValueBoundString === next.LeftValueBoundString) {\r\n // do nothing\r\n } else {\r\n const matchingIndex = updatedRefinementCriteria.findIndex((criterion: ProductRefinerValue) => isMatchingRefinementCriterion(child, criterion));\r\n if (matchingIndex > -1) {\r\n updatedRefinementCriteria.splice(matchingIndex, 1);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return updatedRefinementCriteria;\r\n}\r\n\r\nexport function formatPrice(\r\n amount: string | undefined,\r\n currency: string | undefined,\r\n locale: string | undefined,\r\n telemetry: ITelemetry): string {\r\n if (!amount || !currency) {\r\n telemetry.trace(`[refine-menu.utilities.formatPrice] could not format price for ${amount} ${currency}`);\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency: currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (e) {\r\n result = `${priceAmount} ${currency}`;\r\n telemetry.warning(`[refine-menu.utilities.formatPrice] Failed to format price for ${result}: ${e}`);\r\n }\r\n\r\n return result;\r\n}","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport classnames from 'classnames';\r\nimport { computed, observable, reaction, transaction } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { ILabeledDropdownOnChangeNotification, ILabeledDropdownOption, IModuleProps, INodeProps, LabeledDropdown, UncontrolledPagination } from '@msdyn365-commerce-modules/utilities';\r\nimport { CategoryHierarchy as CategoryHierarchyData, IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\n// category description 1.0\r\nimport MsDyn365, { IImageDimension, RichText, RichTextComponent } from '@msdyn365-commerce/core';\r\nimport { AsyncResult, format, ProductAvailableQuantity, ProductRefinerValue, ProductSearchResult, SortColumn, TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\r\nimport { getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { ICheckoutState } from '@msdyn365-commerce/global-state';\r\n\r\nimport { ISmweSearchResultContainerParentProps } from '../../components/product.component';\r\nimport { buildListPageUrl, getCollectionProducts, getCurrentUrl, GetFullProductsByCollectionInput, hydrateRefinersFromUrl, IFullProductsSearchResultsWithCount, parseQueryParam, sortOptions } from '../../dataActions/search-result-container';\r\nimport { publish } from '../../Utilities/analytics/analytics-dispatcher';\r\nimport { filterInvalidCategories } from '../../Utilities/refiners';\r\nimport { filterCartLines } from '../../Utilities/subscription-manager';\r\n\r\nimport CommerceAttributesParser from '../../Utilities/commerce-attributes-parser';\r\nimport {\r\n ErrorMessage, getUpdatedRefinementCriteria, IChoiceSummaryClickNotification,\r\n IRefineItemCommonProps, IRefineItemToggleNotification, ISearchResultModalViewProps, isMatchingRefinementCriterion, Link, ModalToggle, ProductSearchResultItems, SearchResultModal, Separator, Title\r\n} from './components';\r\nimport ChoiceSummary from './components/choice-summary';\r\nimport RefineSubmenu from './components/refine-submenu';\r\nimport { IElicitSubscriptionsData } from './elicit-subscriptions.data';\r\nimport { IElicitSubscriptionsProps } from './elicit-subscriptions.props.autogenerated';\r\n\r\nexport interface ISearchResultContainerViewProps extends IElicitSubscriptionsProps<{}> {\r\n products?: React.ReactNode;\r\n className?: string;\r\n SearchResultContainer: IModuleProps;\r\n TitleViewProps: ITitleViewProps;\r\n categoryHierarchy: ICategoryHierarchyViewProps;\r\n pagination?: React.ReactNode;\r\n ProductsContainer: INodeProps;\r\n ProductSectionContainer: INodeProps;\r\n refineMenu: IRefineMenuViewProps;\r\n sortByOptions: ISortByViewProps;\r\n choiceSummary?: React.ReactNode;\r\n modalToggle: React.ReactNode;\r\n searchResultModal: ISearchResultModalViewProps;\r\n isMobile: boolean;\r\n CategoryNavContainer: INodeProps;\r\n RefineAndProductSectionContainer: INodeProps;\r\n errorMessage: React.ReactNode;\r\n categoryDescription: JSX.Element | undefined;\r\n}\r\n\r\nexport interface ITitleViewProps {\r\n TitleContainer: INodeProps;\r\n title: ISearchResultTitle;\r\n}\r\n\r\nexport interface IRefineMenuViewProps {\r\n RefineMenuContainer: INodeProps;\r\n RefinerSectionContainer: INodeProps;\r\n refiners?: React.ReactNode[];\r\n}\r\n\r\nexport interface ICategoryHierarchyViewProps {\r\n categoryHierarchyList?: React.ReactNode[];\r\n categoryHierarchySeparator?: React.ReactNode;\r\n CategoryHierarchyContainer: INodeProps;\r\n}\r\n\r\nexport interface ISortByViewProps {\r\n SortingContainer: INodeProps;\r\n sortByDropDown?: React.ReactNode;\r\n}\r\n\r\nexport type GridSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * Title component for search result container\r\n */\r\nexport interface ISearchResultTitle {\r\n titlePrefix?: React.ReactNode;\r\n titleText?: React.ReactNode;\r\n titleCount?: React.ReactNode;\r\n}\r\n\r\nexport interface ISearchResultContainerState {\r\n sortingState: ISortByCollectionState;\r\n modalIsOpen: boolean;\r\n productAvailability: ProductAvailableQuantity[] | undefined;\r\n}\r\n\r\ninterface ISortByCollectionState {\r\n selectedSortByOption: ILabeledDropdownOption;\r\n pending: boolean;\r\n}\r\n\r\ninterface IImageSettingsViewports {\r\n xs: IImageDimension;\r\n sm?: IImageDimension | undefined;\r\n md?: IImageDimension | undefined;\r\n lg?: IImageDimension | undefined;\r\n xl?: IImageDimension | undefined;\r\n}\r\n\r\n/**\r\n *\r\n * SearchResultContainer component\r\n * @extends {React.Component>}\r\n */\r\n@observer\r\nexport default class SmweSearchResultContainer extends React.Component, ISearchResultContainerState> {\r\n\r\n @computed get isMobile(): boolean {\r\n return (this._viewport === 'xs' || this._viewport === 'sm' || this._viewport === 'md');\r\n }\r\n\r\n private sortByDropdownOptions: ILabeledDropdownOption[] = [];\r\n private showSortByDropdown: boolean = false;\r\n private _refineItemCommonProps: IRefineItemCommonProps;\r\n private _pageType: string | undefined = this.props.context.request.urlTokens.pageType;\r\n @observable\r\n private _viewport: GridSize;\r\n\r\n @observable\r\n private _refinersFiltered: boolean = false;\r\n\r\n private _modalToggleRef: React.RefObject;\r\n private _sortAndFilterContainerRef: React.RefObject;\r\n private _initialProductResultCount: number = 0;\r\n\r\n public static getFriendlyName(locale: string, nameTranslations?: TextValueTranslation[]): string | undefined {\r\n let nameTranslation: TextValueTranslation | undefined;\r\n if (locale && nameTranslations && nameTranslations.length > 0) {\r\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\r\n }\r\n\r\n return nameTranslation && nameTranslation.Text;\r\n }\r\n\r\n // tslint:disable-next-line: max-func-body-length\r\n constructor(props: IElicitSubscriptionsProps) {\r\n super(props);\r\n this._viewport = props.context.request && props.context.request.device && props.context.request.device.Type === 'Mobile' ? 'xs' : 'lg';\r\n this._modalToggleRef = React.createRef();\r\n this._sortAndFilterContainerRef = React.createRef();\r\n this._toggleModal = this._toggleModal.bind(this);\r\n this._updateViewport = this._updateViewport.bind(this);\r\n this._addSortByDropdownOptions();\r\n\r\n this.props.data.checkoutState = this.props.data.checkoutState || {} as AsyncResult;\r\n\r\n const modifiedImageSettings = props.config.imageSettings;\r\n if (modifiedImageSettings) {\r\n if (modifiedImageSettings.viewports) {\r\n modifiedImageSettings.viewports = this.usePNGImageSetting(modifiedImageSettings.viewports);\r\n }\r\n }\r\n\r\n this.state = {\r\n sortingState: {\r\n pending: false,\r\n selectedSortByOption: this.sortByDropdownOptions[0]\r\n },\r\n modalIsOpen: false,\r\n productAvailability: undefined\r\n };\r\n const { placeholderTextMax, minLabel, maxLabel, rangeNameFormat } = this.props.resources;\r\n\r\n const locale = this.props.context.request.locale;\r\n const telemetry = this.props.telemetry;\r\n const validationErrorNaN = this.props.resources.validationErrorNotNumber;\r\n const validationErrorRange = this.props.resources.validationErrorNotRange;\r\n this._refineItemCommonProps = {\r\n telemetry,\r\n locale,\r\n placeholderTextMax,\r\n minLabel,\r\n maxLabel,\r\n rangeNameFormat,\r\n validationErrorNaN,\r\n validationErrorRange\r\n };\r\n\r\n reaction(\r\n () => { return [this.props.data.cart.result?.cart.CartLines, this.props.data.cart.result, this.props.data.cart.result?.cart]; },\r\n () => { this.setState({}); }\r\n );\r\n\r\n // Initalization of list page\r\n // Have an ugly promise cascade. Promise.all() does NOT work right here. That causes everything below to run after render instead of before.\r\n void this.props.data.products.then(products => {\r\n void this.props.data.listPageState.then(listPageState => {\r\n void this.props.data.refiners.then(refiners => {\r\n void this.props.data.categoryHierarchy.then(categoryHierarchy => {\r\n if (this._pageType === 'Category') {\r\n listPageState.pageType = 'Category';\r\n } else {\r\n listPageState.pageType = 'Search';\r\n }\r\n let querySorting: SortColumn[] = [];\r\n\r\n if (this.props.context.request.query && this.props.context.request.query.sorting) {\r\n querySorting = JSON.parse(decodeURIComponent(this.props.context.request.query.sorting)) as SortColumn[];\r\n }\r\n\r\n listPageState.currentPageNumber = this.props.context.request.query && (+this.props.context.request.query.skip / (this.props.config.itemsPerPage || 10)) || 0;\r\n listPageState.sortingCritera = { Columns: querySorting };\r\n listPageState.pageSize = this.props.config.itemsPerPage || 10;\r\n listPageState.activeProducts = products.products;\r\n listPageState.totalProductCount = products.count;\r\n this._initialProductResultCount = products.count;\r\n listPageState.activeFilters = hydrateRefinersFromUrl(this.props.context.request);\r\n\r\n filterInvalidCategories(refiners, categoryHierarchy, this.props.context.app.config.refinerRemappers);\r\n this._refinersFiltered = true;\r\n\r\n // tslint:disable-next-line: no-floating-promises\r\n void this._getProductavailabilty(products);\r\n this._emitImpressionEvent(products.products);\r\n\r\n // Initialize reaction based on listPageState properties\r\n reaction(\r\n () => {\r\n return [listPageState.activeFilters && listPageState.activeFilters.length, listPageState.currentPageNumber, listPageState.sortingCritera && listPageState.sortingCritera.Columns && listPageState.sortingCritera.Columns.length];\r\n },\r\n () => {\r\n const input = new GetFullProductsByCollectionInput(\r\n listPageState.pageType,\r\n this.props.context.request.apiSettings,\r\n { Paging: { Top: this.props.config.itemsPerPage, Skip: Math.max((listPageState.pageSize * (listPageState.currentPageNumber || 0)), 0) }, count: true, Sorting: listPageState.sortingCritera || {} },\r\n listPageState.activeFilters || [],\r\n +(this.props.context.request.urlTokens.itemId || 0),\r\n this.props.context.request.query && this.props.context.request.query.q);\r\n\r\n getCollectionProducts(input, this.props.context.actionContext).then(productResults => {\r\n listPageState.activeProducts = productResults.products;\r\n listPageState.totalProductCount = productResults.count || this._initialProductResultCount;\r\n // tslint:disable-next-line: no-floating-promises\r\n void this._getProductavailabilty(productResults);\r\n this._emitImpressionEvent(products.products);\r\n }).catch(e => this.props.telemetry.exception(e));\r\n }\r\n );\r\n });\r\n });\r\n });\r\n });\r\n\r\n this._updateViewport();\r\n }\r\n\r\n public componentDidMount(): void {\r\n // tslint:disable-next-line: no-typeof-undefined\r\n if (typeof window !== 'undefined' && window.addEventListener) {\r\n window.addEventListener('resize', this._updateViewport);\r\n this._updateViewport();\r\n }\r\n }\r\n\r\n public componentWillUnmount(): void {\r\n // tslint:disable-next-line: no-typeof-undefined\r\n if (typeof window !== 'undefined' && window.addEventListener) {\r\n window.removeEventListener('resize', this._updateViewport);\r\n }\r\n }\r\n\r\n public usePNGImageSetting = (viewports: IImageSettingsViewports): IImageSettingsViewports => {\r\n const modifiedViewports = viewports;\r\n if (modifiedViewports?.xs?.q) {\r\n modifiedViewports.xs.q = modifiedViewports.xs.q.replace('f=jpg', 'f=png');\r\n }\r\n if (modifiedViewports?.sm?.q) {\r\n modifiedViewports.sm.q = modifiedViewports.sm.q.replace('f=jpg', 'f=png');\r\n }\r\n if (modifiedViewports?.md?.q) {\r\n modifiedViewports.md.q = modifiedViewports.md.q.replace('f=jpg', 'f=png');\r\n }\r\n if (modifiedViewports?.lg?.q) {\r\n modifiedViewports.lg.q = modifiedViewports.lg.q.replace('f=jpg', 'f=png');\r\n }\r\n if (modifiedViewports?.xl?.q) {\r\n modifiedViewports.xl.q = modifiedViewports.xl.q.replace('f=jpg', 'f=png');\r\n }\r\n\r\n return modifiedViewports;\r\n };\r\n\r\n public render(): JSX.Element {\r\n const { imageSettings, className, paragraph, showPagination } = this.props.config;\r\n const { resources, telemetry, data } = this.props;\r\n const products = (this.props.data.listPageState.result && this.props.data.listPageState.result.activeProducts) || [];\r\n let errorText = '';\r\n if (!products || products.length === 0) {\r\n errorText = this._pageType === 'Category' ? resources.resultCategoryNotFoundText : resources.resultSearchNotFoundText;\r\n }\r\n\r\n const categoryHierarchy = (data.category && data.category.result) || undefined;\r\n const passedProps = { ...this.props, categoryHierarchy };\r\n const productsComponent = (\r\n \r\n );\r\n // category-description 1.0\r\n const categoryDescription = this._getCategoryDescription(paragraph);\r\n\r\n const searchResultContainerViewProps = {\r\n ...this.props,\r\n products: productsComponent,\r\n TitleViewProps: this._getCollectionTitle(),\r\n categoryHierarchy: this._getCategoryHierarchy(),\r\n refineMenu: this._getRefineMenu(),\r\n className: classnames('ms-search-result-container', className),\r\n SearchResultContainer: {\r\n moduleProps: this.props,\r\n className: classnames('ms-search-result-container', className)\r\n },\r\n sortByOptions: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 && this.showSortByDropdown && this.props.config.showSortBy ? this._getSortingDropDown() : null,\r\n pagination: showPagination ? this._getPagination() : '',\r\n ProductsContainer: { className: 'ms-search-result-container__Products' },\r\n ProductSectionContainer: { className: 'ms-search-result-container__product-section' },\r\n CategoryNavContainer: { className: 'ms-search-result-container__category-nav-section' },\r\n RefineAndProductSectionContainer: { className: 'ms-search-result-container__refine-product-section' },\r\n choiceSummary: this._getChoiceSummary(),\r\n modalToggle: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 ?\r\n (\r\n \r\n ) : null,\r\n searchResultModal: this._getSearchResultModal(),\r\n isMobile: this.isMobile,\r\n errorMessage: errorText && (\r\n \r\n ),\r\n categoryDescription: categoryDescription\r\n };\r\n return this.props.renderView(searchResultContainerViewProps) as React.ReactElement;\r\n }\r\n\r\n private _addSortByDropdownOptions = (): void => {\r\n if (this.props.config.showSortingByRelevance) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionRelevanceDesc, value: this.props.resources.sortByOptionRelevanceDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if (this.props.config.showSortingByName) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionNameAsc, value: this.props.resources.sortByOptionNameAsc });\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionNameDesc, value: this.props.resources.sortByOptionNameDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if (this.props.config.showSortingByPrice) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionPriceAsc, value: this.props.resources.sortByOptionPriceAsc });\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionPriceDesc, value: this.props.resources.sortByOptionPriceDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if (this.props.config.showSortingByRating) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionRatingDesc, value: this.props.resources.sortByOptionRatingDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n };\r\n\r\n private _getSearchResultModal = (): ISearchResultModalViewProps => {\r\n const { resources } = this.props;\r\n return SearchResultModal(\r\n {\r\n resources: {\r\n modalCloseButtonText: resources.modalCloseButtonText,\r\n modalTitle: resources.modalTitle\r\n },\r\n isOpen: this.state.modalIsOpen,\r\n returnRef: this._modalToggleRef,\r\n onModalToggle: this._toggleModal\r\n });\r\n };\r\n\r\n private _getCollectionTitle = (): ITitleViewProps => {\r\n const { data, context, resources } = this.props;\r\n\r\n let collectionTitle: string | undefined = '';\r\n if (context && context.request && context.request.query && context.request.query.q) {\r\n collectionTitle = `\"${context.request.query.q}\"`;\r\n } else {\r\n collectionTitle = (data.category.result && SmweSearchResultContainer.getFriendlyName(context.request.locale, data.category.result.NameTranslations)) ||\r\n (data.category.result && data.category.result.Name);\r\n }\r\n let productCountText = '';\r\n let productCountNumber: number | undefined;\r\n if (data.listPageState && data.listPageState.result && data.listPageState.result.totalProductCount !== undefined) {\r\n productCountNumber = data.listPageState.result.totalProductCount;\r\n } else if (data.products && data.products.result) {\r\n productCountNumber = data.products.result.count;\r\n }\r\n\r\n if (productCountNumber && productCountNumber !== 0) {\r\n productCountText = productCountNumber !== 1 ? format(this.props.resources.numberOfProducts, productCountNumber) : this.props.resources.oneProduct;\r\n } else {\r\n productCountText = format(this.props.resources.numberOfProducts, 0);\r\n }\r\n const titlePrefix = ;\r\n const titleText = collectionTitle && <Title className='ms-search-result__collection-title-text' text={collectionTitle} />;\r\n const titleCount = <Title className='ms-search-result__collection-title-count' text={productCountText} />;\r\n\r\n return {\r\n TitleContainer: { className: 'ms-search-result-container__title' },\r\n title: {\r\n titlePrefix: titlePrefix,\r\n titleText: titleText,\r\n titleCount: titleCount\r\n }\r\n };\r\n\r\n };\r\n private _getCategoryHierarchy = (): ICategoryHierarchyViewProps => {\r\n const { data } = this.props;\r\n const categoryHierarchy = data.categoryHierarchy.result;\r\n const categoryLinks =\r\n categoryHierarchy && categoryHierarchy.map((value: CategoryHierarchyData, index: number) => {\r\n\r\n return (\r\n <Link\r\n key={index}\r\n text={value.Name}\r\n ariaLabel={`${this.props.resources.categoryLinkAriaLabel} ${value.Name}`}\r\n href={value.Url}\r\n />\r\n );\r\n });\r\n const categoryLinkSeparator = <Separator separator='/' />;\r\n\r\n return {\r\n CategoryHierarchyContainer: { tag: 'nav', className: 'ms-search-result-container__category-hierarchy' },\r\n categoryHierarchyList: categoryLinks,\r\n categoryHierarchySeparator: categoryLinkSeparator\r\n };\r\n\r\n };\r\n\r\n private _getSortingDropDown = (): ISortByViewProps => {\r\n const { resources } = this.props;\r\n const activeDropdown = this._getCurrentlySelectedOption() || this.state.sortingState.selectedSortByOption;\r\n const dropdown = (\r\n <LabeledDropdown\r\n labelClassname='reviews-list-sort-by'\r\n labelText={resources.sortByDropdownLabel}\r\n dropdownId='categorySortByDropdown'\r\n dropdownClassname='reviews-list-dropdown'\r\n toggleColor='link'\r\n dropdownOptions={this.sortByDropdownOptions}\r\n selectedOption={activeDropdown}\r\n onSelectOption={this._updateSortByDropdown}\r\n ref={this._sortAndFilterContainerRef}\r\n />);\r\n return {\r\n SortingContainer: { className: 'ms-search-result-container__Sort-by-category' },\r\n sortByDropDown: dropdown\r\n };\r\n };\r\n\r\n private _getPagination = (): React.ReactNode => {\r\n const { config, context, data, resources } = this.props;\r\n const listPageState = data && data.listPageState && data.listPageState.result;\r\n const fullUrl = getCurrentUrl(context.request);\r\n const itemsPerPage = config.itemsPerPage || 10;\r\n const skipCount = listPageState && listPageState.currentPageNumber !== null ?\r\n (listPageState.currentPageNumber * (this.props.config.itemsPerPage || 10)) :\r\n ((this.props.context.request.query && +this.props.context.request.query.skip) || 0);\r\n const totalItems = listPageState && listPageState.totalProductCount || 0;\r\n const previousText = resources.flipperPrevious;\r\n const nextText = resources.flipperNext;\r\n const totalActiveProducts = listPageState?.activeProducts?.length || 0;\r\n\r\n if (totalItems <= itemsPerPage) {\r\n return null;\r\n }\r\n if (totalActiveProducts <= 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <UncontrolledPagination\r\n className='ms-search-result-container__pagination'\r\n role='navigation'\r\n aria-label={resources.paginationAriaLabel}\r\n url={fullUrl.href}\r\n qsp={'skip'}\r\n items={totalItems}\r\n itemsPerPage={itemsPerPage}\r\n startingItem={skipCount}\r\n previousText={<div className='msc-pagination__prev'><span className='ms-search-result__pagination-left' aria-hidden='true' /><span className='prev-text'>{previousText}</span></div>}\r\n nextText={<div className='msc-pagination__next'><span className='next-text'>{nextText}</span><span className='ms-search-result__pagination-right' aria-hidden='true' /></div>}\r\n previousAriaLabel={previousText}\r\n nextAriaLabel={nextText}\r\n />);\r\n };\r\n\r\n private _getRefineMenu = (): IRefineMenuViewProps => {\r\n const { data, context } = this.props;\r\n const tempRangeTypeTODO = context.request.query && context.request.query.inputRange ? 'input' : 'slider';\r\n const validRefiners = this._refinersFiltered && data.refiners.result && data.refiners.result.filter(refiner => {\r\n return refiner.Values.length > 0;\r\n });\r\n\r\n const activeRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n const subMenus = validRefiners && validRefiners.map((productRefinerHierarchy: IProductRefinerHierarchy, index: number) => {\r\n return (data.listPageState.result?.totalProductCount !== 0 ?\r\n (\r\n <RefineSubmenu\r\n highestLevelRefinerText={this.props.config.highestLevelItem}\r\n productRefinerHierarchy={productRefinerHierarchy}\r\n selectedRefinerValues={activeRefiners}\r\n refineItemCommonProps={this._refineItemCommonProps}\r\n minValueSliderThumbAriaLabel={this.props.resources.minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={this.props.resources.maxValueSliderThumbAriaLabel}\r\n refinerMinimizeText={this.props.resources.refinerMinimizeText}\r\n refinerExpandText={this.props.resources.refinerExpandText}\r\n minimizedRefiners={this.props.config.minimizedRefiners}\r\n key={index}\r\n onUpdateRefiners={this._onUpdateRefiners}\r\n urlBuilder={this._buildRefinerUrl}\r\n isDisabled={false}\r\n isExpandedOnInitialLoad={this.props.config.collapseRefiners ? false : true}\r\n tempRangeTypeTODO={tempRangeTypeTODO}\r\n context={context}\r\n moduleId={this.props.id}\r\n moduleTypeName={this.props.typeName}\r\n />) : null\r\n );\r\n });\r\n\r\n return {\r\n RefineMenuContainer: { className: 'ms-search-result-container__refine-menu' },\r\n RefinerSectionContainer: { className: 'ms-search-result-container__refiner-section' },\r\n refiners: subMenus || undefined // type shenanigans\r\n };\r\n\r\n };\r\n\r\n private _getChoiceSummary = (): React.ReactNode => {\r\n const { resources, data, telemetry } = this.props;\r\n const selectedRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n return (\r\n <ChoiceSummary\r\n classNames='ms-choice-summary-by-category'\r\n clearAllText={resources.clearAllText}\r\n label={resources.choiceSummaryLabel}\r\n selectedChoices={selectedRefiners}\r\n // @ts-ignore: NOTE Type-unsafe line below, null refinersByCategoryHierarchy case not handled\r\n refinerHierarchy={data.refiners.result}\r\n choiceFormat={resources.choiceFormat}\r\n choiceRangeValueFormat={resources.choiceRangeValueFormat}\r\n telemetry={telemetry}\r\n onChoiceClicked={this._onChoiceClicked}\r\n urlBuilder={this._buildRefinerUrlForChoiceSummary}\r\n choiceAriaLabel={resources.choiceAriaLabel}\r\n />\r\n );\r\n\r\n };\r\n\r\n private _updateSortByDropdown = (notification: ILabeledDropdownOnChangeNotification): void => {\r\n const { context } = this.props;\r\n const requestContext = context && context.request;\r\n const actionContext = context && context.actionContext;\r\n\r\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\r\n const error = `[sort-by-category] cannot sort without context: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\r\n this.props.telemetry.warning(error);\r\n }\r\n\r\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), undefined, [this._getSortColumnFromSelectedOption(notification.selectedOption)], undefined));\r\n transaction(() => {\r\n this.props.data.listPageState.result!.currentPageNumber = 0;\r\n this.props.data.listPageState.result!.sortingCritera = { Columns: [this._getSortColumnFromSelectedOption(notification.selectedOption)] };\r\n });\r\n };\r\n\r\n private _getSortColumnFromSelectedOption = (option: ILabeledDropdownOption): SortColumn => {\r\n const { data } = this.props;\r\n\r\n if (!data.searchConfiguration.result) {\r\n return {};\r\n }\r\n\r\n const mappedConfiguration = data.searchConfiguration.result.find((searchConfiguration) => { return searchConfiguration.key === option.key; });\r\n\r\n if (mappedConfiguration) {\r\n return mappedConfiguration.sortColumn;\r\n }\r\n\r\n return {};\r\n };\r\n\r\n private _getCurrentlySelectedOption = (): ILabeledDropdownOption | undefined => {\r\n const { data } = this.props;\r\n const sortCriteria = data.listPageState.result && data.listPageState.result.sortingCritera;\r\n\r\n const activeSortColumn =\r\n (sortCriteria?.Columns?.length && sortCriteria.Columns[0]) ||\r\n (parseQueryParam<SortColumn[]>('sorting', this.props.context.request) || [])[0];\r\n\r\n if (activeSortColumn && data.searchConfiguration.result) {\r\n const activeMappedConfig = data.searchConfiguration.result.find((mappedSearchConfig) => {\r\n return (mappedSearchConfig.sortColumn.ColumnName === activeSortColumn.ColumnName) &&\r\n (mappedSearchConfig.sortColumn.IsDescending === activeSortColumn.IsDescending);\r\n });\r\n if (activeMappedConfig) {\r\n return this.sortByDropdownOptions.find((dropdownOption) => dropdownOption.key === activeMappedConfig.key);\r\n }\r\n }\r\n\r\n return;\r\n };\r\n\r\n private _onUpdateRefiners = (itemToggleNotification: IRefineItemToggleNotification): void => {\r\n const { context } = this.props;\r\n const requestContext = context && context.request;\r\n const actionContext = context && context.actionContext;\r\n\r\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\r\n const error = `Refine menu cannot refine search criteria: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\r\n this.props.telemetry.warning(error);\r\n }\r\n\r\n const updatedRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result && this.props.data.listPageState.result.activeFilters || []);\r\n\r\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), updatedRefinementCriteria));\r\n transaction(() => {\r\n this.props.data.listPageState.result!.currentPageNumber = 0;\r\n this.props.data.listPageState.result!.activeFilters = updatedRefinementCriteria;\r\n });\r\n };\r\n\r\n private _buildRefinerUrl = (itemToggleNotification: IRefineItemToggleNotification): string => {\r\n if (this.props.data.listPageState.result) {\r\n const newRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result.activeFilters || []);\r\n\r\n return buildListPageUrl(getCurrentUrl(this.props.context.request), newRefinementCriteria);\r\n } else {\r\n this.props.telemetry.warning(`[buildRefinerQueryString]List Page State Not available, unable to build refiner URL`);\r\n return '';\r\n }\r\n };\r\n\r\n private _onChoiceClicked = (notification: IChoiceSummaryClickNotification): void => {\r\n const { data, telemetry } = this.props;\r\n\r\n if (!data.listPageState.result) {\r\n telemetry.warning('[choice-summary-by-category._onChoiceClicked]ListPageState unavailable, unable to update refiners.');\r\n return;\r\n }\r\n\r\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n\r\n if (!notification.clearAll) {\r\n const selectedChoice = notification.choiceClicked;\r\n if (!selectedChoice) {\r\n telemetry.warning('[choice-summary-by-category._onChoiceClicked] Choice could not be determined');\r\n return;\r\n }\r\n currentRefinementCriteria = currentRefinementCriteria.filter(\r\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedChoice, selectedCriterion)\r\n );\r\n } else {\r\n currentRefinementCriteria = [];\r\n\r\n // set focus to sort and filter\r\n const dropdownElementId = this._sortAndFilterContainerRef.current && this._sortAndFilterContainerRef.current.props.dropdownId;\r\n const dropdownElement = dropdownElementId && document.getElementById(dropdownElementId);\r\n setTimeout(() => {\r\n dropdownElement && dropdownElement.focus();\r\n },\r\n 50);\r\n }\r\n\r\n const fullUrl = getCurrentUrl(this.props.context.request);\r\n window.history.pushState({}, '', buildListPageUrl(fullUrl, currentRefinementCriteria));\r\n data.listPageState.result.currentPageNumber = 0;\r\n data.listPageState.result.activeFilters = currentRefinementCriteria;\r\n };\r\n\r\n private _buildRefinerUrlForChoiceSummary = (selectedRefiner: ProductRefinerValue, isClearAll: boolean): string => {\r\n const { data, telemetry } = this.props;\r\n const fullUrl = getCurrentUrl(this.props.context.request);\r\n\r\n if (!data.listPageState.result) {\r\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl]ListPageState unavailable, unable to create refiner URL.');\r\n return fullUrl.href;\r\n }\r\n\r\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n\r\n if (!isClearAll) {\r\n if (!selectedRefiner) {\r\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl] URL for Choice could not be determined');\r\n return fullUrl.href;\r\n }\r\n currentRefinementCriteria = currentRefinementCriteria.filter(\r\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedRefiner, selectedCriterion)\r\n );\r\n } else {\r\n currentRefinementCriteria = [];\r\n }\r\n\r\n return buildListPageUrl(fullUrl, currentRefinementCriteria);\r\n };\r\n\r\n private _getViewport(): GridSize {\r\n const { context } = this.props;\r\n\r\n // always render in mobile viewport on a mobile device\r\n if (context.request && context.request.device && context.request.device.Type === 'Mobile') {\r\n return 'xs';\r\n }\r\n\r\n if (MsDyn365.isBrowser && window.innerWidth) {\r\n const gridSettings = context.request.gridSettings;\r\n if (gridSettings) {\r\n if (gridSettings.xs && window.innerWidth <= gridSettings.xs.w) {\r\n return 'xs';\r\n } else if (gridSettings.sm && window.innerWidth <= gridSettings.sm.w) {\r\n return 'sm';\r\n } else if (gridSettings.md && window.innerWidth <= gridSettings.md.w) {\r\n return 'md';\r\n } else if (gridSettings.lg && window.innerWidth <= gridSettings.lg.w) {\r\n return 'lg';\r\n } else {\r\n return 'xl';\r\n }\r\n }\r\n }\r\n\r\n return 'lg';\r\n }\r\n\r\n private _toggleModal(): void {\r\n this.setState({\r\n modalIsOpen: !this.state.modalIsOpen\r\n });\r\n }\r\n\r\n private _updateViewport(): void {\r\n this._viewport = this._getViewport();\r\n\r\n if (this.state.modalIsOpen && !this.isMobile) {\r\n this._toggleModal();\r\n }\r\n }\r\n\r\n private _getCategoryDescription(paragraph: RichText | undefined): JSX.Element | undefined {\r\n\r\n if (paragraph && paragraph.length > 0) {\r\n return <RichTextComponent className='category-description' text={paragraph} />;\r\n }\r\n return undefined;\r\n }\r\n\r\n private get _subscriptionQuantityLimit(): number {\r\n return this.props.config.quantityLimit || 12; // 12 is default\r\n }\r\n\r\n private get _shouldDisableQuantityAddition(): boolean {\r\n const { checkoutState: { result: checkoutState } } = this.props.data;\r\n if (!checkoutState) { return false; }\r\n const filteredLines = filterCartLines(checkoutState.checkoutCart.cart);\r\n let amount = 0;\r\n filteredLines.subscriptionLines.forEach(line => amount += line.Quantity || 0);\r\n if (amount >= this._subscriptionQuantityLimit) { return false; }\r\n return true;\r\n }\r\n\r\n private async _getProductavailabilty(products: IFullProductsSearchResultsWithCount): Promise<void> {\r\n if (products && products.count && products.count > 0) {\r\n const productIds: number[] = [];\r\n products.products.forEach((product) => {\r\n productIds.push(product.RecordId);\r\n });\r\n const availabilityAll = await getEstimatedAvailabilityAsync({ callerContext: this.props.context.actionContext }, { ProductIds: productIds, DefaultWarehouseOnly: true });\r\n const formattedResponse = availabilityAll.ProductWarehouseInventoryAvailabilities?.map((product) => {\r\n return { ProductId: product.ProductId, AvailableQuantity: product.PhysicalAvailable, ExtensionProperties: product.ExtensionProperties };\r\n }) as ProductAvailableQuantity[];\r\n this.setState({ productAvailability: formattedResponse });\r\n }\r\n }\r\n\r\n //----------------------------------------------------------\r\n //----------------------------------------------------------\r\n private _emitImpressionEvent(products: ProductSearchResult[]): void {\r\n const impressions = products.map(product => ({\r\n product,\r\n attributes: CommerceAttributesParser.getParsedAttributes(product.AttributeValues || []),\r\n }));\r\n\r\n publish('impression', {\r\n products: impressions,\r\n\r\n list: 'Category Page', // Could be Search Results if we ever enable search results pages\r\n category: this.props.data.category.result?.Name,\r\n context: this.props.context,\r\n });\r\n }\r\n}\r\n","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\nimport { ISmweSearchResultContainerProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container.props.autogenerated';\r\n\r\n// tslint:disable-next-line:cyclomatic-complexity\r\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps & ISmweSearchResultContainerProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {/*TODO remove after final testing */}\r\n {/*categoryHierarchy && renderCategoryHierarchy(categoryHierarchy)*/}\r\n {renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && !props.config.pulldownRefiners && choiceSummary}\r\n {showRefiners && !props.config.pulldownRefiners && modalToggle}\r\n {showRefiners && !props.config.pulldownRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && !props.config.pulldownRefiners && refineMenu && renderRefiner(refineMenu)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefinerPulldown = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer, pulldownText, activeRefiners } = props;\r\n const activeRefinersText = getActiveRefinersText(activeRefiners);\r\n const dynamicPulldownText = getPulldownText(activeRefinersText, pulldownText);\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} aria-expanded='false' className='ms-search-result-container__refiner-pulldown-button' id='refiner-pulldown-button'>\r\n <span className='ms-search-result-container__refiner-pulldown-button-content' id='refiner-pulldown-button-content'>{dynamicPulldownText}</span>\r\n </button>\r\n <div className='ms-search-result-container__refiner-pulldown-container pulldown-hide' id='refiner-pulldown-container'>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-close-pulldown-button'>Close</button>\r\n </div>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst getPulldownText = (activeRefiners: string, buttonText: string | undefined): string => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n const spanElement = document.getElementById('refiner-pulldown-button-content');\r\n if (buttonElement && spanElement) {\r\n if (buttonElement.className === 'ms-search-result-container__refiner-pulldown-button refiner-pulldown-button-expanded' || !activeRefiners) {\r\n return spanElement.innerText = buttonText || '';\r\n } else {\r\n return spanElement.innerText = activeRefiners;\r\n }\r\n }\r\n return '';\r\n};\r\n\r\nconst togglePulldown = (activeRefiners: string, buttonText: string | undefined): void => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n var expanded = buttonElement?.getAttribute('aria-expanded');\r\n if (buttonElement) {\r\n buttonElement.classList.toggle('refiner-pulldown-button-expanded');\r\n getPulldownText(activeRefiners, buttonText);\r\n }\r\n const pulldownElement = document.getElementById('refiner-pulldown-container');\r\n if (pulldownElement) {\r\n pulldownElement.classList.toggle('pulldown-hide');\r\n }\r\n if (expanded === 'false') {\r\n buttonElement?.setAttribute('aria-expanded', 'true');\r\n }\r\n else if (buttonElement?.classList.contains('refiner-pulldown-button-expanded')) {\r\n buttonElement?.setAttribute('aria-expanded', 'true');\r\n }\r\n else {\r\n buttonElement?.setAttribute('aria-expanded', 'false');\r\n }\r\n if (pulldownElement?.classList.contains('pulldown-hide') && buttonElement) {\r\n buttonElement?.setAttribute('aria-expanded', 'false');\r\n }\r\n\r\n};\r\n\r\nconst getActiveRefinersText = (activeRefiners: ProductRefinerValue[]): string => {\r\n let formatedActiveRefiners = '';\r\n activeRefiners.forEach(refiner => {\r\n if (refiner.UnitText === 'USD') {\r\n formatedActiveRefiners += `$${refiner.LeftValueBoundString}-$${refiner.RightValueBoundString} / `;\r\n } else if (refiner.LeftValueBoundString) {\r\n formatedActiveRefiners += `${refiner.LeftValueBoundString} / `;\r\n }\r\n });\r\n // removes trailing slash and whitespace\r\n formatedActiveRefiners = formatedActiveRefiners.substring(0, formatedActiveRefiners.length - 2);\r\n return formatedActiveRefiners;\r\n};\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nexport default SearchResultContainerView;","import {\r\n Button,\r\n Modal,\r\n ModalBody,\r\n ModalFooter,\r\n ModalHeader\r\n} from '@msdyn365-commerce-modules/utilities';\r\nimport React from 'react';\r\n\r\nexport interface ISearchResultModalViewProps {\r\n modal: React.ReactElement;\r\n modalHeader: React.ReactElement;\r\n modalFooter: React.ReactElement;\r\n modalBody: React.ReactElement;\r\n}\r\n\r\ninterface IModalToggleProps {\r\n innerRef: React.RefObject<HTMLButtonElement> | undefined;\r\n id: string;\r\n text: string;\r\n ariaLabel: string;\r\n onClick(): void;\r\n}\r\n\r\nexport interface ISearchResultModalResources {\r\n modalTitle: string;\r\n modalCloseButtonText: string;\r\n}\r\n\r\nexport interface ISearchResultModalProps {\r\n resources: ISearchResultModalResources;\r\n isOpen: boolean;\r\n returnRef: React.RefObject<HTMLButtonElement> | undefined;\r\n onModalToggle():void;\r\n}\r\n\r\nexport const ModalToggle: React.FC<IModalToggleProps> = (props: IModalToggleProps) => {\r\n const {text, onClick, ariaLabel, innerRef, id} = props;\r\n return <button id={id} className='msc-button' aria-label={ariaLabel} onClick={onClick} ref={innerRef}>{text}</button>;\r\n};\r\n\r\nexport const SearchResultModal = (props: ISearchResultModalProps):ISearchResultModalViewProps => {\r\n return {\r\n modal: modalNode(props),\r\n modalHeader: modalHeaderNode(props),\r\n modalFooter: modalFooterNode(props),\r\n modalBody: <ModalBody className='msc-review-modal-body'/>\r\n };\r\n};\r\n\r\nconst modalNode = (props: ISearchResultModalProps) => {\r\n return (\r\n <Modal\r\n autoFocus={true}\r\n applicationNode={'renderPage'}\r\n returnFocusRef={props.returnRef}\r\n isOpen={props.isOpen}\r\n toggle={props.onModalToggle}\r\n className={'msc-search-result-modal'}\r\n zIndex={1050}\r\n />\r\n );\r\n};\r\n\r\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\r\n return (\r\n <ModalHeader toggle={props.onModalToggle}>\r\n {props.resources.modalTitle}\r\n </ModalHeader>\r\n );\r\n};\r\n\r\nconst modalFooterNode = (props: ISearchResultModalProps) => {\r\n return (\r\n <ModalFooter>\r\n <Button onClick={props.onModalToggle} className='ms-sort-and-filter-modal-close'>\r\n {props.resources.modalCloseButtonText}\r\n </Button>\r\n </ModalFooter>\r\n );\r\n};","// TODO: Need to find replacement for GetActiveCartInput retail actions in 2.0\r\n// import { getActiveCart, GetActiveCartInput } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n// TODO: may serve as replacement, need to test functionality\r\nimport { BaseCartState, getCartState, GlobalStateInput, ICartState } from '@msdyn365-commerce/global-state';\r\n\r\nimport { Modal, ModalBody, ModalHeader } from '@msdyn365-commerce-modules/utilities';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport * as React from 'react';\r\nimport Button from 'reactstrap/lib/Button';\r\n\r\nexport interface IProductLightboxProps {\r\n id: string;\r\n width: number;\r\n height: number;\r\n productLightboxHref: string;\r\n iframeSrc?: string;\r\n buttonText?: string;\r\n lightboxClassName?: string;\r\n iframeClassName?: string;\r\n context: ICoreContext;\r\n}\r\n\r\nexport interface IProductAttributeProps {\r\n TextValue: string;\r\n Name: string;\r\n}\r\n\r\ninterface IProductLightboxData {\r\n isOpen: boolean;\r\n}\r\n\r\n/**\r\n * Lightbox Component\r\n */\r\nexport default class ProductLightbox extends React.PureComponent<IProductLightboxProps, IProductLightboxData> {\r\n constructor(props: IProductLightboxProps) {\r\n super(props);\r\n this.state = { isOpen: false };\r\n }\r\n\r\n public componentDidMount(): undefined {\r\n window.addEventListener && window.addEventListener('message', this.onMessage);\r\n return;\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { lightboxClassName, iframeClassName } = this.props;\r\n // @ts-ignore\r\n const iframeSrcObj = (new URL(this.props.iframeSrc));\r\n const iframeId = `iframe-${this.props.id}`;\r\n return (\r\n <div className={lightboxClassName && lightboxClassName !== ''? lightboxClassName : 'product-lightbox'}>\r\n {this._launchLightboxButton(this.props.buttonText)}\r\n {(this.state.isOpen) && <Modal\r\n autoFocus={true}\r\n fade={true}\r\n isOpen={this.state.isOpen}\r\n horizontalPosition={'center'}\r\n verticalPosition={'center'}\r\n zIndex={1000}\r\n toggle={this._closeModal}\r\n applicationNode={'rsg-root'}\r\n aria-labelledby={iframeId}\r\n >\r\n <ModalHeader toggle={this._closeModal}/>\r\n <ModalBody>\r\n <div className={iframeClassName && iframeClassName !== '' ? iframeClassName : 'product-iframe'}>\r\n {/* tslint:disable-next-line: react-iframe-missing-sandbox */}\r\n <iframe\r\n className={iframeClassName && iframeClassName !== '' ? `${iframeClassName}-content` : 'iframe-module-content'}\r\n src={iframeSrcObj.href}\r\n width={this.props.width}\r\n height={this.props.height}\r\n title={this.props.buttonText}\r\n id={iframeId}\r\n />\r\n </div>\r\n </ModalBody>\r\n </Modal>}\r\n </div>\r\n );\r\n }\r\n\r\n private onMessage = async (e: MessageEvent) => {\r\n if (!e.isTrusted || e.origin !== window.origin) {\r\n return;\r\n }\r\n // @ts-ignore\r\n const iframeSrcObj = (new URL(this.props.iframeSrc));\r\n\r\n // TODO: Need to find replacement for GetActiveCartInput retail actions in 2.0\r\n // if (e.data.url === iframeSrcObj.href) {\r\n // setTimeout(async () => {\r\n // const context = this.props.context;\r\n // const cartInput = new GetActiveCartInput(context.request.apiSettings, true);\r\n // const newCart = await getActiveCart(cartInput, context.actionContext);\r\n // context.actionContext.update(cartInput, newCart);\r\n // }, 10);\r\n // }\r\n\r\n // TODO: may work as replacement, need to test\r\n if (e.data.url === iframeSrcObj.href) {\r\n setTimeout(async () => {\r\n const context = this.props.context;\r\n const cartInput = new GlobalStateInput<ICartState>('CARTSTATE', BaseCartState, context.actionContext.requestContext.apiSettings);\r\n const newCart = await getCartState(context.actionContext);\r\n context.actionContext.update(cartInput, newCart);\r\n await newCart.refreshCart({});\r\n }, 10);\r\n }\r\n };\r\n\r\n private _launchLightboxButton(buttonText: string | undefined): JSX.Element | null {\r\n return (<Button id={this.props.id} className='launch-lightbox-button' onClick={this._openModal} aria-label=\"Click here to view more details about this product\">{buttonText ? buttonText : 'Quick View'}</Button>);\r\n }\r\n\r\n private _closeModal = () => {\r\n this.setState(prevState => ({\r\n isOpen: !prevState.isOpen\r\n }));\r\n const quickView: HTMLElement | null = document.getElementById(this.props.id);\r\n quickView!.focus();\r\n };\r\n private _openModal = () => {\r\n this.setState(prevState => ({\r\n isOpen: !prevState.isOpen\r\n }));\r\n };\r\n}","import { getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { RatingComponent } from '@msdyn365-commerce/components';\r\nimport { IComponent, IComponentProps, ICoreContext, IGridSettings, IImageData, IImageSettings, Image, msdyn365Commerce, RichTextComponent } from '@msdyn365-commerce/core';\r\nimport { ICartState, ICheckoutState } from '@msdyn365-commerce/global-state';\r\nimport { AsyncResult, AttributeValue, ProductAvailableQuantity, ProductPrice, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport classnames from 'classnames';\r\nimport React from 'react';\r\nimport AcclaimRatingsDisplay from '../modules/acclaim-ratings/acclaim-ratings-display';\r\nimport { ISmweProductCollectionProps } from '../modules/smwe-product-collection/smwe-product-collection.props.autogenerated';\r\nimport { ISmweSearchResultContainerProps } from '../modules/smwe-search-result-container/smwe-search-result-container.props.autogenerated';\r\nimport { CartUtilities } from '../Utilities/cart-utils';\r\nimport { BusLoader, LoadBus } from '../Utilities/event-bus';\r\nimport ProductLightbox, { IProductLightboxProps } from '../Utilities/product-lightbox';\r\nimport { filterCartLines } from '../Utilities/subscription-manager';\r\n\r\nexport interface ISmweSearchResultContainerParentProps extends ISmweSearchResultContainerProps<{}> {\r\n categoryHierarchy: CategoryHierarchy | undefined;\r\n}\r\n\r\nexport interface ISmweProductCollectionParentProps extends ISmweProductCollectionProps<{}> {\r\n categoryHierarchy: undefined;\r\n}\r\n\r\nexport interface IProductComponentProps extends IComponentProps<{ product?: ProductSearchResult }> {\r\n checkoutState?: AsyncResult<ICheckoutState>;\r\n cart?: AsyncResult<ICartState>;\r\n displayQuantitySlider?: boolean;\r\n disableQuantitySlider?: boolean;\r\n maxAdditionLimit?: number;\r\n className?: string;\r\n imageSettings?: IImageSettings;\r\n savingsText?: string;\r\n freePriceText?: string;\r\n originalPriceText?: string;\r\n currentPriceText?: string;\r\n ratingAriaLabel?: string;\r\n subscriptionBtnText?: string;\r\n parentProps: ISmweSearchResultContainerParentProps | ISmweProductCollectionParentProps;\r\n addToCart?: boolean;\r\n addToCartText?: string;\r\n giftCardText?: string;\r\n addToCartMessage?: string;\r\n showPrice?: boolean;\r\n availability?: ProductAvailableQuantity | undefined;\r\n clubPrice?: ProductPrice | undefined;\r\n showQuantityAsDropdown?: boolean;\r\n}\r\n\r\nexport interface IProductComponent extends IComponent<IProductComponentProps> { }\r\n\r\nconst PriceComponentActions = {\r\n};\r\nlet qtyAddedToCart: number = 0;\r\n\r\n// tslint:disable-next-line:cyclomatic-complexity\r\nconst ProductCard: React.FC<IProductComponentProps> = ({\r\n data,\r\n context,\r\n imageSettings,\r\n savingsText,\r\n freePriceText,\r\n originalPriceText,\r\n currentPriceText,\r\n ratingAriaLabel,\r\n typeName,\r\n id,\r\n parentProps,\r\n checkoutState,\r\n subscriptionBtnText,\r\n displayQuantitySlider,\r\n showPrice\r\n}) => {\r\n const {\r\n showStarRating,\r\n launchLightboxButtonText,\r\n productLightboxHref,\r\n productLightboxWidth,\r\n productLightboxHeight,\r\n productLightboxClassName,\r\n productLightboxIframeClassName,\r\n cardBanner\r\n } = parentProps.config;\r\n const product = data.product;\r\n const recordId = product?.RecordId;\r\n if (!product) {\r\n return null;\r\n }\r\n\r\n const productLightboxProps: IProductLightboxProps = {\r\n id: '',\r\n buttonText: launchLightboxButtonText,\r\n productLightboxHref: productLightboxHref,\r\n width: productLightboxWidth,\r\n height: productLightboxHeight,\r\n lightboxClassName: productLightboxClassName,\r\n iframeClassName: productLightboxIframeClassName,\r\n context: parentProps.context\r\n };\r\n\r\n if (productLightboxProps) {\r\n productLightboxProps.id = `product-placement-${recordId}`;\r\n const domainUrl = _getEndpoint(context && context.request.url.requestUrl.toString());\r\n if (productLightboxProps.productLightboxHref && productLightboxProps.productLightboxHref.indexOf('?') >= 0) {\r\n productLightboxProps.iframeSrc = `${domainUrl}${productLightboxProps.productLightboxHref}&productId=${recordId}`;\r\n } else {\r\n productLightboxProps.iframeSrc = `${domainUrl}${productLightboxProps.productLightboxHref}?productId=${recordId}`;\r\n }\r\n }\r\n\r\n let tastingNotes: AttributeValue | undefined;\r\n let appellation: AttributeValue | undefined;\r\n let banner: AttributeValue | undefined;\r\n let productType: AttributeValue | undefined;\r\n if (product.AttributeValues) {\r\n product.AttributeValues.forEach(attribute => {\r\n switch (attribute.Name) {\r\n case 'Tasting Notes':\r\n tastingNotes = attribute;\r\n break;\r\n case 'SLR Appellation':\r\n appellation = attribute;\r\n break;\r\n case 'Appellation':\r\n appellation = attribute;\r\n break;\r\n case cardBanner:\r\n banner = attribute;\r\n break;\r\n case 'Product Type':\r\n productType = attribute;\r\n break;\r\n default:\r\n }\r\n });\r\n }\r\n const ariaLabel = `${(appellation && appellation.TextValue) ? appellation.TextValue : ''} ${product.Name ? product.Name : ''} product page`;\r\n const imageProductClass = productType && productType.TextValue ? `product-type-${productType.TextValue.replace(/\\s+/g, '-').toLowerCase()}` : '';\r\n const productUrl = getProductPageUrlSync(product.Name || '', product.RecordId, context && context.actionContext, parentProps.categoryHierarchy);\r\n const isGiftCard = product.ItemId?.toLowerCase() === 'giftcard';\r\n let imageUrl = product.PrimaryImageUrl;\r\n if (isGiftCard && parentProps.app.config.giftCardImage) {\r\n imageUrl = parentProps.app.config.giftCardImage;\r\n }\r\n return (\r\n <>\r\n <a href={productUrl} aria-label={ariaLabel} className={`msc-product__details product-placement-content ${imageProductClass}`}>\r\n <div className='msc-product__image'>\r\n {renderProductPlacementImage(imageSettings, context.request.gridSettings, imageUrl, product.Name)}\r\n <div className='product-details'>\r\n {banner && renderAttribute(banner, 'product-details-banner')}\r\n <i className='fas fa-chevron-right' />\r\n <div className='product-details-header'>\r\n {renderAttribute(appellation, 'product-attribute appellation')}\r\n <h2 className='product-placement__item-title'>{product.Name}</h2>\r\n </div>\r\n {renderAttribute(tastingNotes, 'product-attribute description')}\r\n {showPrice && !displayQuantitySlider && product.Price && renderPrice(product.Price)}\r\n {recordId && renderAcclaim(recordId)}\r\n {showStarRating && renderRating(context, typeName, id, product.AverageRating, product.TotalRatings, ratingAriaLabel)}\r\n </div>\r\n </div>\r\n </a>\r\n {renderProductLightboxButton(productLightboxProps)}\r\n </>\r\n );\r\n};\r\n\r\nfunction renderRating(context: ICoreContext, typeName: string, id: string, avgRating?: number, totalRatings?: number, ariaLabel?: string): JSX.Element | null {\r\n if (!avgRating) {\r\n return null;\r\n }\r\n\r\n const numRatings = totalRatings && totalRatings.toString() || undefined;\r\n\r\n return (\r\n <RatingComponent\r\n context={context}\r\n id={id}\r\n typeName={typeName}\r\n avgRating={avgRating}\r\n ratingCount={numRatings}\r\n readOnly={true}\r\n ariaLabel={ariaLabel || ''}\r\n data={{}}\r\n />\r\n );\r\n}\r\n\r\nfunction renderProductPlacementImage(imageSettings?: IImageSettings, gridSettings?: IGridSettings, imageUrl?: string, altText?: string): JSX.Element | null {\r\n if (!imageUrl || !gridSettings || !imageSettings) {\r\n return null;\r\n }\r\n const img: IImageData = {\r\n src: imageUrl,\r\n altText: altText ? altText : ''\r\n };\r\n const imageProps = {\r\n gridSettings: gridSettings,\r\n imageSettings: imageSettings\r\n };\r\n return (\r\n <Image {...img} {...imageProps} loadFailureBehavior='empty' />\r\n );\r\n}\r\n\r\nfunction renderAttribute(attribute: AttributeValue | undefined, className: string | ''): JSX.Element | null {\r\n return (\r\n <div className={className}>\r\n {attribute && <RichTextComponent\r\n className='product-attribute-value'\r\n text={(attribute.TextValue !== undefined ? attribute.TextValue : '')}\r\n />}\r\n </div>\r\n );\r\n}\r\n\r\n// Render acclaim ratings if any\r\n// @FIXME/dg: Hardcoding the count and date/reviewer settings is bad!\r\nfunction renderAcclaim(recordId: number): JSX.Element | null {\r\n return (\r\n <AcclaimRatingsDisplay productID={recordId} numberToShow={1} showReviewer={true} showDate={false} />\r\n );\r\n}\r\n\r\nfunction renderPrice(price: number, className?: string, clubPrice?: number): JSX.Element | null {\r\n return (\r\n <div className={classnames('product-price', className)}>\r\n <span className='product-component-wrapper-price-default'>${price.toFixed(2).replace(/\\.00$/,'')}</span>\r\n {clubPrice && <span className='product-component-wrapper-price-club'>${clubPrice.toFixed(2).replace(/\\.00$/,'')} Club</span>}\r\n </div>\r\n );\r\n}\r\n\r\nfunction _getEndpoint(url: string | undefined): string | null {\r\n if (url) {\r\n const urlParts = url.split('/');\r\n return url.indexOf('//') > -1 ? `${urlParts[0]}//${urlParts[2]}` : urlParts[0];\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction renderProductLightboxButton(productLightboxProps: IProductLightboxProps | undefined): JSX.Element | null {\r\n if (!productLightboxProps) {\r\n return null;\r\n }\r\n\r\n return (\r\n <React.Fragment>\r\n <ProductLightbox {...productLightboxProps} />\r\n </React.Fragment>\r\n );\r\n}\r\n\r\n// @ts-ignore\r\nexport const ProductComponent: React.FunctionComponent<IProductComponentProps> = msdyn365Commerce.createComponentOverride<IProductComponent>(\r\n 'Product',\r\n { component: ProductCard, ...PriceComponentActions }\r\n);\r\n\r\ninterface IProductComponentWrapperData {\r\n quantity: number;\r\n disable: boolean;\r\n cartMessage: string;\r\n}\r\n\r\n/**\r\n * class definition containing product component for\r\n * add to cart state\r\n */\r\n@LoadBus('product-component-wrapper')\r\nclass ProductComponentWrapper extends React.Component<IProductComponentProps, IProductComponentWrapperData> {\r\n\r\n private bus: BusLoader | undefined;\r\n private addToCartSubId: number;\r\n private finishAddToCartSubId: number;\r\n\r\n constructor(props: IProductComponentProps) {\r\n super(props);\r\n this.state = {\r\n quantity: 1,\r\n disable: false,\r\n cartMessage: ''\r\n };\r\n this._decreaseCartQuantity = this._decreaseCartQuantity.bind(this);\r\n this._increaseCartQuantity = this._increaseCartQuantity.bind(this);\r\n this._onQuantityChange = this._onQuantityChange.bind(this);\r\n this._onClickAddToCart = this._onClickAddToCart.bind(this);\r\n this._onClickAddToSubscription = this._onClickAddToSubscription.bind(this);\r\n\r\n this.addToCartSubId = this.bus?.subscribe('adding-to-cart', () => { this.setState({ disable: true }); }).id!;\r\n this.finishAddToCartSubId = this.bus?.subscribe('finished-adding-to-cart', () => { this.setState({ disable: false }); }).id!;\r\n }\r\n\r\n public componentWillUnmount(): void {\r\n this.bus?.unsubscribe(this.addToCartSubId);\r\n this.bus?.unsubscribe(this.finishAddToCartSubId);\r\n }\r\n\r\n // tslint:disable-next-line:cyclomatic-complexity\r\n public render(): JSX.Element | null {\r\n if (this.props.data.product && this.props.data.product.RecordId && this.props.displayQuantitySlider) {\r\n const attributes: AttributeValue[] | undefined = this.props.data.product.AttributeValues;\r\n const productType: AttributeValue | undefined = attributes?.find(attribute => attribute.Name === 'Product Type');\r\n const bottleSize: AttributeValue | undefined = attributes?.find(attribute => attribute.Name === 'Wine Bottle Size');\r\n const imageProductClass = productType?.TextValue ? `product-type-${productType.TextValue.replace(/\\s+/g, '-').toLowerCase()}` : '';\r\n const { subscriptionBtnText } = this.props;\r\n const outOfStock = this.props.availability?.AvailableQuantity === undefined || this.props.availability?.AvailableQuantity > this.props.context.app.config.outOfStockThreshold ? false : true;\r\n const availability = this.props.availability?.AvailableQuantity && this.props.availability.AvailableQuantity - this.props.context.app.config.outOfStockThreshold;\r\n const productUrl = getProductPageUrlSync(this.props.data.product.Name || '', this.props.data.product.RecordId, this.props.context && this.props.context.actionContext, this.props.parentProps.categoryHierarchy);\r\n const showQuantityAsDropdown:boolean = this.props.showQuantityAsDropdown || false;\r\n const maxQuantity: number | undefined = availability || 10;\r\n const quantityControl = this._generateQuantityControl(this.props.data.product.RecordId, maxQuantity, this.state.quantity, showQuantityAsDropdown);\r\n\r\n if (this.props.giftCardText && bottleSize && bottleSize.TextValue === 'Gift Card') {\r\n return (\r\n <React.Fragment>\r\n <ProductComponent {...this.props} />\r\n <div className={classnames('product-component-wrapper', imageProductClass, 'product-component-wrapper-giftcard')}>\r\n <a\r\n href={productUrl}\r\n aria-label={this.props.giftCardText}\r\n className='product-component-wrapper-giftcard-link'\r\n >\r\n {this.props.giftCardText}\r\n </a>\r\n </div>\r\n </React.Fragment>\r\n );\r\n }\r\n return (\r\n <React.Fragment>\r\n <ProductComponent {...this.props} />\r\n <div className={classnames('product-component-wrapper', imageProductClass)}>\r\n {this.props.data.product.Price && renderPrice(this.props.data.product.Price, 'product-component-wrapper-price', this.props.clubPrice?.CustomerContextualPrice)}\r\n <div className='product-component-wrapper-quantity-group' hidden={outOfStock}>\r\n <button className='product-component-wrapper-decrease-button' onClick={this._decreaseCartQuantity}>-</button>\r\n <label className='sr-only' htmlFor={`quantity-${this.props.data.product.RecordId.toString()}`}>Quantity</label>\r\n {quantityControl}\r\n <button className='product-component-wrapper-increase-button' onClick={this._increaseCartQuantity}>+</button>\r\n </div>\r\n {this.props.addToCart && this.props.addToCartText && (\r\n <div className='product-component-wrapper-add-to-cart'>\r\n <button\r\n className={outOfStock ? 'product-component-wrapper-add-to-cart-out-of-stock' : 'product-component-wrapper-add-to-cart-button'}\r\n disabled={this.state.disable || outOfStock}\r\n onClick={this._onClickAddToCart}\r\n >\r\n {outOfStock ? 'Out of stock' : this.props.addToCartText}\r\n </button>\r\n <div className={`product-component-wrapper-add-to-cart-message ${this.state.cartMessage}`} hidden={!this.state.cartMessage}>\r\n {this.state.cartMessage === 'success' && `${qtyAddedToCart} ${qtyAddedToCart === 1 ? 'item' : 'items'} ${this.props.addToCartMessage}`}\r\n {availability && this.state.cartMessage === 'error' && `Quantity available: ${availability}`}\r\n {/* Start Mixed Cart Bandaid */}\r\n {this.state.cartMessage === 'mixedcart' && 'Gift cards and events may not be combined with wine or merchandise orders. Please remove them from your cart and place a separate order.'}\r\n {/* End Mixed Cart Bandaid */}\r\n </div>\r\n </div>\r\n )\r\n }\r\n {\r\n this.props.checkoutState && subscriptionBtnText && (\r\n <div className='product-component-wrapper-add-to-subscription'>\r\n <button\r\n className={outOfStock ? 'product-component-wrapper-add-to-cart-out-of-stock' : 'product-component-wrapper-add-to-subscription-button'}\r\n disabled={this.state.disable || (this._isAdditionInvalid && !!this.props.disableQuantitySlider) || outOfStock}\r\n onClick={this._onClickAddToSubscription}\r\n >\r\n {outOfStock ? 'Out of stock' : subscriptionBtnText}\r\n </button>\r\n <div className={`product-component-wrapper-add-to-cart-message ${this.state.cartMessage}`} hidden={!this.state.cartMessage}>\r\n {this.state.cartMessage === 'success' && `${qtyAddedToCart} ${qtyAddedToCart === 1 ? 'item' : 'items'} ${this.props.addToCartMessage}`}\r\n {availability && this.state.cartMessage === 'error' && `Quantity available: ${availability}`}\r\n {/* Start Mixed Cart Bandaid */}\r\n {this.state.cartMessage === 'mixedcart' && 'Gift cards and events may not be combined with wine or merchandise orders. Please remove them from your cart and place a separate order.'}\r\n {/* End Mixed Cart Bandaid */}\r\n </div>\r\n </div>\r\n )\r\n }\r\n </div>\r\n </React.Fragment>\r\n );\r\n } else {\r\n return <ProductComponent {...this.props} />;\r\n }\r\n }\r\n\r\n private _generateMenu = (quantity: number | undefined) => {\r\n const nodes = [];\r\n\r\n if (quantity !== undefined) {\r\n for (let i = 1; i <= quantity; i++) {\r\n // tslint:disable-next-line:react-a11y-role-has-required-aria-props\r\n nodes.push(<option className='product-component__quantity__select-menu__item' value={i}>{i}</option>);\r\n }\r\n }\r\n\r\n return nodes;\r\n };\r\n\r\n private _generateQuantityControl = (productId: number | undefined, maxQuantity: number | undefined, currentQuantity: number, showAsDropdown:boolean = false): JSX.Element => {\r\n if (showAsDropdown && productId !== undefined) {\r\n return (<select aria-label=\"Quantity To Purchase\" id={`quantity-${productId.toString()}`}\r\n className='product-component__quantity__select-menu' value={currentQuantity} onChange={this._onQuantityChange}>\r\n {\r\n this._generateMenu(maxQuantity)\r\n }\r\n </select>);\r\n } else {\r\n return (\r\n /* tslint:disable-next-line: react-a11y-role-has-required-aria-props react-this-binding-issue */\r\n <input className='product-component-wrapper-quantity' type='number' value={currentQuantity} max={maxQuantity} onChange={this._onQuantityChange} />\r\n );\r\n }\r\n };\r\n\r\n private async _onClickAddToCart(): Promise<void> {\r\n const { data: { product }, context } = this.props;\r\n const cartQty = (this.props.cart?.result?.cart.TotalItems || 0) + this.state.quantity;\r\n qtyAddedToCart = this.state.quantity;\r\n\r\n this.bus?.publish('adding-to-cart');\r\n await onAddToCartAction(context, product!.RecordId, this.state.quantity);\r\n this.bus?.publish('finished-adding-to-cart');\r\n\r\n // Mixed Cart Bandaid - Remove when no longer needed\r\n // Checking if cart contains a gift card. Because gift cards are not added in the PLP, no need to check for the\r\n // other way around. If that changes, mixed cart check needs to be rewritten.\r\n\r\n /* Start Mixed Cart Bandaid */\r\n const mixedCart = !!this.props.cart?.result?.cart?.CartLines?.find(\r\n item => item.IsGiftCardLine ||\r\n item.DeliveryMode === \"40.5\" // 40.5 responds to events i believe, so use it here\r\n );\r\n /* End Mixed Cart Bandaid */\r\n if (cartQty === this.props.cart?.result?.cart.TotalItems) {\r\n this.setState({ cartMessage: 'success' });\r\n setTimeout(() => { this.setState({ cartMessage: '', quantity: 1 }); }, 2000);\r\n /* Start Mixed Cart Bandaid */\r\n } else if (mixedCart) {\r\n this.setState({ cartMessage: 'mixedcart' });\r\n /* End Mixed Cart Bandaid */\r\n } else {\r\n this.setState({ cartMessage: 'error' });\r\n }\r\n }\r\n\r\n private async _onClickAddToSubscription(): Promise<void> {\r\n const { data: { product }, context } = this.props;\r\n const cartQty = (this.props.cart?.result?.cart.TotalItems || 0) + this.state.quantity;\r\n qtyAddedToCart = this.state.quantity;\r\n\r\n this.bus?.publish('adding-to-cart');\r\n await onSubscribeAction(context, product!.RecordId, this.state.quantity, this.props.cart);\r\n this.bus?.publish('finished-adding-to-cart');\r\n\r\n // Mixed Cart Bandaid - Remove when no longer needed\r\n // Checking if cart contains a gift card. Because gift cards are not added in the PLP, no need to check for the\r\n // other way around. If that changes, mixed cart check needs to be rewritten.\r\n\r\n /* Start Mixed Cart Bandaid */\r\n const mixedCart = !!this.props.cart?.result?.cart?.CartLines?.find(\r\n item => item.IsGiftCardLine ||\r\n item.DeliveryMode === \"40.5\" // 40.5 responds to events i believe, so use it here\r\n );\r\n /* End Mixed Cart Bandaid */\r\n\r\n if (cartQty === this.props.cart?.result?.cart.TotalItems) {\r\n this.setState({ cartMessage: 'success' });\r\n setTimeout(() => { this.setState({ cartMessage: '', quantity: 1 }); }, 2000);\r\n /* Start Mixed Cart Bandaid */\r\n } else if (mixedCart) {\r\n this.setState({ cartMessage: 'mixedCart' });\r\n /* End Mixed Cart Bandaid */\r\n } else {\r\n this.setState({ cartMessage: 'error' });\r\n }\r\n }\r\n\r\n private _increaseCartQuantity(): void {\r\n this.setState({ quantity: this.state.quantity + 1 });\r\n }\r\n\r\n private _decreaseCartQuantity(): void {\r\n this.setState({ quantity: this.state.quantity > 1 ? this.state.quantity - 1 : this.state.quantity });\r\n }\r\n\r\n private _onQuantityChange({ target }: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLSelectElement>): void {\r\n if (parseInt(target.value, 10) < 1) {\r\n this.setState({ quantity: 1 });\r\n } else {\r\n this.setState({ quantity: parseInt(target.value, 10) });\r\n }\r\n }\r\n\r\n private get _isAdditionInvalid(): boolean {\r\n const cartQuantity = CartUtilities.countCartLineAmount(filterCartLines(this.props.cart?.result?.cart).subscriptionLines);\r\n return (this.state.quantity + cartQuantity) > (this.props.maxAdditionLimit || 12);\r\n }\r\n}\r\n\r\nasync function onAddToCartAction(context: ICoreContext, recordId: number, amount: number | undefined): Promise<void> {\r\n\r\n return CartUtilities.elicitAddItemIdToCart({ recordId, amount, context });\r\n}\r\n\r\nasync function onSubscribeAction(context: ICoreContext, recordId: number, amount?: number, cart?: AsyncResult<ICartState>): Promise<void> {\r\n // fetch attribute list and simple product\r\n\r\n return CartUtilities.elicitAddSubscriptionItemIdToCart({ context, recordId, amount }, cart!);\r\n}\r\n\r\nexport default ProductComponentWrapper;","export * from './link';\r\nexport * from './product-search-result-items';\r\nexport * from './title';\r\nexport * from './separator';\r\nexport * from './range-refine-item';\r\nexport * from './refine-item';\r\nexport * from './refine-item-toggle-notification';\r\nexport * from './refine-item.props.common';\r\nexport * from './utilities';\r\nexport * from './choice-summary';\r\nexport * from './choice-summary.props';\r\nexport * from './modal';\r\nexport * from './refine-submenu';\r\nexport * from './error-message';\r\n","import * as React from 'react';\r\ninterface IErrorMessage {\r\n text?: string;\r\n}\r\n\r\nexport const ErrorMessage: React.FC<IErrorMessage> = ({ text }) => {\r\n return (\r\n <span className='ms-search-result-container__no-results-message'>\r\n <h5> {text} </h5>\r\n </span>\r\n );\r\n};","import { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport classnames from 'classnames';\r\nimport { get } from 'lodash';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport { IChoiceSummaryProps } from './choice-summary.props';\r\nimport { isMatchingRefinementCriterion, ProductRefinerValueDataTypeValue } from './utilities';\r\n\r\ninterface IRefinerMap {\r\n key: string;\r\n value: ProductRefinerValue;\r\n}\r\n\r\n /**\r\n * ChoiceSummary component\r\n */\r\n@observer\r\nexport default class ChoiceSummary extends React.Component<IChoiceSummaryProps> {\r\n private closeButtonGlyph: string = 'msi-close-btn';\r\n\r\n @computed get selectedRefinersMap(): IRefinerMap[] {\r\n const { selectedChoices } = this.props;\r\n return selectedChoices.map((selectedRefiner: ProductRefinerValue) => {\r\n return {\r\n key: this._getKeyForRefinerValue(selectedRefiner),\r\n value: selectedRefiner\r\n } as IRefinerMap;\r\n });\r\n }\r\n\r\n constructor(props: Readonly<IChoiceSummaryProps>) {\r\n super(props);\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { clearAllText, label, classNames, choiceAriaLabel } = this.props;\r\n const items = this.selectedRefinersMap;\r\n return (\r\n <div className='msc-choice-summary'>\r\n {items.length > 0 && label && <span className='msc-choice-summary__label'>{label}</span>}\r\n <ul className={classnames(classNames, 'msc-choice-summary__list', 'list-unstyled')}>\r\n {items.map((item: IRefinerMap, index: number) => {\r\n const listItemProps = {\r\n 'aria-posinset': index,\r\n 'aria-setsize': items.length\r\n };\r\n\r\n return (\r\n <li className='msc-choice-summary__list-item' key={item.key} {...listItemProps}>\r\n <a\r\n className='msc-choice-summary__item'\r\n href={this.props.urlBuilder(item.value, false)}\r\n aria-label={`${item.key} ${choiceAriaLabel}`}\r\n onClick={this._onClick}\r\n >\r\n {item.key}\r\n <span className={`${this.closeButtonGlyph} msc-choice-summary__glyph`} />\r\n </a>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n {items.length > 0 && clearAllText && <a href={this.props.urlBuilder({}, true)} className={'msc-choice-summary__clear-all'} onClick={this._onClick}>{clearAllText}</a>}\r\n </div>\r\n );\r\n }\r\n\r\n private _getKeyForRefinerValue(productRefinerValue: ProductRefinerValue): string {\r\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry } = this.props;\r\n const overallFormat = choiceFormat || '{1}';\r\n const rangeFormat = choiceRangeValueFormat;\r\n let refinerName = '';\r\n if (refinerHierarchy && refinerHierarchy.find) {\r\n const parent = refinerHierarchy.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, productRefinerValue))\r\n );\r\n\r\n if (!parent) {\r\n telemetry.warning('[choice-summary] could not find parent of selected refiner value');\r\n } else {\r\n refinerName = parent.KeyName || '';\r\n }\r\n }\r\n\r\n let refinerValueName: string;\r\n switch (productRefinerValue.DataTypeValue) {\r\n case ProductRefinerValueDataTypeValue.Range:\r\n case ProductRefinerValueDataTypeValue.RangeInput:\r\n refinerValueName = rangeFormat\r\n .replace('{0}', this._formatPrice(productRefinerValue.LeftValueBoundString, productRefinerValue.UnitText))\r\n .replace('{1}', this._formatPrice(productRefinerValue.RightValueBoundString, productRefinerValue.UnitText));\r\n break;\r\n default:\r\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n }\r\n\r\n return overallFormat.replace('{0}', refinerName).replace('{1}', refinerValueName);\r\n }\r\n\r\n private _formatPrice(amount: string | undefined, currency: string | undefined): string {\r\n if (!amount || !currency) {\r\n this.props.telemetry.trace('[choice-summary] could not format price');\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n const locale = get(this.props, 'context.request.locale', 'en-US');\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency: currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (e) {\r\n result = `${priceAmount} ${currency}`;\r\n this.props.telemetry.warning(`Failed to format price for ${result}: ${e}`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _onClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const target = e.currentTarget as HTMLElement;\r\n const clearAll = target.getAttribute('class')!.indexOf('choice-summary__clear-all') > -1;\r\n const selectedRefiner = clearAll ? undefined : this._getSelectedRefinerChoice(target);\r\n\r\n if (this.props.onChoiceClicked) {\r\n this.props.onChoiceClicked({\r\n clearAll: clearAll,\r\n itemClicked: target,\r\n choiceClicked: selectedRefiner,\r\n nextItemToFocus: target.nextSibling as HTMLElement\r\n });\r\n }\r\n };\r\n\r\n private _getSelectedRefinerChoice(itemClicked: HTMLElement): ProductRefinerValue | undefined {\r\n const result = this.selectedRefinersMap.find(selected => (itemClicked.innerText && itemClicked.innerText.trim()) === selected.key);\r\n return (result && result.value) || undefined;\r\n }\r\n}\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport * as React from 'react';\r\n\r\nimport { Button, Collapse } from '@msdyn365-commerce-modules/utilities';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\r\nimport RefineItem from './refine-item';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { findMatchingRefinementCriterion, ProductRefinerTypeValue, ProductRefinerValueDataTypeValue } from './utilities';\r\n\r\n/**\r\n * Properties associated with the RefineSubmenu component\r\n */\r\nexport interface IRefineSubmenuProps {\r\n tempRangeTypeTODO: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n refinerExpandText?: string;\r\n refinerMinimizeText?: string;\r\n minimizedRefiners?: string;\r\n productRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinerValues: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n isExpandedOnInitialLoad: boolean;\r\n context: ICoreContext;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n highestLevelRefinerText?: string;\r\n onUpdateRefiners(notfication: Readonly<IRefineItemToggleNotification>): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine submenu state\r\n */\r\nexport interface IRefineSubmenuState extends React.ComponentState {\r\n expanded: boolean;\r\n}\r\n\r\n/**\r\n *\r\n * The RefineSubmenu component renders the submenu category and child items.\r\n * This computed observes the stateful category hierarchy object.\r\n * @extends {React.PureComponent<IRefineSubmenuProps>}\r\n */\r\nclass RefineSubmenu extends React.PureComponent<IRefineSubmenuProps, IRefineSubmenuState> {\r\n\r\n private isMinimizedRefiner: boolean = false;\r\n\r\n constructor(props: IRefineSubmenuProps) {\r\n super(props);\r\n\r\n this._onToggleItem = this._onToggleItem.bind(this);\r\n this._onToggleSubmenu = this._onToggleSubmenu.bind(this);\r\n this._expandCategoryRefiner = this._expandCategoryRefiner.bind(this);\r\n\r\n let isExpanded = this.props.isExpandedOnInitialLoad;\r\n if (this.props.productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range) {\r\n isExpanded = true;\r\n }\r\n\r\n this.state = {\r\n expanded: isExpanded\r\n };\r\n\r\n if (this.props.minimizedRefiners) {\r\n const minimizedRefinersList = this.props.minimizedRefiners.split(',');\r\n this.isMinimizedRefiner = minimizedRefinersList.some(\r\n keyName => this.props.productRefinerHierarchy.KeyName && (keyName.toLowerCase() === this.props.productRefinerHierarchy.KeyName.toLocaleLowerCase())\r\n );\r\n }\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\r\n }\r\n\r\n const isRangeRefiner = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range);\r\n let key = '';\r\n if (isRangeRefiner) {\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(productRefinerHierarchy.Values[0], this.props.selectedRefinerValues);\r\n key = selectedRefinementCriterion ? `($${selectedRefinementCriterion.LeftValueBoundString && parseFloat(selectedRefinementCriterion.LeftValueBoundString).toFixed(2)} - $${selectedRefinementCriterion.RightValueBoundString && parseFloat(selectedRefinementCriterion.RightValueBoundString).toFixed(2)})` : '';\r\n }\r\n\r\n if (this.isMinimizedRefiner) {\r\n return (\r\n <div className='ms-refine-submenu list-group'>\r\n <div className='ms-refine-submenu__minimized-header'>{productRefinerHierarchy.KeyName} {key}</div>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className='ms-refine-submenu list-group'>\r\n <Button\r\n className={this.state.expanded ? 'ms-refine-submenu__toggle_expanded' : 'ms-refine-submenu__toggle_collapsed'}\r\n aria-label={productRefinerHierarchy.KeyName || 'refiner.Name'}\r\n onClick={this._onToggleSubmenu}\r\n aria-expanded={this.state.expanded}\r\n >\r\n {productRefinerHierarchy.KeyName} {key}\r\n </Button>\r\n <Collapse isOpen={this.state.expanded} timeout={350}>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n </Collapse>\r\n </div>\r\n );\r\n }\r\n\r\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n switch (productRefinerHierarchy.DataTypeValue) {\r\n case ProductRefinerValueDataTypeValue.Range:\r\n case ProductRefinerValueDataTypeValue.RangeInput:\r\n return this._renderRange(productRefinerHierarchy);\r\n default:\r\n return this._renderSingleMultiSelect(productRefinerHierarchy);\r\n }\r\n }\r\n\r\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context } = this.props;\r\n const isSingleSelect = productRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single;\r\n const role = isSingleSelect ? { role: 'radiogroup' } : undefined;\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n return (\r\n <RefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n key={index}\r\n context={context}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n );\r\n });\r\n if (this.isMinimizedRefiner) {\r\n return (\r\n <div className='ms-refine-submenu__list-min' id={`refine-submenu-minimize__${this.props.productRefinerHierarchy.RecordId}`}>\r\n <ul className='ms-refine-submenu__list' {...role} aria-label={productRefinerHierarchy.KeyName}>\r\n {listItems}\r\n </ul>\r\n <a\r\n onClick={this._expandCategoryRefiner}\r\n className='ms-refine-submenu__expand-button'\r\n role='button'\r\n id={`refine-submenu-minimize-button__${productRefinerHierarchy.RecordId}`}\r\n >\r\n {this.props.refinerExpandText}\r\n </a>\r\n </div>\r\n );\r\n }\r\n return (\r\n <ul className='ms-refine-submenu__list' {...role} aria-label={productRefinerHierarchy.KeyName}>\r\n {listItems}\r\n </ul>\r\n );\r\n }\r\n\r\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context, minValueSliderThumbAriaLabel, maxValueSliderThumbAriaLabel } = this.props;\r\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n // TODO BUGBUG 22424559 determine only from the DataTypeValue once live example is working (can test with the tempRangeTypeTODO derived from QSP until then)\r\n const rangeType = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.RangeInput || this.props.tempRangeTypeTODO === 'input') ?\r\n 'input' :\r\n 'slider';\r\n const key = selectedRefinementCriterion ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}` : `not-selected-${index}`;\r\n return (\r\n <li className={`${submenuClassNamePrefix}--range`} key={index}>\r\n <RangeRefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n rangeType={rangeType}\r\n key={key}\r\n context={context}\r\n minValueSliderThumbAriaLabel={minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={maxValueSliderThumbAriaLabel}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n </li>\r\n );\r\n });\r\n return <ul className='ms-refine-submenu__list list-unstyled'>{listItems}</ul>;\r\n }\r\n\r\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\r\n this.props.onUpdateRefiners(itemToggleNotification);\r\n }\r\n\r\n private _onToggleSubmenu(): void {\r\n this.setState(prevState => ({\r\n expanded: !prevState.expanded\r\n }));\r\n }\r\n\r\n private _getSortedValueList(): ProductRefinerValue[] {\r\n const sortedList = this.props.productRefinerHierarchy.Values.sort((nextOption, curOption) => {\r\n const curOptionName =\r\n nextOption.LeftValueBoundString || nextOption.RightValueBoundString || '';\r\n const nextOptionName =\r\n curOption.LeftValueBoundString || curOption.RightValueBoundString || '';\r\n\r\n return curOptionName.localeCompare(nextOptionName);\r\n });\r\n\r\n const dividedList = {\r\n options: [] as ProductRefinerValue[],\r\n topLevel: [] as ProductRefinerValue[]\r\n };\r\n sortedList.forEach(option => {\r\n const optionName = option.LeftValueBoundString || option.RightValueBoundString || '';\r\n\r\n if (optionName === this.props.highestLevelRefinerText) {\r\n dividedList.topLevel.push(option);\r\n } else {\r\n dividedList.options.push(option);\r\n }\r\n });\r\n\r\n return [...dividedList.topLevel, ...dividedList.options];\r\n }\r\n\r\n private _expandCategoryRefiner(): void {\r\n const minimizedElement = document.getElementById(`refine-submenu-minimize__${this.props.productRefinerHierarchy.RecordId}`);\r\n const buttonElement = document.getElementById(`refine-submenu-minimize-button__${this.props.productRefinerHierarchy.RecordId}`);\r\n if (minimizedElement && buttonElement) {\r\n if (minimizedElement.className === 'ms-refine-submenu__list-min') {\r\n minimizedElement.className = 'ms-refine-submenu__list-full';\r\n buttonElement.textContent = this.props.refinerMinimizeText!;\r\n } else {\r\n minimizedElement.className = 'ms-refine-submenu__list-min';\r\n buttonElement.textContent = this.props.refinerExpandText!;\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default RefineSubmenu;","import * as React from 'react';\r\n\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\r\nimport RefineItem from './refine-item';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { findMatchingRefinementCriterion, ProductRefinerTypeValue, ProductRefinerValueDataTypeValue } from './utilities';\r\n\r\n/**\r\n * Properties associated with the RefineSubmenu component\r\n */\r\nexport interface IRefinePulldownProps {\r\n tempRangeTypeTODO: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n productRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinerValues: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n context: ICoreContext;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n highestLevelRefinerText?: string;\r\n buttonText: string | undefined;\r\n onUpdateRefiners(notfication: Readonly<IRefineItemToggleNotification>): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n *\r\n * The RefineSubmenu component renders the submenu category and child items.\r\n * This computed observes the stateful category hierarchy object.\r\n * @extends {React.PureComponent<IRefineSubmenuProps>}\r\n */\r\nclass RefinePulldown extends React.Component<IRefinePulldownProps> {\r\n\r\n constructor(props: IRefinePulldownProps) {\r\n super(props);\r\n\r\n this._onToggleItem = this._onToggleItem.bind(this);\r\n }\r\n\r\n public componentDidMount(): void {\r\n document.body && document.body.addEventListener('mousedown', this._handleClickOutsidePulldown);\r\n }\r\n\r\n public componentWillUnmount(): void {\r\n document.body && document.body.removeEventListener('mousedown', this._handleClickOutsidePulldown, false);\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\r\n }\r\n\r\n const isRangeRefiner = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range);\r\n let key = '';\r\n if (isRangeRefiner) {\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(productRefinerHierarchy.Values[0], this.props.selectedRefinerValues);\r\n key = selectedRefinementCriterion ? `($${selectedRefinementCriterion.LeftValueBoundString && parseFloat(selectedRefinementCriterion.LeftValueBoundString).toFixed(2)} - $${selectedRefinementCriterion.RightValueBoundString && parseFloat(selectedRefinementCriterion.RightValueBoundString).toFixed(2)})` : '';\r\n }\r\n\r\n return (\r\n <div className='ms-refine-submenu list-group'>\r\n <div\r\n className={'ms-refine-submenu__toggle_expanded'}\r\n aria-label={productRefinerHierarchy.KeyName || 'refiner.Name'}\r\n >\r\n {productRefinerHierarchy.KeyName} {key}\r\n </div>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n </div>\r\n );\r\n }\r\n\r\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n switch (productRefinerHierarchy.DataTypeValue) {\r\n case ProductRefinerValueDataTypeValue.Range:\r\n case ProductRefinerValueDataTypeValue.RangeInput:\r\n return this._renderRange(productRefinerHierarchy);\r\n default:\r\n return this._renderSingleMultiSelect(productRefinerHierarchy);\r\n }\r\n }\r\n\r\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context } = this.props;\r\n const isSingleSelect = productRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single;\r\n const role = isSingleSelect ? { role: 'radiogroup' } : undefined;\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n return (\r\n <RefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n key={index}\r\n context={context}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n );\r\n });\r\n return (\r\n <ul className='ms-refine-submenu__list' {...role} aria-label={productRefinerHierarchy.KeyName}>\r\n {listItems}\r\n </ul>\r\n );\r\n }\r\n\r\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context, minValueSliderThumbAriaLabel, maxValueSliderThumbAriaLabel } = this.props;\r\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n // TODO BUGBUG 22424559 determine only from the DataTypeValue once live example is working (can test with the tempRangeTypeTODO derived from QSP until then)\r\n const rangeType = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.RangeInput || this.props.tempRangeTypeTODO === 'input') ?\r\n 'input' :\r\n 'slider';\r\n const key = selectedRefinementCriterion ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}` : `not-selected-${index}`;\r\n return (\r\n <li className={`${submenuClassNamePrefix}--range`} key={index}>\r\n <RangeRefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n rangeType={rangeType}\r\n key={key}\r\n context={context}\r\n minValueSliderThumbAriaLabel={minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={maxValueSliderThumbAriaLabel}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n </li>\r\n );\r\n });\r\n return <ul className='ms-refine-submenu__list list-unstyled'>{listItems}</ul>;\r\n }\r\n\r\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\r\n this.props.onUpdateRefiners(itemToggleNotification);\r\n }\r\n\r\n // tslint:disable-next-line:no-any\r\n private _handleClickOutsidePulldown = (event: any) => {\r\n const pulldown:boolean = event.target.id === 'refiner-pulldown-button';\r\n const pulldownElement = document.getElementById('refiner-pulldown-container');\r\n if (!pulldownElement?.contains(event.target) && !pulldown && pulldownElement?.className !== 'ms-search-result-container__refiner-pulldown-container pulldown-hide') {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n if (buttonElement) {\r\n buttonElement.classList.toggle('refiner-pulldown-button-expanded');\r\n this._getPulldownText(this._getActiveRefinersText(this.props.selectedRefinerValues), this.props.buttonText);\r\n }\r\n if (pulldownElement) {\r\n pulldownElement.classList.toggle('pulldown-hide');\r\n }\r\n }\r\n };\r\n\r\n private _getPulldownText = (activeRefiners: string, buttonText: string | undefined): string => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n const spanElement = document.getElementById('refiner-pulldown-button-content');\r\n if (buttonElement && spanElement) {\r\n if (buttonElement.className === 'ms-search-result-container__refiner-pulldown-button refiner-pulldown-button-expanded' || !activeRefiners) {\r\n return spanElement.innerText = buttonText || '';\r\n } else {\r\n return spanElement.innerText = activeRefiners;\r\n }\r\n }\r\n return '';\r\n };\r\n\r\n private _getActiveRefinersText = (activeRefiners: ProductRefinerValue[]): string => {\r\n let formatedActiveRefiners = '';\r\n activeRefiners.forEach(refiner => {\r\n if (refiner.UnitText === 'USD') {\r\n formatedActiveRefiners += `$${refiner.LeftValueBoundString}-$${refiner.RightValueBoundString} / `;\r\n } else if (refiner.LeftValueBoundString) {\r\n formatedActiveRefiners += `${refiner.LeftValueBoundString} / `;\r\n }\r\n });\r\n // removes trailing slash and whitespace\r\n formatedActiveRefiners = formatedActiveRefiners.substring(0, formatedActiveRefiners.length - 2);\r\n return formatedActiveRefiners;\r\n };\r\n\r\n private _getSortedValueList(): ProductRefinerValue[] {\r\n const sortedList = this.props.productRefinerHierarchy.Values.sort((nextOption, curOption) => {\r\n const curOptionName =\r\n nextOption.LeftValueBoundString || nextOption.RightValueBoundString || '';\r\n const nextOptionName =\r\n curOption.LeftValueBoundString || curOption.RightValueBoundString || '';\r\n\r\n return curOptionName.localeCompare(nextOptionName);\r\n });\r\n\r\n const dividedList = {\r\n options: [] as ProductRefinerValue[],\r\n topLevel: [] as ProductRefinerValue[]\r\n };\r\n sortedList.forEach(option => {\r\n const optionName = option.LeftValueBoundString || option.RightValueBoundString || '';\r\n\r\n if (optionName === this.props.highestLevelRefinerText) {\r\n dividedList.topLevel.push(option);\r\n } else {\r\n dividedList.options.push(option);\r\n }\r\n });\r\n\r\n return [...dividedList.topLevel, ...dividedList.options];\r\n }\r\n}\r\n\r\nexport default RefinePulldown;","import classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport {UncontrolledTooltip, mapToCssModules, PaginationItem, PaginationLink, ITelemetryContent} from '@msdyn365-commerce-modules/utilities';\r\n\r\n/**\r\n * UncontrolledPagination properties.\r\n */\r\nexport interface IUncontrolledPaginationProps extends React.HTMLAttributes<HTMLElement> {\r\n /** The current url */\r\n url: string;\r\n\r\n /** The qsp to use with the pagination */\r\n qsp: string;\r\n\r\n /** Number of items */\r\n items?: number;\r\n\r\n /** Items per page */\r\n itemsPerPage?: number;\r\n\r\n /** Index of first item returned */\r\n startingItem?: number;\r\n\r\n /** The text to display for the previous arrow */\r\n previousText?: React.ReactChild;\r\n\r\n /** The text to display for the next arrow */\r\n nextText?: React.ReactChild;\r\n\r\n /** The aria-label for the previous arrow */\r\n previousAriaLabel?: string;\r\n\r\n /** The aria-label for the next arrow */\r\n nextAriaLabel?: string;\r\n\r\n /** Tag property to set if you want the HTML tag to be something else */\r\n tag?: React.ReactType;\r\n\r\n /** List tag property to set if you want the HTML tag to be something else */\r\n listTag?: React.ReactType;\r\n\r\n /** ClassName Property to set any CSS classnames on the pagination */\r\n className?: string;\r\n\r\n /** List ClassName Property to set any CSS classnames on the pagination */\r\n listClassName?: string;\r\n\r\n /** CssModule Property to set any CSS classModule on the pagination */\r\n cssModule?: object;\r\n\r\n /** Set the pagination bar showed size */\r\n size?: string;\r\n\r\n /** Define a string that labels the current element */\r\n 'aria-label'?: string;\r\n\r\n /** Define a string that provide the role on the pagination */\r\n role?: string;\r\n\r\n /** The Id for the next arrow */\r\n nextId?: string;\r\n\r\n /** The Id for the prev arrow */\r\n prevId?: string;\r\n\r\n /** The text for the next arrow aria described */\r\n nextAreaDescribed?: string;\r\n\r\n /** The text for the prev arrow aria described */\r\n prevAreaDescribed?: string;\r\n\r\n /** The telemetry content */\r\n telemetryContent?: ITelemetryContent;\r\n}\r\n\r\n/**\r\n * Uncontrolled Pagination component\r\n */\r\n export default class SMWEPagination extends React.PureComponent<IUncontrolledPaginationProps> {\r\n public static defaultProps: Partial<IUncontrolledPaginationProps> = {\r\n tag: 'nav',\r\n listTag: 'ul',\r\n 'aria-label': 'pagination',\r\n items: 0,\r\n itemsPerPage: 25,\r\n startingItem: 0\r\n };\r\n\r\n private static readonly pagesDisplayed: number = 7;\r\n\r\n private maxPages: number;\r\n\r\n private activePage: number = 0;\r\n\r\n private qsps: { [param: string]: string };\r\n\r\n private url: string;\r\n\r\n private hash: string;\r\n\r\n constructor(props: IUncontrolledPaginationProps) {\r\n super(props);\r\n this.maxPages = this.props.items ? Math.ceil(this.props.items / this.props.itemsPerPage!) : 0;\r\n this.activePage = Math.floor((this.props.startingItem || 0) / this.props.itemsPerPage!);\r\n this.qsps = {};\r\n const splitUrl = this.props.url.split('?');\r\n\r\n if (splitUrl[1]) {\r\n this.url = splitUrl[0];\r\n const secondSplit = splitUrl[1].split('#');\r\n this.hash = secondSplit[1] ? `#${secondSplit[1]}` : '';\r\n const parsedQsps = secondSplit[0].split('&');\r\n\r\n for (const qsp of parsedQsps) {\r\n const qspPair = qsp.split('=');\r\n\r\n if (this.props.qsp !== qspPair[0]) {\r\n this.qsps[qspPair[0]] = qspPair[1];\r\n }\r\n }\r\n } else {\r\n const secondSplit = splitUrl[0].split('#');\r\n this.url = secondSplit[0];\r\n this.hash = secondSplit[1] ? `#${secondSplit[1]}` : '';\r\n }\r\n }\r\n\r\n public render(): JSX.Element {\r\n const {\r\n className,\r\n baseUrl,\r\n qsp,\r\n items,\r\n itemsPerPage,\r\n startingItem,\r\n previousText,\r\n nextText,\r\n previousAriaLabel,\r\n nextAriaLabel,\r\n listClassName,\r\n cssModule,\r\n children,\r\n size,\r\n tag: Tag,\r\n listTag: ListTag,\r\n 'aria-label': label,\r\n role,\r\n ...props\r\n\r\n }: any = this.props;\r\n\r\n this.maxPages = this.props.items ? Math.ceil(this.props.items / this.props.itemsPerPage!) : 0;\r\n this.activePage = Math.floor((this.props.startingItem || 0) / this.props.itemsPerPage!);\r\n this.qsps = {};\r\n const splitUrl = this.props.url.split('?');\r\n\r\n if (splitUrl[1]) {\r\n this.url = splitUrl[0];\r\n const secondSplit = splitUrl[1].split('#');\r\n this.hash = secondSplit[1] ? `#${secondSplit[1]}` : '';\r\n const parsedQsps = secondSplit[0].split('&');\r\n\r\n for (const activeQsp of parsedQsps) {\r\n const qspPair = activeQsp.split('=');\r\n\r\n if (this.props.qsp !== qspPair[0]) {\r\n this.qsps[qspPair[0]] = qspPair[1];\r\n }\r\n }\r\n } else {\r\n const secondSplit = splitUrl[0].split('#');\r\n this.url = secondSplit[0];\r\n this.hash = secondSplit[1] ? `#${secondSplit[1]}` : '';\r\n }\r\n\r\n const paginationClasses = mapToCssModules(\r\n classNames(\r\n className\r\n ),\r\n cssModule\r\n );\r\n\r\n const listpaginationClasses = mapToCssModules(\r\n classNames(\r\n listClassName,\r\n 'msc-pagination',\r\n {\r\n [`msc-pagination-${size}`]: !!size\r\n }\r\n ),\r\n cssModule\r\n );\r\n\r\n return (\r\n <Tag className={paginationClasses} role='navigation' aria-label={label}>\r\n <ListTag {...props} className={listpaginationClasses}>\r\n {this._generatePageLinks()}\r\n </ListTag>\r\n </Tag>\r\n );\r\n }\r\n\r\n private _generateUrl(page: number): string {\r\n const items = this.props.itemsPerPage! * page;\r\n const keys = Object.keys(this.qsps);\r\n let qspUrl = page > 0 ? `?${this.props.qsp}=${items}` : '';\r\n\r\n keys.forEach((key: string) => {\r\n qspUrl = qspUrl ? `${qspUrl}&${key}=${this.qsps[key]}` : `?${key}=${this.qsps[key]}`;\r\n });\r\n\r\n return this.url + qspUrl + this.hash;\r\n }\r\n\r\n private _generatePaginationArrow(next: boolean, disable: boolean, className: string): React.ReactElement<PaginationItem> {\r\n const url = disable ? undefined : this._generateUrl(this.activePage + (next ? 1 : -1));\r\n const tooltipId = next ? this.props.nextId : this.props.prevId;\r\n const ariaDescribedBy = next ? this.props.nextAreaDescribed : this.props.prevAreaDescribed;\r\n const placement = next ? 'right' : 'left';\r\n const tag = disable ? 'span' : 'a';\r\n\r\n return (\r\n <PaginationItem disabled={disable} className={className}>\r\n <PaginationLink\r\n id={tooltipId}\r\n href={url}\r\n next={next}\r\n previous={!next}\r\n aria-describedby={ariaDescribedBy}\r\n tag={tag}\r\n aria-label={next ? this.props.nextAriaLabel : this.props.previousAriaLabel}\r\n aria-disabled={disable}\r\n telemetryContent={this.props.telemetryContent}\r\n >\r\n {next ? this.props.nextText : this.props.previousText}\r\n </PaginationLink>\r\n {tooltipId && (\r\n <UncontrolledTooltip placement={placement} id={ariaDescribedBy} target={tooltipId}>\r\n {next ? 'next' : 'previous'}\r\n </UncontrolledTooltip>\r\n )}\r\n </PaginationItem>\r\n );\r\n }\r\n\r\n private _generatePaginationItem(page: number): React.ReactElement<PaginationItem> {\r\n const active = this.activePage === page;\r\n const url = this._generateUrl(page);\r\n page += 1;\r\n const label = `Page ${page}`;\r\n return (\r\n <PaginationItem active={active} >\r\n <PaginationLink href={active ? undefined : url} {...(active ? {'aria-current': 'page'} : {})} aria-label={label} telemetryContent={this.props.telemetryContent}>\r\n {page}\r\n </PaginationLink>\r\n </PaginationItem>\r\n );\r\n }\r\n\r\n private _generateEllipse(): React.ReactElement<PaginationItem> {\r\n return (\r\n <PaginationItem>\r\n <PaginationLink tag='span'>\r\n ...\r\n </PaginationLink>\r\n </PaginationItem>\r\n );\r\n }\r\n\r\n private _generatePageLinks(): React.ReactFragment {\r\n const displayCountSide = 3;\r\n let leftDistance = this.activePage;\r\n let rightDistance = this.maxPages - this.activePage - 1;\r\n const leftEllipse = this.maxPages > SMWEPagination.pagesDisplayed && leftDistance > 3;\r\n const rightEllipse = this.maxPages > SMWEPagination.pagesDisplayed && rightDistance > 3;\r\n\r\n leftDistance = Math.min(leftDistance, displayCountSide);\r\n rightDistance = Math.min(rightDistance, displayCountSide);\r\n const pages = [];\r\n const ellipseOffset = leftEllipse ? -1 : 0;\r\n const displayedPagesOnLeft = leftDistance + (displayCountSide - rightDistance) + ellipseOffset;\r\n const startingIndex = Math.max(this.activePage - displayedPagesOnLeft, 0);\r\n const endIndex = Math.min((startingIndex + 5 + (rightEllipse ? 0 : 1) + (leftEllipse ? 0 : 1)),\r\n (rightEllipse ? this.maxPages - 1 : this.maxPages));\r\n\r\n if (leftEllipse) {\r\n pages.push(this._generatePaginationItem(0));\r\n pages.push(this._generateEllipse());\r\n }\r\n\r\n for (let i = startingIndex; i < endIndex; i++) {\r\n pages.push(this._generatePaginationItem(i));\r\n }\r\n\r\n if (rightEllipse) {\r\n pages.push(this._generateEllipse());\r\n pages.push(this._generatePaginationItem(this.maxPages - 1));\r\n }\r\n\r\n return (\r\n <>\r\n { this._generatePaginationArrow(false, (this.activePage === 0), 'previous') }\r\n {pages}\r\n { this._generatePaginationArrow(true, (this.activePage === this.maxPages - 1), 'next') }\r\n </>\r\n );\r\n }\r\n}\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport classnames from 'classnames';\r\nimport { computed, observable, reaction, transaction } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { ILabeledDropdownOnChangeNotification, ILabeledDropdownOption, IModuleProps, INodeProps, LabeledDropdown } from '@msdyn365-commerce-modules/utilities';\r\nimport { CategoryHierarchy as CategoryHierarchyData, IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\n// category description 1.0\r\nimport MsDyn365, { IImageDimension, RichText, RichTextComponent } from '@msdyn365-commerce/core';\r\nimport { format, ProductAvailableQuantity, ProductRefinerValue, ProductSearchResult, SortColumn, TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\r\nimport { getActivePricesAsync, getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { AffiliationLoyaltyTier, ProductPrice, ProjectionDomain } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\nimport { buildListPageUrl, getCollectionProducts, getCurrentUrl, GetFullProductsByCollectionInput, hydrateRefinersFromUrl, IFullProductsSearchResultsWithCount, parseQueryParam, sortOptions, } from '../../dataActions/search-result-container';\r\nimport { publish } from '../../Utilities/analytics/analytics-dispatcher';\r\nimport CommerceAttributesParser from '../../Utilities/commerce-attributes-parser';\r\nimport { filterInvalidCategories } from '../../Utilities/refiners';\r\n\r\nimport { ErrorMessage, getUpdatedRefinementCriteria, IChoiceSummaryClickNotification,\r\n IRefineItemCommonProps, IRefineItemToggleNotification, ISearchResultModalViewProps, isMatchingRefinementCriterion, Link, ModalToggle, ProductSearchResultItems, SearchResultModal, Separator, Title } from './components';\r\nimport ChoiceSummary from './components/choice-summary';\r\nimport RefinePulldown from './components/refine-pulldown';\r\nimport RefineSubmenu from './components/refine-submenu';\r\nimport SMWEPagination from './components/smwe-pagination';\r\nimport { ISmweSearchResultContainerData } from './smwe-search-result-container.data';\r\nimport { ISmweSearchResultContainerProps } from './smwe-search-result-container.props.autogenerated';\r\n\r\nexport interface ISearchResultContainerViewProps extends ISmweSearchResultContainerProps<{}> {\r\n products?: React.ReactNode;\r\n className?: string;\r\n SearchResultContainer: IModuleProps;\r\n TitleViewProps: ITitleViewProps;\r\n categoryHierarchy: ICategoryHierarchyViewProps;\r\n pagination?: React.ReactNode;\r\n ProductsContainer: INodeProps;\r\n ProductSectionContainer: INodeProps;\r\n refineMenu: IRefineMenuViewProps;\r\n sortByOptions: ISortByViewProps;\r\n choiceSummary?: React.ReactNode;\r\n modalToggle: React.ReactNode;\r\n searchResultModal: ISearchResultModalViewProps;\r\n isMobile: boolean;\r\n CategoryNavContainer: INodeProps;\r\n RefineAndProductSectionContainer: INodeProps;\r\n errorMessage: React.ReactNode;\r\n categoryDescription: JSX.Element | undefined;\r\n}\r\n\r\nexport interface ITitleViewProps {\r\n TitleContainer: INodeProps;\r\n title:ISearchResultTitle;\r\n}\r\n\r\nexport interface IRefineMenuViewProps {\r\n RefineMenuContainer: INodeProps;\r\n RefinerSectionContainer: INodeProps;\r\n refiners?: React.ReactNode[];\r\n activeRefiners: ProductRefinerValue[];\r\n pulldownText?: string;\r\n}\r\n\r\nexport interface ICategoryHierarchyViewProps {\r\n categoryHierarchyList?: React.ReactNode[];\r\n categoryHierarchySeparator?: React.ReactNode;\r\n CategoryHierarchyContainer: INodeProps;\r\n}\r\n\r\nexport interface ISortByViewProps {\r\n SortingContainer: INodeProps;\r\n sortByDropDown?:React.ReactNode;\r\n}\r\n\r\nexport type GridSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * Title component for search result container\r\n */\r\nexport interface ISearchResultTitle {\r\n titlePrefix?: React.ReactNode;\r\n titleText?: React.ReactNode;\r\n titleCount?: React.ReactNode;\r\n}\r\n\r\nexport interface ISearchResultContainerState {\r\n sortingState: ISortByCollectionState;\r\n modalIsOpen: boolean;\r\n productAvailability: ProductAvailableQuantity[] | undefined;\r\n clubPricing: ProductPrice[] | undefined;\r\n}\r\n\r\ninterface ISortByCollectionState {\r\n selectedSortByOption: ILabeledDropdownOption;\r\n pending: boolean;\r\n}\r\n\r\ninterface IImageSettingsViewports {\r\n xs: IImageDimension;\r\n sm?: IImageDimension | undefined;\r\n md?: IImageDimension | undefined;\r\n lg?: IImageDimension | undefined;\r\n xl?: IImageDimension | undefined;\r\n}\r\n\r\n/**\r\n *\r\n * SearchResultContainer component\r\n * @extends {React.Component<ISmweSearchResultContainerProps<ISmweSearchResultContainerData>>}\r\n */\r\n@observer\r\nexport default class SmweSearchResultContainer extends React.Component<ISmweSearchResultContainerProps<ISmweSearchResultContainerData>, ISearchResultContainerState> {\r\n\r\n @computed get isMobile(): boolean {\r\n return (this._viewport === 'xs' || this._viewport === 'sm' || this._viewport === 'md');\r\n }\r\n\r\n private sortByDropdownOptions: ILabeledDropdownOption[] = [];\r\n private showSortByDropdown: boolean= false;\r\n private _refineItemCommonProps: IRefineItemCommonProps;\r\n private _pageType: string | undefined = this.props.context.request.urlTokens.pageType;\r\n @observable\r\n private _viewport: GridSize;\r\n\r\n @observable\r\n private _refinersFiltered: boolean = false;\r\n\r\n private _modalToggleRef: React.RefObject<HTMLButtonElement>;\r\n private _sortAndFilterContainerRef: React.RefObject<LabeledDropdown>;\r\n private _initialProductResultCount: number = 0;\r\n\r\n public static getFriendlyName(locale: string, nameTranslations?: TextValueTranslation[]): string | undefined {\r\n let nameTranslation: TextValueTranslation | undefined;\r\n if (locale && nameTranslations && nameTranslations.length > 0) {\r\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\r\n }\r\n\r\n return nameTranslation && nameTranslation.Text;\r\n }\r\n\r\n // tslint:disable-next-line: max-func-body-length\r\n constructor(props: ISmweSearchResultContainerProps<ISmweSearchResultContainerData>, state: ISearchResultContainerState) {\r\n super(props);\r\n this._viewport = props.context.request && props.context.request.device && props.context.request.device.Type === 'Mobile' ? 'xs' : 'lg';\r\n this._modalToggleRef = React.createRef<HTMLButtonElement>();\r\n this._sortAndFilterContainerRef = React.createRef<LabeledDropdown>();\r\n this._toggleModal = this._toggleModal.bind(this);\r\n this._updateViewport = this._updateViewport.bind(this);\r\n this._addSortByDropdownOptions();\r\n\r\n const modifiedImageSettings = props.config.imageSettings;\r\n if(modifiedImageSettings) {\r\n if(modifiedImageSettings.viewports) {\r\n modifiedImageSettings.viewports = this.usePNGImageSetting(modifiedImageSettings.viewports);\r\n }\r\n }\r\n\r\n this.state = {\r\n sortingState: {\r\n pending: false,\r\n selectedSortByOption: this.sortByDropdownOptions[0]\r\n },\r\n modalIsOpen: false,\r\n productAvailability: undefined,\r\n clubPricing: undefined\r\n };\r\n const {\r\n placeholderTextMax,\r\n minLabel,\r\n maxLabel,\r\n rangeNameFormat\r\n } = this.props.resources;\r\n\r\n const locale = this.props.context.request.locale;\r\n const telemetry = this.props.telemetry;\r\n const validationErrorNaN = this.props.resources.validationErrorNotNumber;\r\n const validationErrorRange = this.props.resources.validationErrorNotRange;\r\n this._refineItemCommonProps = {\r\n telemetry,\r\n locale,\r\n placeholderTextMax,\r\n minLabel,\r\n maxLabel,\r\n rangeNameFormat,\r\n validationErrorNaN,\r\n validationErrorRange\r\n };\r\n\r\n // Initalization of list page\r\n // Have an ugly promise cascade. Promise.all() does NOT work right here. That causes everything below to run after render instead of before.\r\n void this.props.data.products.then(products => {\r\n void this.props.data.listPageState.then(listPageState => {\r\n void this.props.data.refiners.then(refiners => {\r\n void this.props.data.categoryHierarchy.then(categoryHierarchy => {\r\n if (this._pageType === 'Category') {\r\n listPageState.pageType = 'Category';\r\n } else {\r\n listPageState.pageType = 'Search';\r\n }\r\n\r\n let querySorting: SortColumn[] = [];\r\n\r\n if (this.props.context.request.query && this.props.context.request.query.sorting) {\r\n querySorting = JSON.parse(decodeURIComponent(this.props.context.request.query.sorting)) as SortColumn[];\r\n }\r\n\r\n // This sets off a render cascade\r\n listPageState.currentPageNumber = this.props.context.request.query && (+this.props.context.request.query.skip / (this.props.config.itemsPerPage || 10)) || 0;\r\n listPageState.sortingCritera = { Columns: querySorting };\r\n listPageState.pageSize = this.props.config.itemsPerPage || 10;\r\n listPageState.activeProducts = products.products;\r\n listPageState.totalProductCount = products.count;\r\n this._initialProductResultCount = products.count;\r\n listPageState.activeFilters = hydrateRefinersFromUrl(this.props.context.request);\r\n\r\n filterInvalidCategories(refiners, categoryHierarchy, this.props.context.app.config.refinerRemappers);\r\n this._refinersFiltered = true;\r\n\r\n if (props.config.addToCart) {\r\n // tslint:disable-next-line: no-floating-promises\r\n void this._getProductavailabilty(products);\r\n if (props.context.app.config.affiliationId) {\r\n void this._getClubPricing(products);\r\n }\r\n }\r\n this._emitImpressionEvent(products.products);\r\n\r\n // Initialize reaction based on listPageState properties\r\n reaction(\r\n () => {\r\n return [listPageState.activeFilters && listPageState.activeFilters.length, listPageState.currentPageNumber, listPageState.sortingCritera && listPageState.sortingCritera.Columns && listPageState.sortingCritera.Columns.length];\r\n },\r\n () => {\r\n const input = new GetFullProductsByCollectionInput(\r\n listPageState.pageType,\r\n this.props.context.request.apiSettings,\r\n { Paging: { Top: this.props.config.itemsPerPage, Skip: Math.max((listPageState.pageSize * (listPageState.currentPageNumber || 0)), 0) }, count: true, Sorting: listPageState.sortingCritera || {} },\r\n listPageState.activeFilters || [],\r\n +(this.props.context.request.urlTokens.itemId || 0),\r\n this.props.context.request.query && this.props.context.request.query.q);\r\n\r\n getCollectionProducts(input, this.props.context.actionContext).then(productResults => {\r\n listPageState.activeProducts = productResults.products;\r\n listPageState.totalProductCount = productResults.count || this._initialProductResultCount;\r\n if (props.config.addToCart) {\r\n // tslint:disable-next-line: no-floating-promises\r\n void this._getProductavailabilty(productResults);\r\n if (this.props.context.app.config.affiliationId) {\r\n void this._getClubPricing(productResults);\r\n }\r\n }\r\n this._emitImpressionEvent(productResults.products);\r\n }).catch(e => this.props.telemetry.exception(e));\r\n }\r\n );\r\n });\r\n });\r\n });\r\n });\r\n\r\n this._updateViewport();\r\n }\r\n\r\n public componentDidMount(): void {\r\n // tslint:disable-next-line: no-typeof-undefined\r\n if (typeof window !== 'undefined' && window.addEventListener) {\r\n window.addEventListener('resize', this._updateViewport);\r\n this._updateViewport();\r\n }\r\n }\r\n\r\n public componentWillUnmount(): void {\r\n // tslint:disable-next-line: no-typeof-undefined\r\n if (typeof window !== 'undefined' && window.addEventListener) {\r\n window.removeEventListener('resize', this._updateViewport);\r\n }\r\n }\r\n\r\n public usePNGImageSetting = (viewports: IImageSettingsViewports): IImageSettingsViewports => {\r\n const modifiedViewports = viewports;\r\n if(modifiedViewports?.xs?.q) {\r\n modifiedViewports.xs.q = modifiedViewports.xs.q.replace('f=jpg', 'f=png');\r\n }\r\n if(modifiedViewports?.sm?.q) {\r\n modifiedViewports.sm.q = modifiedViewports.sm.q.replace('f=jpg', 'f=png');\r\n }\r\n if(modifiedViewports?.md?.q) {\r\n modifiedViewports.md.q = modifiedViewports.md.q.replace('f=jpg', 'f=png');\r\n }\r\n if(modifiedViewports?.lg?.q) {\r\n modifiedViewports.lg.q = modifiedViewports.lg.q.replace('f=jpg', 'f=png');\r\n }\r\n if(modifiedViewports?.xl?.q) {\r\n modifiedViewports.xl.q = modifiedViewports.xl.q.replace('f=jpg', 'f=png');\r\n }\r\n\r\n return modifiedViewports;\r\n };\r\n\r\n public render(): JSX.Element {\r\n const { imageSettings, className, paragraph, showPagination, addToCart } = this.props.config;\r\n const { resources, telemetry, data } = this.props;\r\n const products = (this.props.data.listPageState.result && this.props.data.listPageState.result.activeProducts) || [];\r\n let errorText = '';\r\n if(!products || products.length === 0) {\r\n errorText = this._pageType === 'Category'? resources.resultCategoryNotFoundText : resources.resultSearchNotFoundText;\r\n\r\n }\r\n const categoryHierarchy = (data.category && data.category.result) || undefined;\r\n const passedProps = {...this.props, categoryHierarchy };\r\n const showQuantityAsDropdown = this.props.config.showQuantityAsDropdown || false;\r\n const productsComponent = (\r\n <ProductSearchResultItems\r\n cart={this.props.data.cart}\r\n addToCart={addToCart}\r\n products={products}\r\n context={this.props.context}\r\n imageSettings={imageSettings}\r\n telemetry={telemetry}\r\n resources={resources}\r\n moduleType={this.props.typeName}\r\n moduleId={this.props.id}\r\n parentProps={passedProps}\r\n productAvailability={this.state.productAvailability}\r\n clubPricing={this.state.clubPricing}\r\n showQuantityAsDropdown={showQuantityAsDropdown}\r\n />\r\n );\r\n // category-description 1.0\r\n const categoryDescription = this._getCategoryDescription(paragraph);\r\n\r\n const searchResultContainerViewProps = {\r\n ...this.props,\r\n products: productsComponent,\r\n TitleViewProps: this._getCollectionTitle(),\r\n categoryHierarchy: this._getCategoryHierarchy(),\r\n refineMenu: this._getRefineMenu(),\r\n className: classnames('ms-search-result-container', className),\r\n SearchResultContainer: {\r\n moduleProps: this.props,\r\n className: classnames('ms-search-result-container', className)\r\n },\r\n sortByOptions: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 && this.showSortByDropdown && this.props.config.showSortBy ? this._getSortingDropDown(): null,\r\n pagination: showPagination ? this._getPagination() : '',\r\n ProductsContainer: { className: 'ms-search-result-container__Products' },\r\n ProductSectionContainer: {className: 'ms-search-result-container__product-section'},\r\n CategoryNavContainer: {className: 'ms-search-result-container__category-nav-section'},\r\n RefineAndProductSectionContainer: {className: 'ms-search-result-container__refine-product-section'},\r\n choiceSummary: this._getChoiceSummary(),\r\n modalToggle: this.props.data.listPageState.result && this.props.data.listPageState.result.totalProductCount !== 0 ?\r\n (\r\n <ModalToggle\r\n text={resources.modalTitle}\r\n ariaLabel={resources.modalTitle}\r\n innerRef={this._modalToggleRef}\r\n onClick={this._toggleModal}\r\n id='search-result-modal'\r\n />\r\n ) : null,\r\n searchResultModal: this._getSearchResultModal(),\r\n isMobile: this.isMobile,\r\n errorMessage: errorText && (\r\n <ErrorMessage text={errorText} />\r\n ),\r\n categoryDescription: categoryDescription\r\n };\r\n return this.props.renderView(searchResultContainerViewProps) as React.ReactElement;\r\n }\r\n\r\n private _addSortByDropdownOptions = ():void => {\r\n if(this.props.config.showSortingByRelevance) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionRelevanceDesc, value: this.props.resources.sortByOptionRelevanceDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if(this.props.config.showSortingByName) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionNameAsc, value: this.props.resources.sortByOptionNameAsc });\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionNameDesc, value: this.props.resources.sortByOptionNameDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if(this.props.config.showSortingByPrice) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionPriceAsc, value: this.props.resources.sortByOptionPriceAsc });\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionPriceDesc, value: this.props.resources.sortByOptionPriceDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n if(this.props.config.showSortingByRating) {\r\n this.sortByDropdownOptions.push({ key: sortOptions.sortByOptionRatingDesc, value: this.props.resources.sortByOptionRatingDesc });\r\n this.showSortByDropdown = true;\r\n }\r\n };\r\n\r\n private _getSearchResultModal = (): ISearchResultModalViewProps => {\r\n const {resources} = this.props;\r\n return SearchResultModal(\r\n {\r\n resources:{\r\n modalCloseButtonText: resources.modalCloseButtonText,\r\n modalTitle: resources.modalTitle\r\n },\r\n isOpen:this.state.modalIsOpen,\r\n returnRef: this._modalToggleRef,\r\n onModalToggle: this._toggleModal\r\n });\r\n };\r\n\r\n private _getCollectionTitle = (): ITitleViewProps => {\r\n const { data, context, resources } = this.props;\r\n\r\n let collectionTitle: string | undefined = '';\r\n if (context && context.request && context.request.query && context.request.query.q) {\r\n collectionTitle = `\"${context.request.query.q}\"`;\r\n } else {\r\n collectionTitle = (data.category.result && SmweSearchResultContainer.getFriendlyName(context.request.locale, data.category.result.NameTranslations)) ||\r\n (data.category.result && data.category.result.Name);\r\n }\r\n let productCountText = '';\r\n let productCountNumber: number | undefined;\r\n if (data.listPageState && data.listPageState.result && data.listPageState.result.totalProductCount !== undefined) {\r\n productCountNumber = data.listPageState.result.totalProductCount;\r\n } else if (data.products && data.products.result) {\r\n productCountNumber = data.products.result.count;\r\n }\r\n\r\n if (productCountNumber && productCountNumber !== 0) {\r\n productCountText = productCountNumber !== 1 ? format(this.props.resources.numberOfProducts, productCountNumber) : this.props.resources.oneProduct;\r\n } else {\r\n productCountText = format(this.props.resources.numberOfProducts, 0);\r\n }\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={resources.searchTextPrefix} />;\r\n const titleText = collectionTitle && <Title className='ms-search-result__collection-title-text' text={collectionTitle} />;\r\n const titleCount = <Title className='ms-search-result__collection-title-count' text={productCountText} />;\r\n\r\n return {\r\n TitleContainer: { className: 'ms-search-result-container__title' },\r\n title:{\r\n titlePrefix: titlePrefix,\r\n titleText: titleText,\r\n titleCount: titleCount\r\n }\r\n };\r\n\r\n };\r\n private _getCategoryHierarchy = (): ICategoryHierarchyViewProps => {\r\n const { data } = this.props;\r\n const categoryHierarchy = data.categoryHierarchy.result;\r\n const categoryLinks =\r\n categoryHierarchy && categoryHierarchy.map((value: CategoryHierarchyData, index: number) => {\r\n\r\n return (\r\n <Link\r\n key={index}\r\n text={value.Name}\r\n ariaLabel={`${this.props.resources.categoryLinkAriaLabel} ${value.Name}`}\r\n href={value.Url}\r\n />\r\n );\r\n });\r\n const categoryLinkSeparator = <Separator separator='/' />;\r\n\r\n return {\r\n CategoryHierarchyContainer: { tag: 'nav', className: 'ms-search-result-container__category-hierarchy' },\r\n categoryHierarchyList: categoryLinks,\r\n categoryHierarchySeparator: categoryLinkSeparator\r\n };\r\n\r\n };\r\n\r\n private _getSortingDropDown = (): ISortByViewProps => {\r\n const { resources } = this.props;\r\n const activeDropdown = this._getCurrentlySelectedOption() || this.state.sortingState.selectedSortByOption;\r\n const dropdown = (\r\n <LabeledDropdown\r\n labelClassname='reviews-list-sort-by'\r\n labelText={resources.sortByDropdownLabel}\r\n dropdownId='categorySortByDropdown'\r\n dropdownClassname='reviews-list-dropdown'\r\n toggleColor='link'\r\n dropdownOptions={this.sortByDropdownOptions}\r\n selectedOption={activeDropdown}\r\n onSelectOption={this._updateSortByDropdown}\r\n ref={this._sortAndFilterContainerRef}\r\n />);\r\n return {\r\n SortingContainer: { className: 'ms-search-result-container__Sort-by-category' },\r\n sortByDropDown:dropdown\r\n };\r\n };\r\n\r\n private _getPagination = (): React.ReactNode => {\r\n const { config, context, data, resources } = this.props;\r\n const listPageState = data && data.listPageState && data.listPageState.result;\r\n const fullUrl = getCurrentUrl(context.request);\r\n const itemsPerPage = config.itemsPerPage || 10;\r\n const skipCount = listPageState && listPageState.currentPageNumber !== null ?\r\n (listPageState.currentPageNumber * (this.props.config.itemsPerPage || 10)) :\r\n ((this.props.context.request.query && +this.props.context.request.query.skip) || 0);\r\n const totalItems = listPageState && listPageState.totalProductCount || 0;\r\n const previousText = resources.flipperPrevious;\r\n const nextText = resources.flipperNext;\r\n const totalActiveProducts = listPageState?.activeProducts?.length || 0;\r\n\r\n if (totalItems <= itemsPerPage) {\r\n return null;\r\n }\r\n if (totalActiveProducts <= 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <SMWEPagination\r\n className='ms-search-result-container__pagination'\r\n role='navigation'\r\n aria-label={'Product Navigation'}\r\n url={fullUrl.href}\r\n qsp={'skip'}\r\n items={totalItems}\r\n itemsPerPage={itemsPerPage}\r\n startingItem={skipCount}\r\n previousText={<div className='msc-pagination__prev'><span className='ms-search-result__pagination-left' aria-hidden='true'/><span className='prev-text'>{previousText}</span></div>}\r\n nextText={<div className='msc-pagination__next'><span className='next-text'>{nextText}</span><span className='ms-search-result__pagination-right' aria-hidden='true'/></div>}\r\n previousAriaLabel={'Previous, click here to view the previous page'}\r\n nextAriaLabel={'Next, click here to view the next page'}\r\n />);\r\n };\r\n\r\n private _getRefineMenu = (): IRefineMenuViewProps => {\r\n const { data, context } = this.props;\r\n const tempRangeTypeTODO = context.request.query && context.request.query.inputRange ? 'input' : 'slider';\r\n const validRefiners = this._refinersFiltered && data.refiners.result && data.refiners.result.filter(refiner => {\r\n return refiner.Values.length > 0;\r\n });\r\n\r\n const activeRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n let subMenus;\r\n if (validRefiners) {\r\n if (this.props.config.pulldownRefiners) {\r\n subMenus = validRefiners.map((productRefinerHierarchy: IProductRefinerHierarchy, index: number) => {\r\n return (data.listPageState.result!.totalProductCount !== 0 ?\r\n (\r\n <RefinePulldown\r\n highestLevelRefinerText={this.props.config.highestLevelItem}\r\n productRefinerHierarchy={productRefinerHierarchy}\r\n selectedRefinerValues={activeRefiners}\r\n refineItemCommonProps={this._refineItemCommonProps}\r\n minValueSliderThumbAriaLabel={this.props.resources.minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={this.props.resources.maxValueSliderThumbAriaLabel}\r\n key={index}\r\n onUpdateRefiners={this._onUpdateRefiners}\r\n urlBuilder={this._buildRefinerUrl}\r\n isDisabled={false}\r\n tempRangeTypeTODO={tempRangeTypeTODO}\r\n context={context}\r\n moduleId={this.props.id}\r\n moduleTypeName={this.props.typeName}\r\n buttonText={this.props.config.pulldownButtonText}\r\n />) : null\r\n );\r\n });\r\n } else {\r\n subMenus = validRefiners.map((productRefinerHierarchy: IProductRefinerHierarchy, index: number) => {\r\n return (data.listPageState.result!.totalProductCount !== 0 ?\r\n (\r\n <RefineSubmenu\r\n highestLevelRefinerText={this.props.config.highestLevelItem}\r\n productRefinerHierarchy={productRefinerHierarchy}\r\n selectedRefinerValues={activeRefiners}\r\n refineItemCommonProps={this._refineItemCommonProps}\r\n minValueSliderThumbAriaLabel={this.props.resources.minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={this.props.resources.maxValueSliderThumbAriaLabel}\r\n refinerMinimizeText={this.props.resources.refinerMinimizeText}\r\n refinerExpandText={this.props.resources.refinerExpandText}\r\n minimizedRefiners={this.props.config.minimizedRefiners}\r\n key={index}\r\n onUpdateRefiners={this._onUpdateRefiners}\r\n urlBuilder={this._buildRefinerUrl}\r\n isDisabled={false}\r\n isExpandedOnInitialLoad={this.props.config.collapseRefiners ? false : true}\r\n tempRangeTypeTODO={tempRangeTypeTODO}\r\n context={context}\r\n moduleId={this.props.id}\r\n moduleTypeName={this.props.typeName}\r\n />) : null\r\n );\r\n });\r\n }\r\n }\r\n\r\n return {\r\n RefineMenuContainer:{className: 'ms-search-result-container__refine-menu' },\r\n RefinerSectionContainer:{className: 'ms-search-result-container__refiner-section'},\r\n refiners: subMenus || undefined, // type shenanigans\r\n activeRefiners: activeRefiners,\r\n pulldownText: this.props.config.pulldownButtonText || 'All Wines'\r\n };\r\n\r\n };\r\n\r\n private _getChoiceSummary = (): React.ReactNode => {\r\n const { resources, data, telemetry } = this.props;\r\n const selectedRefiners = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n return (\r\n <ChoiceSummary\r\n classNames='ms-choice-summary-by-category'\r\n clearAllText={resources.clearAllText}\r\n label={resources.choiceSummaryLabel}\r\n selectedChoices={selectedRefiners}\r\n // @ts-ignore: NOTE Type-unsafe line below, null refinersByCategoryHierarchy case not handled\r\n refinerHierarchy={data.refiners.result}\r\n choiceFormat={resources.choiceFormat}\r\n choiceRangeValueFormat={resources.choiceRangeValueFormat}\r\n telemetry={telemetry}\r\n onChoiceClicked={this._onChoiceClicked}\r\n urlBuilder={this._buildRefinerUrlForChoiceSummary}\r\n choiceAriaLabel={resources.choiceAriaLabel}\r\n />\r\n );\r\n\r\n };\r\n\r\n private _updateSortByDropdown = (notification: ILabeledDropdownOnChangeNotification): void => {\r\n const { context } = this.props;\r\n const requestContext = context && context.request;\r\n const actionContext = context && context.actionContext;\r\n\r\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\r\n const error = `[sort-by-category] cannot sort without context: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\r\n this.props.telemetry.warning(error);\r\n }\r\n\r\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), undefined, [this._getSortColumnFromSelectedOption(notification.selectedOption)], undefined));\r\n transaction(() => {\r\n this.props.data.listPageState.result!.currentPageNumber = 0;\r\n this.props.data.listPageState.result!.sortingCritera = { Columns: [this._getSortColumnFromSelectedOption(notification.selectedOption)] };\r\n });\r\n };\r\n\r\n private _getSortColumnFromSelectedOption = (option: ILabeledDropdownOption): SortColumn => {\r\n const { data } = this.props;\r\n\r\n if (!data.searchConfiguration.result) {\r\n return {};\r\n }\r\n\r\n const mappedConfiguration = data.searchConfiguration.result.find((searchConfiguration) => { return searchConfiguration.key === option.key; });\r\n\r\n if (mappedConfiguration) {\r\n return mappedConfiguration.sortColumn;\r\n }\r\n\r\n return {};\r\n };\r\n\r\n private _getCurrentlySelectedOption = (): ILabeledDropdownOption | undefined => {\r\n const { data } = this.props;\r\n const sortCriteria = data.listPageState.result && data.listPageState.result.sortingCritera;\r\n\r\n const activeSortColumn =\r\n (sortCriteria?.Columns?.length && sortCriteria.Columns[0]) ||\r\n (parseQueryParam<SortColumn[]>('sorting', this.props.context.request) || [])[0];\r\n\r\n if (activeSortColumn && data.searchConfiguration.result) {\r\n const activeMappedConfig = data.searchConfiguration.result.find((mappedSearchConfig) => {\r\n return (mappedSearchConfig.sortColumn.ColumnName === activeSortColumn.ColumnName) &&\r\n (mappedSearchConfig.sortColumn.IsDescending === activeSortColumn.IsDescending);\r\n });\r\n if (activeMappedConfig) {\r\n return this.sortByDropdownOptions.find((dropdownOption) => dropdownOption.key === activeMappedConfig.key);\r\n }\r\n }\r\n\r\n return;\r\n };\r\n\r\n private _onUpdateRefiners = (itemToggleNotification: IRefineItemToggleNotification): void => {\r\n const { context } = this.props;\r\n const requestContext = context && context.request;\r\n const actionContext = context && context.actionContext;\r\n\r\n if (!requestContext || !actionContext || !this.props.data.listPageState.result) {\r\n const error = `Refine menu cannot refine search criteria: ${!requestContext ? 'requestContext ' : ''} ${!actionContext ? 'actionContext ' : ''} could not be found`;\r\n this.props.telemetry.warning(error);\r\n }\r\n\r\n const updatedRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result && this.props.data.listPageState.result.activeFilters || []);\r\n\r\n window.history.pushState({}, '', buildListPageUrl(getCurrentUrl(this.props.context.request), updatedRefinementCriteria));\r\n transaction(() => {\r\n this.props.data.listPageState.result!.currentPageNumber = 0;\r\n this.props.data.listPageState.result!.activeFilters = updatedRefinementCriteria;\r\n });\r\n };\r\n\r\n private _buildRefinerUrl = (itemToggleNotification: IRefineItemToggleNotification): string => {\r\n if (this.props.data.listPageState.result) {\r\n const newRefinementCriteria = getUpdatedRefinementCriteria(itemToggleNotification, this.props.data.listPageState.result.activeFilters || []);\r\n\r\n return buildListPageUrl(getCurrentUrl(this.props.context.request), newRefinementCriteria);\r\n } else {\r\n this.props.telemetry.warning(`[buildRefinerQueryString]List Page State Not available, unable to build refiner URL`);\r\n return '';\r\n }\r\n };\r\n\r\n private _onChoiceClicked = (notification: IChoiceSummaryClickNotification): void => {\r\n const { data, telemetry } = this.props;\r\n\r\n if (!data.listPageState.result) {\r\n telemetry.warning('[choice-summary-by-category._onChoiceClicked]ListPageState unavailable, unable to update refiners.');\r\n return;\r\n }\r\n\r\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n\r\n if (!notification.clearAll) {\r\n const selectedChoice = notification.choiceClicked;\r\n if (!selectedChoice) {\r\n telemetry.warning('[choice-summary-by-category._onChoiceClicked] Choice could not be determined');\r\n return;\r\n }\r\n currentRefinementCriteria = currentRefinementCriteria.filter(\r\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedChoice, selectedCriterion)\r\n );\r\n } else {\r\n currentRefinementCriteria = [];\r\n\r\n // set focus to sort and filter\r\n const dropdownElementId = this._sortAndFilterContainerRef.current && this._sortAndFilterContainerRef.current.props.dropdownId;\r\n const dropdownElement = dropdownElementId && document.getElementById(dropdownElementId);\r\n setTimeout(() => {\r\n dropdownElement && dropdownElement.focus();\r\n },\r\n 50);\r\n }\r\n\r\n const fullUrl = getCurrentUrl(this.props.context.request);\r\n window.history.pushState({}, '', buildListPageUrl(fullUrl, currentRefinementCriteria));\r\n data.listPageState.result.currentPageNumber = 0;\r\n data.listPageState.result.activeFilters = currentRefinementCriteria;\r\n };\r\n\r\n private _buildRefinerUrlForChoiceSummary = (selectedRefiner: ProductRefinerValue, isClearAll: boolean): string => {\r\n const { data, telemetry } = this.props;\r\n const fullUrl = getCurrentUrl(this.props.context.request);\r\n\r\n if (!data.listPageState.result) {\r\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl]ListPageState unavailable, unable to create refiner URL.');\r\n return fullUrl.href;\r\n }\r\n\r\n let currentRefinementCriteria = (data.listPageState.result && data.listPageState.result.activeFilters) || [];\r\n\r\n if (!isClearAll) {\r\n if (!selectedRefiner) {\r\n telemetry.warning('[choice-summary-by-category._buildRefinerUrl] URL for Choice could not be determined');\r\n return fullUrl.href;\r\n }\r\n currentRefinementCriteria = currentRefinementCriteria.filter(\r\n (selectedCriterion: ProductRefinerValue) => !isMatchingRefinementCriterion(selectedRefiner, selectedCriterion)\r\n );\r\n } else {\r\n currentRefinementCriteria = [];\r\n }\r\n\r\n return buildListPageUrl(fullUrl, currentRefinementCriteria);\r\n };\r\n\r\n private _getViewport(): GridSize {\r\n const { context } = this.props;\r\n\r\n // always render in mobile viewport on a mobile device\r\n if (context.request && context.request.device && context.request.device.Type === 'Mobile') {\r\n return 'xs';\r\n }\r\n\r\n if (MsDyn365.isBrowser && window.innerWidth) {\r\n const gridSettings = context.request.gridSettings;\r\n if (gridSettings) {\r\n if (gridSettings.xs && window.innerWidth <= gridSettings.xs.w) {\r\n return 'xs';\r\n } else if (gridSettings.sm && window.innerWidth <= gridSettings.sm.w) {\r\n return 'sm';\r\n } else if (gridSettings.md && window.innerWidth <= gridSettings.md.w) {\r\n return 'md';\r\n } else if (gridSettings.lg && window.innerWidth <= gridSettings.lg.w) {\r\n return 'lg';\r\n } else {\r\n return 'xl';\r\n }\r\n }\r\n }\r\n\r\n return 'lg';\r\n }\r\n\r\n private _toggleModal(): void {\r\n this.setState({\r\n modalIsOpen: !this.state.modalIsOpen\r\n });\r\n }\r\n\r\n private _updateViewport(): void {\r\n this._viewport = this._getViewport();\r\n\r\n if (this.state.modalIsOpen && !this.isMobile) {\r\n this._toggleModal();\r\n }\r\n }\r\n\r\n private _getCategoryDescription(paragraph: RichText | undefined): JSX.Element | undefined {\r\n\r\n if (paragraph && paragraph.length > 0) {\r\n return <RichTextComponent className='category-description' text={paragraph}/>;\r\n }\r\n return undefined;\r\n }\r\n\r\n private async _getProductavailabilty(products: IFullProductsSearchResultsWithCount): Promise<void> {\r\n if (products && products.count && products.count > 0) {\r\n const productIds: number[] = [];\r\n products.products.forEach((product) => {\r\n productIds.push(product.RecordId);\r\n });\r\n const availabilityAll = await getEstimatedAvailabilityAsync({ callerContext: this.props.context.actionContext }, {ProductIds: productIds, DefaultWarehouseOnly: true});\r\n const formattedResponse = availabilityAll.ProductWarehouseInventoryAvailabilities?.map((product) => {\r\n return {ProductId: product.ProductId, AvailableQuantity: product.PhysicalAvailable, ExtensionProperties: product.ExtensionProperties};\r\n }) as ProductAvailableQuantity[];\r\n this.setState({productAvailability: formattedResponse});\r\n }\r\n }\r\n\r\n private async _getClubPricing(products: IFullProductsSearchResultsWithCount): Promise<void> {\r\n const projectDomain: ProjectionDomain = { ChannelId: +this.props.context.request.apiSettings.channelId, CatalogId: +this.props.context.request.apiSettings.catalogId };\r\n let affiliations: AffiliationLoyaltyTier[];\r\n if (this.props.context.app.config.affiliationId) {\r\n affiliations = [\r\n {\r\n AffiliationId: this.props.context.app.config.affiliationId\r\n }\r\n ];\r\n } else {\r\n affiliations = [];\r\n }\r\n const productIds: number[] = [];\r\n products.products.forEach((product) => {\r\n productIds.push(product.RecordId);\r\n });\r\n const clubPricingAll = await getActivePricesAsync(\r\n { callerContext: this.props.context.actionContext },\r\n projectDomain,\r\n productIds,\r\n new Date(),\r\n '',\r\n affiliations,\r\n true\r\n );\r\n this.setState({clubPricing: clubPricingAll});\r\n }\r\n\r\n //----------------------------------------------------------\r\n //----------------------------------------------------------\r\n private _emitImpressionEvent(products: ProductSearchResult[]): void {\r\n const impressions = products.map(product => ({\r\n product,\r\n attributes: CommerceAttributesParser.getParsedAttributes(product.AttributeValues || []),\r\n }));\r\n\r\n publish('impression', {\r\n products: impressions,\r\n\r\n list: 'Category Page', // Could be Search Results if we ever enable search results pages\r\n category: this.props.data.category.result?.Name,\r\n context: this.props.context,\r\n });\r\n }\r\n}\r\n","import { CategoryHierarchy, IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\n\r\n// Refiner Remappers, stored in global config\r\nexport interface IRemapper {\r\n originalName: string;\r\n newName: string;\r\n}\r\n\r\n//-----------------------------------------------------\r\n// Remove category refiners that aren't in the current\r\n// position within the hierarchy.\r\n//-----------------------------------------------------\r\nexport function filterInvalidCategories(refiners: IProductRefinerHierarchy[], categoryHierarchy: CategoryHierarchy[], remappers: IRemapper[]): void {\r\n // If we don't have any refiners (yet), don't do anything\r\n if (!refiners || !refiners.length) {\r\n return undefined;\r\n }\r\n\r\n // Find the category refiner name\r\n const categoryRemapper = remappers && remappers.find(remapRecord => remapRecord.originalName.toLowerCase() === `category`);\r\n const categoryRefinerName = categoryRemapper ? categoryRemapper.newName : `Category`;\r\n\r\n // Find the category refiners\r\n const categoryRefiners = refiners.find(entry => (entry.KeyName === categoryRefinerName));\r\n\r\n // Filter out invalid entries\r\n if (categoryRefiners) {\r\n // Construct a list of valid categories (note: this only goes one level deep!)\r\n const categoryIDs = {};\r\n\r\n if (categoryHierarchy && categoryHierarchy[0]) {\r\n categoryHierarchy[0].Children?.forEach(entry => categoryIDs[entry.RecordId] = true);\r\n }\r\n\r\n // Remove refiners that aren't in the list of categories\r\n categoryRefiners.Values = categoryRefiners.Values.filter(entry => (entry.RefinerRecordId && categoryIDs[entry.RefinerRecordId]));\r\n }\r\n}\r\n","import getMappedSearchConfiguration, { MappedSearchInput, sortOptions } from './get-mapped-search-configuration';\r\nimport getCollectionRefinersAction, { RefinersByCollectionInput } from './get-refiners-for-collection';\r\nimport { IFullProductsSearchResultsWithCount } from './IFullProductsSearchResultsWithCount';\r\nimport { IMappedSearchConfiguration } from './IMappedSearchConfiguration';\r\nimport getCollectionProducts, { GetFullProductsByCollectionInput } from './smwe-get-full-products-by-collection';\r\n\r\nexport * from './base-collection-action';\r\nexport * from './url-utils';\r\n\r\nexport {\r\n getCollectionProducts,\r\n getCollectionRefinersAction,\r\n GetFullProductsByCollectionInput,\r\n getMappedSearchConfiguration,\r\n IFullProductsSearchResultsWithCount,\r\n IMappedSearchConfiguration,\r\n MappedSearchInput,\r\n RefinersByCollectionInput,\r\n sortOptions\r\n};","import { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { RatingComponent } from '@msdyn365-commerce/components';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { ProductRefinerSource, ProductRefinerTypeValue } from './utilities';\r\n\r\n/**\r\n * RefineItem properties\r\n */\r\nexport interface IRefineItemProps {\r\n\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\r\n productRefinerValue: ProductRefinerValue;\r\n selectedRefinementCriterion: ProductRefinerValue | undefined;\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n context: ICoreContext;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n onToggle(notfication: Readonly<IRefineItemToggleNotification>): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine item state\r\n */\r\nexport interface IRefineItemState extends React.ComponentState {\r\n isChecked: boolean;\r\n renderingError?: object;\r\n}\r\n\r\n/**\r\n * Single-select and multi-select refine item component (controlled by RefineSubmenu)\r\n */\r\nexport default class RefineItem extends React.Component<IRefineItemProps, IRefineItemState> {\r\n private anchorType: React.RefObject<HTMLAnchorElement>;\r\n\r\n constructor(props: IRefineItemProps) {\r\n super(props);\r\n this._onClick = this._onClick.bind(this);\r\n this.state = {\r\n isChecked: !!this.props.selectedRefinementCriterion\r\n };\r\n this.anchorType = React.createRef();\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n selectedRefinementCriterion,\r\n children,\r\n onToggle,\r\n context,\r\n ...attrs\r\n } = this.props;\r\n if (!productRefinerValue) {\r\n refineItemCommonProps.telemetry.error('[refine-item] Cannot render refineItem without productRefinerValue');\r\n return undefined;\r\n }\r\n if (!productRefinerValue.LeftValueBoundString) {\r\n refineItemCommonProps.telemetry.warning(`[refine-item] RefineItem without LeftValueBoundString: ${JSON.stringify(productRefinerValue)}`);\r\n }\r\n const isSingleSelect = parentProductRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single;\r\n let itemTypeClassName = isSingleSelect ? 'single-select' : 'multi-select';\r\n itemTypeClassName = `ms-refine-submenu-item ${itemTypeClassName}`;\r\n const inputType = isSingleSelect ? 'radio' : 'checkbox';\r\n const role = isSingleSelect ? 'radio' : undefined;\r\n itemTypeClassName = !!selectedRefinementCriterion ? `${itemTypeClassName}-checked` : itemTypeClassName;\r\n if (parentProductRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) {\r\n if (productRefinerValue.LeftValueBoundString) {\r\n return (\r\n <li\r\n className='ms-refine-submenu-item'\r\n role='radio'\r\n aria-checked='false'\r\n id={`${parentProductRefinerHierarchy.KeyName! }_${productRefinerValue.LeftValueBoundLocalizedString}`}\r\n aria-label={`${parentProductRefinerHierarchy.KeyName!}_${productRefinerValue.LeftValueBoundLocalizedString}`}\r\n >\r\n <a\r\n href={this._getRefinerUrl()}\r\n aria-label={`${parentProductRefinerHierarchy.KeyName!}_${productRefinerValue.LeftValueBoundLocalizedString}`}\r\n onClick={this._onClick}\r\n >\r\n <RatingComponent\r\n avgRating={parseInt(productRefinerValue.LeftValueBoundString, 10)}\r\n ratingCount={productRefinerValue.LeftValueBoundLocalizedString ? productRefinerValue.LeftValueBoundLocalizedString : productRefinerValue.LeftValueBoundString}\r\n hideCount={false}\r\n readOnly={true}\r\n ariaLabel=''\r\n context={context}\r\n id={this.props.moduleId}\r\n typeName={this.props.moduleTypeName}\r\n data={{}}\r\n />\r\n <span className='refine-submenu-item__rating'>{productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}</span>\r\n </a>\r\n </li>\r\n );\r\n } else {\r\n return undefined;\r\n }\r\n } else {\r\n return (\r\n <li className='ms-refine-submenu-item' role={role} id={`${parentProductRefinerHierarchy.KeyName!}_${productRefinerValue.LeftValueBoundString}`}>\r\n <a\r\n key={!!selectedRefinementCriterion ? 'true' : 'false'}\r\n ref={this.anchorType}\r\n href={this._getRefinerUrl()}\r\n tabIndex={0}\r\n onClick={this._onClick}\r\n className={itemTypeClassName}\r\n role={inputType}\r\n aria-checked={!!selectedRefinementCriterion}\r\n {...attrs}\r\n >\r\n <span className='ms-refine-submenu-item__label'>\r\n {productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}\r\n </span>\r\n </a>\r\n </li>\r\n );\r\n }\r\n }\r\n\r\n private _getRefinerUrl(): string {\r\n const { urlBuilder, parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n\r\n if (productRefinerValue) {\r\n return urlBuilder({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n }\r\n\r\n return '';\r\n }\r\n\r\n private _onClick = (e: React.MouseEvent<HTMLAnchorElement | HTMLInputElement>): void => {\r\n e.preventDefault();\r\n\r\n const { parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n if (productRefinerValue) {\r\n this.props.onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n\r\n setTimeout(\r\n () => {\r\n this.anchorType.current && this.anchorType.current.focus();\r\n },\r\n 0\r\n );\r\n }\r\n };\r\n}","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport { ICoreContext, IImageSettings, ITelemetry } from '@msdyn365-commerce/core';\r\nimport { ICartState, ICheckoutState } from '@msdyn365-commerce/global-state';\r\nimport { AsyncResult, ProductAvailableQuantity, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport ProductCard, { ISmweSearchResultContainerParentProps } from '../../../components/product.component';\r\nimport { IElicitSubscriptionsResources } from '../elicit-subscriptions.props.autogenerated';\r\n\r\ninterface IProductSearchResultItems {\r\n products: ProductSearchResult[];\r\n context: ICoreContext;\r\n resources: IElicitSubscriptionsResources;\r\n telemetry: ITelemetry;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n parentProps: ISmweSearchResultContainerParentProps;\r\n checkoutState?: AsyncResult<ICheckoutState>;\r\n disableQuantitySlider?: boolean;\r\n maxAdditionLimit?: number;\r\n cart?: AsyncResult<ICartState>;\r\n productAvailability?: ProductAvailableQuantity[] | undefined;\r\n}\r\n\r\nexport const ProductSearchResultItems: React.FC<IProductSearchResultItems> = ({\r\n products,\r\n context,\r\n imageSettings,\r\n resources,\r\n moduleType,\r\n moduleId,\r\n parentProps,\r\n checkoutState,\r\n disableQuantitySlider,\r\n maxAdditionLimit,\r\n cart,\r\n productAvailability\r\n}) => {\r\n return (\r\n\r\n <ul className='list-unstyled'>\r\n {products.map((product: ProductSearchResult, index: number) => {\r\n const availibity = productAvailability?.find((item) => {\r\n return item.ProductId === product.RecordId;\r\n });\r\n return (\r\n <li className='ms-product-search-result__item' key={index}>\r\n <ProductCard\r\n displayQuantitySlider={true}\r\n cart={cart}\r\n disableQuantitySlider={disableQuantitySlider}\r\n maxAdditionLimit={maxAdditionLimit}\r\n subscriptionBtnText={resources.elicitSubscriptions_buyboxSubscriptionBtnTxt}\r\n checkoutState={checkoutState}\r\n context={context}\r\n imageSettings={imageSettings}\r\n freePriceText={resources.priceFree}\r\n originalPriceText={resources.originalPriceText}\r\n currentPriceText={resources.currentPriceText}\r\n ratingAriaLabel={resources.ratingAriaLabel}\r\n id={moduleId}\r\n typeName={moduleType}\r\n data={{ product: product }}\r\n parentProps={parentProps}\r\n availability={availibity}\r\n addToCartMessage={resources.addToBoxMessagePlp}\r\n />\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n );\r\n\r\n};","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\nimport { ISmweSearchResultContainerProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container.props.autogenerated';\r\n\r\n// tslint:disable-next-line:cyclomatic-complexity\r\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps & ISmweSearchResultContainerProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {/*TODO remove after final testing */}\r\n {/*categoryHierarchy && renderCategoryHierarchy(categoryHierarchy)*/}\r\n {renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && !props.config.pulldownRefiners && choiceSummary}\r\n {showRefiners && !props.config.pulldownRefiners && modalToggle}\r\n {showRefiners && !props.config.pulldownRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && !props.config.pulldownRefiners && refineMenu && renderRefiner(refineMenu)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefinerPulldown = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer, pulldownText, activeRefiners } = props;\r\n const activeRefinersText = getActiveRefinersText(activeRefiners);\r\n const dynamicPulldownText = getPulldownText(activeRefinersText, pulldownText);\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-pulldown-button' id='refiner-pulldown-button'>\r\n <span className='ms-search-result-container__refiner-pulldown-button-content' id='refiner-pulldown-button-content'>{dynamicPulldownText}</span>\r\n </button>\r\n <div className='ms-search-result-container__refiner-pulldown-container pulldown-hide' id='refiner-pulldown-container'>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-close-pulldown-button'>Close</button>\r\n </div>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst getPulldownText = (activeRefiners: string, buttonText: string | undefined): string => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n const spanElement = document.getElementById('refiner-pulldown-button-content');\r\n if (buttonElement && spanElement) {\r\n if (buttonElement.className === 'ms-search-result-container__refiner-pulldown-button refiner-pulldown-button-expanded' || !activeRefiners) {\r\n return spanElement.innerText = buttonText || '';\r\n } else {\r\n return spanElement.innerText = activeRefiners;\r\n }\r\n }\r\n return '';\r\n};\r\n\r\nconst togglePulldown = (activeRefiners: string, buttonText: string | undefined): void => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n if (buttonElement) {\r\n buttonElement.classList.toggle('refiner-pulldown-button-expanded');\r\n getPulldownText(activeRefiners, buttonText);\r\n }\r\n const pulldownElement = document.getElementById('refiner-pulldown-container');\r\n if (pulldownElement) {\r\n pulldownElement.classList.toggle('pulldown-hide');\r\n }\r\n\r\n};\r\n\r\nconst getActiveRefinersText = (activeRefiners: ProductRefinerValue[]): string => {\r\n let formatedActiveRefiners = '';\r\n activeRefiners.forEach(refiner => {\r\n if (refiner.UnitText === 'USD') {\r\n formatedActiveRefiners += `$${refiner.LeftValueBoundString}-$${refiner.RightValueBoundString} / `;\r\n } else if (refiner.LeftValueBoundString) {\r\n formatedActiveRefiners += `${refiner.LeftValueBoundString} / `;\r\n }\r\n });\r\n // removes trailing slash and whitespace\r\n formatedActiveRefiners = formatedActiveRefiners.substring(0, formatedActiveRefiners.length - 2);\r\n return formatedActiveRefiners;\r\n};\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2 aria-level={1}>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nexport default SearchResultContainerView;","export * from './link';\r\nexport * from './product-search-result-items';\r\nexport * from './title';\r\nexport * from './separator';\r\nexport * from './range-refine-item';\r\nexport * from './refine-item';\r\nexport * from './refine-item-toggle-notification';\r\nexport * from './refine-item.props.common';\r\nexport * from './utilities';\r\nexport * from './choice-summary';\r\nexport * from './choice-summary.props';\r\nexport * from './modal';\r\nexport * from './refine-submenu';\r\nexport * from './error-message';\r\n","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst SmweSearchResultContainerView: React.FC<ISearchResultContainerViewProps> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage,\r\n categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showRefiners && modalToggle}\r\n {showRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && refineMenu && renderRefiner(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n};\r\n\r\nexport default SmweSearchResultContainerView;\r\n","import * as React from 'react';\r\ninterface ILink {\r\n className?: string;\r\n text?: string;\r\n href?: string;\r\n ariaLabel?: string;\r\n}\r\n\r\nexport const Link: React.FC<ILink> = ({ text, className, href, ariaLabel }) => (<a className={className} href={href} aria-label={ariaLabel}> {text} </a>);","import * as React from 'react';\r\ninterface ISeparator {\r\n separator: string;\r\n}\r\n\r\nexport const Separator: React.FC<ISeparator> = ({ separator }) => (<span> {separator} </span>);","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from './components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from './elicit-subscriptions';\r\nimport { IElicitSubscriptionsProps } from './elicit-subscriptions.props.autogenerated';\r\n\r\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps & IElicitSubscriptionsProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showRefiners && modalToggle}\r\n {showRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && refineMenu && renderRefiner(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nexport default SearchResultContainerView;","import * as React from 'react';\r\ninterface ISeparator {\r\n separator: string;\r\n}\r\n\r\nexport const Separator: React.FC<ISeparator> = ({ separator }) => (<span> {separator} </span>);","/* tslint:disable */\r\nimport { IReactComponent } from 'mobx-react/index';\r\nimport React, { Component, ComponentType } from 'react';\r\n\r\ntype subscriptionCallback<T> = (...args: T[]) => void;\r\n\r\ntype subscription<T> = { [uniqueId: string]: subscriptionCallback<T> };\r\n\r\n/**\r\n * A loader that maintains a list of current namespaces. Meant to be later\r\n * singleton'd\r\n */\r\nclass EventBusLoader {\r\n\r\n // list of current buses that are in action\r\n private _buses: { [namespace: string]: BusLoader } = {};\r\n\r\n /**\r\n * get's an existing bus or creating a new bus of that namespace\r\n *\r\n * @param busNamespace the namespace of the bus to retrieve\r\n */\r\n public getBus(busNamespace: string): BusLoader {\r\n // fast return if the bus already exists\r\n if (this._buses[busNamespace]) {\r\n return this._buses[busNamespace];\r\n }\r\n\r\n // create a new bus and do the internal subscription for deleting the entire bus when bus\r\n // is empty\r\n this._buses[busNamespace] = new BusLoader();\r\n this._buses[busNamespace].subscribe('_readyForDeletion', this.deleteBus.bind(this));\r\n return this._buses[busNamespace];\r\n }\r\n\r\n /**\r\n * deletes and purges all events\r\n *\r\n * @param busNamespace the namespace of the bus to delete\r\n */\r\n public deleteBus(busNamespace: string): void {\r\n if (this._buses[busNamespace]) {\r\n this._buses[busNamespace].purge();\r\n }\r\n delete this._buses[busNamespace];\r\n }\r\n}\r\n\r\n/**\r\n * Contains a single namespace of events of the event bus\r\n */\r\nexport class BusLoader {\r\n\r\n // list of all subscriptions within this bus's namespace\r\n private _subscriptions: { [subName: string]: subscription<unknown> } = {};\r\n\r\n /**\r\n * subscribe to a subscription within this namespace\r\n *\r\n * @param subName event subscription name\r\n * @param onPublish callback that triggers when subscription gets published\r\n */\r\n public subscribe<T>(subName: string, onPublish: subscriptionCallback<T>): { unsubscribe(): void, id: number } {\r\n\r\n // generates an ever-counting up id generator\r\n const nextId = IdGenerator();\r\n\r\n // create a new list if the bus loader contains no subscription\r\n if (!this._subscriptions[subName]) {\r\n this._subscriptions[subName] = {\r\n _readyForDeletion: () => { /* event to notify loader that this is going to be deleted */ }\r\n };\r\n }\r\n\r\n // add the subscription to the list\r\n this._subscriptions[subName][nextId] = onPublish as subscriptionCallback<unknown>;\r\n\r\n // return an unsubscribe method for deleting this specific subscription\r\n return {\r\n id: nextId,\r\n unsubscribe: () => {\r\n this._purgeById(subName, nextId);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * remove a subscription from anywhere within the namespace\r\n *\r\n * @param id subscription id\r\n */\r\n public unsubscribe(id: number): boolean {\r\n for (const subName in this._subscriptions) {\r\n if (this._subscriptions[subName][id]) {\r\n this._purgeById(subName, id);\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * publish data to all subscriptions\r\n *\r\n * @param subName subscription name to publish to\r\n * @param args data to pass into the subscribed functions\r\n */\r\n public publish(subName: string, ...args: any): void {\r\n // don't do anything if it doesnt exist and fail\r\n // gracefully\r\n if (!this._subscriptions[subName]) {\r\n return;\r\n }\r\n\r\n Object.keys(this._subscriptions[subName])\r\n .forEach(id => {\r\n this._subscriptions[subName] && this._subscriptions[subName][id] && this._subscriptions[subName][id](...args);\r\n });\r\n }\r\n\r\n /**\r\n * purge all data in the bus loader\r\n */\r\n public purge(): void {\r\n this._subscriptions = {};\r\n }\r\n\r\n /**\r\n * purges a single subscription id endpoint from a subscription\r\n * name\r\n *\r\n * @param subName subscription name\r\n * @param id subscription id\r\n */\r\n private _purgeById(subName: string, id: number) {\r\n delete this._subscriptions[subName][id];\r\n\r\n // not zero because there will always be the internal _readyForDeletion event\r\n if (Object.keys(this._subscriptions[subName]).length === 1) {\r\n this.publish('_readyForDeletion');\r\n delete this._subscriptions[subName];\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * generates a singleton of ids\r\n */\r\nconst IdGenerator = (() => {\r\n let idValue = 0;\r\n\r\n return () => {\r\n idValue += 1;\r\n return idValue;\r\n };\r\n})();\r\n\r\n/**\r\n * generates a singleton of the bus loader\r\n */\r\nconst Loader = (() => {\r\n return new EventBusLoader();\r\n})();\r\n\r\nexport function LoadBus<T extends IReactComponent>(eventNamespace: string): <T extends IReactComponent>(newComponent: T) => void {\r\n return (CHILD_COMP: ComponentType) => {\r\n return class extends Component {\r\n constructor(props: any) {\r\n super(props);\r\n\r\n // add to the component the bus\r\n CHILD_COMP.prototype.bus = this.bus;\r\n }\r\n\r\n // the bus's definition\r\n public get bus() { return Loader.getBus(eventNamespace); }\r\n\r\n // we arent decorating anything related to the UI so just return the child with\r\n // all it's props\r\n public render(): JSX.Element {\r\n return <CHILD_COMP {...this.props} />;\r\n }\r\n };\r\n };\r\n}","import * as React from 'react';\r\ninterface ITitle {\r\n className: string;\r\n text: string;\r\n}\r\n\r\nexport const Title: React.FC<ITitle> = ({ text, className }) => (<span className={className}> {text} </span>);\r\n","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\n\r\nimport { ISmweSearchResultContainerProps } from '../definition-extensions/smwe-search-result-container.ext.props.autogenerated';\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst SmweSearchResultContainerView: React.FC<ISearchResultContainerViewProps & ISmweSearchResultContainerProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage,\r\n categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showRefiners && modalToggle}\r\n {showRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && refineMenu && renderRefiner(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n\r\n};\r\n\r\nexport default SmweSearchResultContainerView;","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from './components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from './smwe-search-result-container';\r\nimport { ISmweSearchResultContainerProps } from './smwe-search-result-container.props.autogenerated';\r\n\r\n// tslint:disable-next-line:cyclomatic-complexity\r\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps & ISmweSearchResultContainerProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {/*TODO remove after final testing */}\r\n {/*categoryHierarchy && renderCategoryHierarchy(categoryHierarchy)*/}\r\n {renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && !props.config.pulldownRefiners && choiceSummary}\r\n {showRefiners && !props.config.pulldownRefiners && modalToggle}\r\n {showRefiners && !props.config.pulldownRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && !props.config.pulldownRefiners && refineMenu && renderRefiner(refineMenu)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefinerPulldown = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer, pulldownText, activeRefiners } = props;\r\n const activeRefinersText = getActiveRefinersText(activeRefiners);\r\n const dynamicPulldownText = getPulldownText(activeRefinersText, pulldownText);\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-pulldown-button' id='refiner-pulldown-button'>\r\n <span className='ms-search-result-container__refiner-pulldown-button-content' id='refiner-pulldown-button-content'>{dynamicPulldownText}</span>\r\n </button>\r\n <div className='ms-search-result-container__refiner-pulldown-container pulldown-hide' id='refiner-pulldown-container'>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-close-pulldown-button'>Close</button>\r\n </div>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst getPulldownText = (activeRefiners: string, buttonText: string | undefined): string => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n const spanElement = document.getElementById('refiner-pulldown-button-content');\r\n if (buttonElement && spanElement) {\r\n if (buttonElement.className === 'ms-search-result-container__refiner-pulldown-button refiner-pulldown-button-expanded' || !activeRefiners) {\r\n return spanElement.innerText = buttonText || '';\r\n } else {\r\n return spanElement.innerText = activeRefiners;\r\n }\r\n }\r\n return '';\r\n};\r\n\r\nconst togglePulldown = (activeRefiners: string, buttonText: string | undefined): void => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n if (buttonElement) {\r\n buttonElement.classList.toggle('refiner-pulldown-button-expanded');\r\n getPulldownText(activeRefiners, buttonText);\r\n }\r\n const pulldownElement = document.getElementById('refiner-pulldown-container');\r\n if (pulldownElement) {\r\n pulldownElement.classList.toggle('pulldown-hide');\r\n }\r\n\r\n};\r\n\r\nconst getActiveRefinersText = (activeRefiners: ProductRefinerValue[]): string => {\r\n let formatedActiveRefiners = '';\r\n activeRefiners.forEach(refiner => {\r\n if (refiner.UnitText === 'USD') {\r\n formatedActiveRefiners += `$${refiner.LeftValueBoundString}-$${refiner.RightValueBoundString} / `;\r\n } else if (refiner.LeftValueBoundString) {\r\n formatedActiveRefiners += `${refiner.LeftValueBoundString} / `;\r\n }\r\n });\r\n // removes trailing slash and whitespace\r\n formatedActiveRefiners = formatedActiveRefiners.substring(0, formatedActiveRefiners.length - 2);\r\n return formatedActiveRefiners;\r\n};\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nexport default SearchResultContainerView;","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\nimport { ISmweSearchResultContainerProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container.props.autogenerated';\r\n\r\n// tslint:disable-next-line:cyclomatic-complexity\r\nconst SearchResultContainerView: React.FC<ISearchResultContainerViewProps & ISmweSearchResultContainerProps<{}>> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage, categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {/*TODO remove after final testing */}\r\n {/*categoryHierarchy && renderCategoryHierarchy(categoryHierarchy)*/}\r\n {renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && !props.config.pulldownRefiners && choiceSummary}\r\n {showRefiners && !props.config.pulldownRefiners && modalToggle}\r\n {showRefiners && !props.config.pulldownRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && !props.config.pulldownRefiners && refineMenu && renderRefiner(refineMenu)}\r\n {showRefiners && props.config.pulldownRefiners && refineMenu && renderRefinerPulldown(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n {categoryDescription}\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefinerPulldown = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer, pulldownText, activeRefiners } = props;\r\n const activeRefinersText = getActiveRefinersText(activeRefiners);\r\n const dynamicPulldownText = getPulldownText(activeRefinersText, pulldownText);\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-pulldown-button' id='refiner-pulldown-button'>\r\n <span className='ms-search-result-container__refiner-pulldown-button-content' id='refiner-pulldown-button-content'>{dynamicPulldownText}</span>\r\n </button>\r\n <div className='ms-search-result-container__refiner-pulldown-container pulldown-hide' id='refiner-pulldown-container'>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n {/* tslint:disable-next-line:jsx-no-lambda react-this-binding-issue */}\r\n <button onClick={() => togglePulldown(getActiveRefinersText(activeRefiners), pulldownText)} className='ms-search-result-container__refiner-close-pulldown-button'>Close</button>\r\n </div>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst getPulldownText = (activeRefiners: string, buttonText: string | undefined): string => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n const spanElement = document.getElementById('refiner-pulldown-button-content');\r\n if (buttonElement && spanElement) {\r\n if (buttonElement.className === 'ms-search-result-container__refiner-pulldown-button refiner-pulldown-button-expanded' || !activeRefiners) {\r\n return spanElement.innerText = buttonText || '';\r\n } else {\r\n return spanElement.innerText = activeRefiners;\r\n }\r\n }\r\n return '';\r\n};\r\n\r\nconst togglePulldown = (activeRefiners: string, buttonText: string | undefined): void => {\r\n const buttonElement = document.getElementById('refiner-pulldown-button');\r\n if (buttonElement) {\r\n buttonElement.classList.toggle('refiner-pulldown-button-expanded');\r\n getPulldownText(activeRefiners, buttonText);\r\n }\r\n const pulldownElement = document.getElementById('refiner-pulldown-container');\r\n if (pulldownElement) {\r\n pulldownElement.classList.toggle('pulldown-hide');\r\n }\r\n\r\n};\r\n\r\nconst getActiveRefinersText = (activeRefiners: ProductRefinerValue[]): string => {\r\n let formatedActiveRefiners = '';\r\n activeRefiners.forEach(refiner => {\r\n if (refiner.UnitText === 'USD') {\r\n formatedActiveRefiners += `$${refiner.LeftValueBoundString}-$${refiner.RightValueBoundString} / `;\r\n } else if (refiner.LeftValueBoundString) {\r\n formatedActiveRefiners += `${refiner.LeftValueBoundString} / `;\r\n }\r\n });\r\n // removes trailing slash and whitespace\r\n formatedActiveRefiners = formatedActiveRefiners.substring(0, formatedActiveRefiners.length - 2);\r\n return formatedActiveRefiners;\r\n};\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h1 className='h2'>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h1>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nexport default SearchResultContainerView;","import { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport classnames from 'classnames';\r\nimport { get } from 'lodash';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport { IChoiceSummaryProps } from './choice-summary.props';\r\nimport { isMatchingRefinementCriterion, ProductRefinerValueDataTypeValue } from './utilities';\r\n\r\ninterface IRefinerMap {\r\n key: string;\r\n value: ProductRefinerValue;\r\n}\r\n\r\n /**\r\n * ChoiceSummary component\r\n */\r\n@observer\r\nexport default class ChoiceSummary extends React.Component<IChoiceSummaryProps> {\r\n private closeButtonGlyph: string = 'msi-close-btn';\r\n\r\n @computed get selectedRefinersMap(): IRefinerMap[] {\r\n const { selectedChoices } = this.props;\r\n return selectedChoices.map((selectedRefiner: ProductRefinerValue) => {\r\n return {\r\n key: this._getKeyForRefinerValue(selectedRefiner),\r\n value: selectedRefiner\r\n } as IRefinerMap;\r\n });\r\n }\r\n\r\n constructor(props: Readonly<IChoiceSummaryProps>) {\r\n super(props);\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { clearAllText, label, classNames, choiceAriaLabel } = this.props;\r\n const items = this.selectedRefinersMap;\r\n return (\r\n <div className='msc-choice-summary'>\r\n {items.length > 0 && label && <span className='msc-choice-summary__label'>{label}</span>}\r\n <ul className={classnames(classNames, 'msc-choice-summary__list', 'list-unstyled')}>\r\n {items.map((item: IRefinerMap, index: number) => {\r\n const listItemProps = {\r\n 'aria-posinset': index,\r\n 'aria-setsize': items.length\r\n };\r\n\r\n return (\r\n <li className='msc-choice-summary__list-item' key={item.key} {...listItemProps}>\r\n <a\r\n className='msc-choice-summary__item'\r\n href={this.props.urlBuilder(item.value, false)}\r\n aria-label={`${item.key} ${choiceAriaLabel}`}\r\n onClick={this._onClick}\r\n >\r\n {item.key}\r\n <span className={`${this.closeButtonGlyph} msc-choice-summary__glyph`} />\r\n </a>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n {items.length > 0 && clearAllText && <a href={this.props.urlBuilder({}, true)} className={'msc-choice-summary__clear-all'} onClick={this._onClick}>{clearAllText}</a>}\r\n </div>\r\n );\r\n }\r\n\r\n private _getKeyForRefinerValue(productRefinerValue: ProductRefinerValue): string {\r\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry } = this.props;\r\n const overallFormat = choiceFormat || '{1}';\r\n const rangeFormat = choiceRangeValueFormat;\r\n let refinerName = '';\r\n if (refinerHierarchy && refinerHierarchy.find) {\r\n const parent = refinerHierarchy.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, productRefinerValue))\r\n );\r\n\r\n if (!parent) {\r\n telemetry.warning('[choice-summary] could not find parent of selected refiner value');\r\n } else {\r\n refinerName = parent.KeyName || '';\r\n }\r\n }\r\n\r\n let refinerValueName: string;\r\n switch (productRefinerValue.DataTypeValue) {\r\n case ProductRefinerValueDataTypeValue.Range:\r\n case ProductRefinerValueDataTypeValue.RangeInput:\r\n refinerValueName = rangeFormat\r\n .replace('{0}', this._formatPrice(productRefinerValue.LeftValueBoundString, productRefinerValue.UnitText))\r\n .replace('{1}', this._formatPrice(productRefinerValue.RightValueBoundString, productRefinerValue.UnitText));\r\n break;\r\n default:\r\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n }\r\n\r\n return overallFormat.replace('{0}', refinerName).replace('{1}', refinerValueName);\r\n }\r\n\r\n private _formatPrice(amount: string | undefined, currency: string | undefined): string {\r\n if (!amount || !currency) {\r\n this.props.telemetry.trace('[choice-summary] could not format price');\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n const locale = get(this.props, 'context.request.locale', 'en-US');\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency: currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (e) {\r\n result = `${priceAmount} ${currency}`;\r\n this.props.telemetry.warning(`Failed to format price for ${result}: ${e}`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _onClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const target = e.currentTarget as HTMLElement;\r\n const clearAll = target.getAttribute('class')!.indexOf('choice-summary__clear-all') > -1;\r\n const selectedRefiner = clearAll ? undefined : this._getSelectedRefinerChoice(target);\r\n\r\n if (this.props.onChoiceClicked) {\r\n this.props.onChoiceClicked({\r\n clearAll: clearAll,\r\n itemClicked: target,\r\n choiceClicked: selectedRefiner,\r\n nextItemToFocus: target.nextSibling as HTMLElement\r\n });\r\n }\r\n };\r\n\r\n private _getSelectedRefinerChoice(itemClicked: HTMLElement): ProductRefinerValue | undefined {\r\n const result = this.selectedRefinersMap.find(selected => (itemClicked.innerText && itemClicked.innerText.trim()) === selected.key);\r\n return (result && result.value) || undefined;\r\n }\r\n}\r\n","import { Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport { ISearchResultModalViewProps, Title } from '../../../modules/smwe-search-result-container/components';\r\nimport { IRefineMenuViewProps, ISearchResultContainerViewProps, ISortByViewProps, ITitleViewProps } from '../../../modules/smwe-search-result-container/smwe-search-result-container';\r\n\r\nconst renderSort = (props: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n const { SortingContainer, sortByDropDown } = props;\r\n if (sortByDropDown && showSortBy) {\r\n return (\r\n <Node {...SortingContainer}>\r\n {sortByDropDown}\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderRefiner = (props: IRefineMenuViewProps): JSX.Element | null => {\r\n const { refiners, RefineMenuContainer, RefinerSectionContainer } = props;\r\n if (refiners) {\r\n return (\r\n <Node {...RefinerSectionContainer}>\r\n <Node {...RefineMenuContainer}>\r\n {refiners.map((submenu, index) => (\r\n <React.Fragment key={index}>\r\n {submenu}\r\n </React.Fragment>\r\n ))}\r\n </Node>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst createModalBody = (props: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element | null => {\r\n if (sortByDropDown) {\r\n return React.cloneElement(props.modalBody, {}, renderSort(sortByDropDown, showSortBy), renderRefiner(refineMenu));\r\n }\r\n return null;\r\n};\r\n\r\nconst createSearchResultModal = (modalProps: ISearchResultModalViewProps, refineMenu: IRefineMenuViewProps, sortByDropDown: ISortByViewProps, showSortBy: boolean): JSX.Element => {\r\n return React.cloneElement(modalProps.modal, {}, modalProps.modalHeader, createModalBody(modalProps, refineMenu, sortByDropDown, showSortBy), modalProps.modalFooter);\r\n};\r\n\r\nconst renderTitle = (props: ITitleViewProps, showResultPrefix: boolean, categoryNamePrefix: string): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n const titlePrefix = <Title className='ms-search-result__collection-title-prefix' text={categoryNamePrefix} />;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h2>\r\n {showResultPrefix && titlePrefix}\r\n {title.titleText}\r\n </h2>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst renderTitleCount = (props: ITitleViewProps): JSX.Element | null => {\r\n const { title, TitleContainer } = props;\r\n if (title) {\r\n return (\r\n <Node {...TitleContainer}>\r\n <h5>\r\n {title.titleCount}\r\n </h5>\r\n </Node>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst SmweSearchResultContainerView: React.FC<ISearchResultContainerViewProps> = props => {\r\n const { SearchResultContainer, products, pagination, ProductsContainer, ProductSectionContainer, choiceSummary, isMobile, modalToggle, searchResultModal, TitleViewProps,\r\n refineMenu, sortByOptions, CategoryNavContainer, RefineAndProductSectionContainer, errorMessage,\r\n categoryDescription } = props;\r\n // customization for 1.0\r\n const { showRefiners, showSortBy, showResultCount, categoryNamePrefix } = props.config;\r\n if (isMobile) {\r\n return (\r\n <Module {...SearchResultContainer}>\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showRefiners && modalToggle}\r\n {showRefiners && createSearchResultModal(searchResultModal, refineMenu, sortByOptions, showSortBy!)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Module>\r\n );\r\n }\r\n return (\r\n <Module {...SearchResultContainer}>\r\n {showResultCount && TitleViewProps && <Node {...CategoryNavContainer}>\r\n {renderTitleCount(TitleViewProps)}\r\n </Node>}\r\n <Node {...RefineAndProductSectionContainer}>\r\n {showRefiners && refineMenu && renderRefiner(refineMenu)}\r\n <Node {...ProductSectionContainer}>\r\n <div className='ms-search-result-container__title-header'>\r\n {TitleViewProps && renderTitle(TitleViewProps, showResultCount!, categoryNamePrefix!)}\r\n {categoryDescription}\r\n </div>\r\n <div className='ms-search-result-container__filter-sort'>\r\n {showRefiners && choiceSummary}\r\n {showSortBy && sortByOptions && renderSort(sortByOptions, showSortBy)}\r\n </div>\r\n <Node {...ProductsContainer}>\r\n {errorMessage}\r\n {products}\r\n </Node>\r\n {pagination}\r\n </Node>\r\n </Node>\r\n </Module>\r\n );\r\n};\r\n\r\nexport default SmweSearchResultContainerView;\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport { ICoreContext, IImageSettings, ITelemetry } from '@msdyn365-commerce/core';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { AsyncResult, ProductAvailableQuantity, ProductPrice, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport * as React from 'react';\r\nimport ProductCard, { ISmweSearchResultContainerParentProps } from '../../../components/product.component';\r\nimport { ISmweSearchResultContainerResources } from '../smwe-search-result-container.props.autogenerated';\r\n\r\ninterface IProductSearchResultItems {\r\n products: ProductSearchResult[];\r\n context: ICoreContext;\r\n resources: ISmweSearchResultContainerResources;\r\n telemetry: ITelemetry;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n parentProps: ISmweSearchResultContainerParentProps;\r\n addToCart?: boolean;\r\n cart?: AsyncResult<ICartState>;\r\n productAvailability?: ProductAvailableQuantity[] | undefined;\r\n clubPricing?: ProductPrice[] | undefined;\r\n showQuantityAsDropdown?: boolean;\r\n}\r\n\r\nexport const ProductSearchResultItems: React.FC<IProductSearchResultItems> = ({\r\n products,\r\n context,\r\n imageSettings,\r\n resources,\r\n moduleType,\r\n moduleId,\r\n parentProps,\r\n addToCart,\r\n cart,\r\n productAvailability,\r\n clubPricing,\r\n showQuantityAsDropdown\r\n}) => {\r\n return (\r\n <ul className='list-unstyled'>\r\n {products.map((product: ProductSearchResult, index: number) => {\r\n const availibity = productAvailability?.find((item) => {\r\n return item.ProductId === product.RecordId;\r\n });\r\n const clubPrice = clubPricing?.find((item) => {\r\n return item.ProductId === product.RecordId;\r\n });\r\n return (\r\n <li className='ms-product-search-result__item' key={index}>\r\n <ProductCard\r\n context={context}\r\n imageSettings={imageSettings}\r\n freePriceText={resources.priceFree}\r\n originalPriceText={resources.originalPriceText}\r\n currentPriceText={resources.currentPriceText}\r\n ratingAriaLabel={resources.ratingAriaLabel}\r\n id={moduleId}\r\n typeName={moduleType}\r\n data={{product: product}}\r\n parentProps={parentProps}\r\n addToCart={addToCart}\r\n addToCartText={resources.addToCartTextPlp}\r\n addToCartMessage={resources.addToCartMessagePlp}\r\n giftCardText={resources.giftCardText}\r\n displayQuantitySlider={addToCart}\r\n cart={cart}\r\n availability={availibity}\r\n clubPrice={clubPrice}\r\n showQuantityAsDropdown={showQuantityAsDropdown || false}\r\n />\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n );\r\n};","import { INodeProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\nimport { IProductCollectionViewProps, IProductComponentViewProps } from './smwe-product-collection';\r\n\r\nconst ProductCollectionView: React.FC<IProductCollectionViewProps> = props => {\r\n const { heading, ProductCollectionContainer, products, SingleSlideCarouselComponentProps, GridComponentProps, isCarousel } = props;\r\n if (products) {\r\n return (\r\n <Module {...ProductCollectionContainer}>\r\n {heading}\r\n {\r\n isCarousel ? _renderCarousel(SingleSlideCarouselComponentProps, products) : _renderGrid(GridComponentProps, products)\r\n }\r\n </Module>\r\n );\r\n }\r\n return null;\r\n};\r\n\r\nconst _renderCarousel = (carouselContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return (\r\n <Node {...carouselContainer}>\r\n {items && items.map(_renderProduct)}\r\n </Node>\r\n );\r\n};\r\n\r\nconst _renderGrid = (gridContainer: INodeProps, items: IProductComponentViewProps[]): JSX.Element => {\r\n return (\r\n <Node {...gridContainer}>\r\n {items && items.map(_renderProduct)}\r\n </Node>\r\n );\r\n};\r\n\r\nconst _renderProduct = (product: IProductComponentViewProps): JSX.Element => {\r\n const { ProductContainer, productComponent } = product;\r\n\r\n return (\r\n <Node {...ProductContainer}>\r\n {productComponent}\r\n </Node>\r\n );\r\n};\r\n\r\nexport default ProductCollectionView;","import { Slider } from '@msdyn365-commerce-modules/utilities';\r\nimport debounce from 'lodash/debounce';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport { formatPrice } from './utilities';\r\n\r\ntype InputType = 'Min' | 'Max';\r\n\r\nimport { IRefineItemProps, IRefineItemState } from './refine-item';\r\n\r\nexport type RangeRefineItemType = 'slider' | 'input';\r\n\r\n/**\r\n * Range refine item properties\r\n */\r\nexport interface IRangeRefineItemProps extends IRefineItemProps {\r\n rangeType: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n}\r\n\r\n/**\r\n * Range refine item state\r\n */\r\nexport interface IRangeRefineItemState extends IRefineItemState {\r\n validationErrorMin: string | undefined;\r\n validationErrorMax: string | undefined;\r\n selectedMin: string | undefined;\r\n selectedMax: string | undefined;\r\n touchedMin: boolean;\r\n touchedMax: boolean;\r\n}\r\n\r\n/**\r\n * RangeRefineItem component (controlled by RefineSubmenu)\r\n */\r\n@observer\r\nexport default class RangeRefineItem extends React.Component<IRangeRefineItemProps, IRangeRefineItemState> {\r\n private _formattedPriceReverseLookup: Map<string, string> = new Map();\r\n\r\n private minInput: React.RefObject<HTMLInputElement>;\r\n private maxInput: React.RefObject<HTMLInputElement>;\r\n\r\n @computed get currencyCode(): string {\r\n return this.props.productRefinerValue.UnitText || '';\r\n }\r\n\r\n constructor(props: IRangeRefineItemProps) {\r\n super(props);\r\n this._onRangeUpdate = this._onRangeUpdate.bind(this);\r\n this._onRangeUpdateEnd = this._onRangeUpdateEnd.bind(this);\r\n this._handleRangeTooltipText = this._handleRangeTooltipText.bind(this);\r\n this._changeMin = this._changeMin.bind(this);\r\n this._changeMax = this._changeMax.bind(this);\r\n this._finishChangeMin = this._finishChangeMin.bind(this);\r\n this._finishChangeMax = this._finishChangeMax.bind(this);\r\n\r\n this.minInput = React.createRef<HTMLInputElement>();\r\n this.maxInput = React.createRef<HTMLInputElement>();\r\n\r\n const { selectedRefinementCriterion } = this.props;\r\n const initialMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\r\n const initialMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\r\n this.state = {\r\n isChecked: false,\r\n validationErrorMin: undefined,\r\n validationErrorMax: undefined,\r\n selectedMin: initialMin,\r\n selectedMax: initialMax,\r\n touchedMin: false,\r\n touchedMax: false\r\n };\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const { productRefinerValue, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerValue || !parentProductRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render refine value range without productRefinerValue and parentProductRefinerHierarchy');\r\n return undefined;\r\n }\r\n\r\n if (this.props.rangeType === 'input') {\r\n return this._renderInputFields();\r\n }\r\n\r\n return this._renderSlider();\r\n }\r\n\r\n private _renderInputFields(): JSX.Element | undefined {\r\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n const { selectedMin, selectedMax, touchedMin, touchedMax, validationErrorMin, validationErrorMax } = this.state;\r\n\r\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', (parentProductRefinerHierarchy.KeyName || ''));\r\n const formAttrs = {\r\n 'aria-label': rangeAriaLabel,\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n // To enable price formatting of selected fields, this is the approach:\r\n // initial value: min=0 formatted as price, max=undefined\r\n // onFocus/onChange: convert to number (unformat) and mark as touched to indicate value is being edited\r\n // onBlur: validate and format entered value as price\r\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${validationErrorMin ? 'refine-submenu__input-range--error' : ''}`;\r\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${validationErrorMax ? 'refine-submenu__input-range--error' : ''}`;\r\n const minLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-min';\r\n const maxLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-max';\r\n const formattedSelectedMin = this._getFormattedSelectedValue(selectedMin, touchedMin, validationErrorMin);\r\n const formattedSelectedMax = this._getFormattedSelectedValue(selectedMax, touchedMax, validationErrorMax);\r\n return (\r\n <form className='ms-refine-submenu__input-range-refiner' {...formAttrs}>\r\n <label className={minLabelClassName}>\r\n {refineItemCommonProps.minLabel}\r\n <input\r\n className={minInputClassName}\r\n onChange={this._changeMin}\r\n onFocus={this._changeMin}\r\n onBlur={this._finishChangeMin}\r\n value={formattedSelectedMin}\r\n ref={this.minInput}\r\n />\r\n </label>\r\n <label className={maxLabelClassName}>\r\n {refineItemCommonProps.maxLabel}\r\n <input\r\n className={maxInputClassName}\r\n placeholder={formattedSelectedMax ? undefined : refineItemCommonProps.placeholderTextMax}\r\n onChange={this._changeMax}\r\n onFocus={this._changeMax}\r\n onBlur={this._finishChangeMax}\r\n value={formattedSelectedMax}\r\n ref={this.maxInput}\r\n />\r\n </label>\r\n {validationErrorMin &&\r\n <span className='ms-refine-submenu__input-range-error-text refine-submenu__input-range-min-error-text'>{validationErrorMin}</span>\r\n }\r\n {validationErrorMax && validationErrorMin !== validationErrorMax &&\r\n <span className='ms-refine-submenu__input-range-error-text refine-submenu__input-range-max-error-text'>{validationErrorMax}</span>\r\n }\r\n </form>\r\n );\r\n }\r\n\r\n private _renderSlider(): JSX.Element | undefined {\r\n const { isDisabled, productRefinerValue, parentProductRefinerHierarchy, selectedRefinementCriterion } = this.props;\r\n const min = productRefinerValue.LeftValueBoundString;\r\n const max = productRefinerValue.RightValueBoundString;\r\n const selectedMin = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || productRefinerValue.LeftValueBoundString || '0';\r\n const selectedMax = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || productRefinerValue.RightValueBoundString || max;\r\n const sliderId = `slider_${parentProductRefinerHierarchy.RecordId}_${productRefinerValue.RefinerRecordId}`;\r\n const ariaAttributes = {\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n const minPrice = this._formatPrice(min);\r\n const maxPrice = this._formatPrice(max);\r\n const selectedMinPrice =this._formatPrice(selectedMin);\r\n const selectedMaxPrice =this._formatPrice(selectedMax);\r\n\r\n return (\r\n <Slider\r\n className={'ms-refine-submenu__range-refiner'}\r\n key={sliderId}\r\n id={sliderId}\r\n inForm={false}\r\n min={min && Number(min) || undefined}\r\n max={max && Number(max) || undefined}\r\n step={1}\r\n orientation={'horizontal'}\r\n labels={[\r\n {\r\n labelId: `${sliderId}_start`,\r\n labelString: `${minPrice}`,\r\n labelPositioning: 'start'\r\n },\r\n {\r\n labelId: `${sliderId}_end`,\r\n labelString: `${maxPrice}`,\r\n labelPositioning: 'end'\r\n }\r\n ]}\r\n showLabels={true}\r\n showTooltip={true}\r\n sliderThumbs={[\r\n {\r\n id: `${sliderId}_slider_thumb_start`,\r\n value: selectedMin && Number(selectedMin) || 0,\r\n ariaLabel: `${this.props.minValueSliderThumbAriaLabel} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMinPrice}`\r\n },\r\n {\r\n id: `${sliderId}_slider_thumb_end`,\r\n value: Number(selectedMax) || Number(maxPrice),\r\n ariaLabel: `${this.props.maxValueSliderThumbAriaLabel} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMaxPrice}`\r\n }\r\n ]}\r\n onChangeEnd={this._onRangeUpdateEnd}\r\n onChange={debounce(this._onRangeUpdate, 500)}\r\n handleTooltipText={this._handleRangeTooltipText}\r\n {...ariaAttributes}\r\n />\r\n );\r\n }\r\n\r\n private _changeMin(event: React.FocusEvent<HTMLInputElement>): void {\r\n this._changeValue(event, 'Min');\r\n }\r\n\r\n private _changeMax(event: React.FocusEvent<HTMLInputElement>): void {\r\n this._changeValue(event, 'Max');\r\n }\r\n\r\n private _changeValue(event: React.FocusEvent<HTMLInputElement>, inputType: InputType): void {\r\n const selectedKey = `selected${inputType}`;\r\n const touchedKey = `touched${inputType}`;\r\n this.setState({\r\n [selectedKey]: this._getInputWithoutFormatting(event.currentTarget.value),\r\n [touchedKey]: true\r\n });\r\n }\r\n\r\n private _finishChangeMin(event: React.FocusEvent<HTMLInputElement>): boolean {\r\n const selectedMinValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMin: selectedMinValue,\r\n minTouched: false\r\n });\r\n const minInput = Number(selectedMinValue);\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\r\n const max = selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString || undefined;\r\n\r\n const maxNum = max ? Number(max) : undefined;\r\n\r\n if (isNaN(minInput)) {\r\n this.setState({validationErrorMin: refineItemCommonProps.validationErrorNaN});\r\n this._focus('Min');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minInput, maxNum)) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minInput,\r\n rangeEnd: maxNum\r\n });\r\n return true;\r\n } else {\r\n this._focus('Min');\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _finishChangeMax(event: React.FocusEvent<HTMLInputElement>): boolean {\r\n const selectedMaxValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMax: selectedMaxValue,\r\n maxTouched: false\r\n });\r\n const maxInput = Number(selectedMaxValue);\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue, refineItemCommonProps, selectedRefinementCriterion } = this.props;\r\n const min = selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString || '0';\r\n\r\n const minNum = Number(min);\r\n\r\n if (isNaN(maxInput)) {\r\n this.setState({validationErrorMax: refineItemCommonProps.validationErrorNaN});\r\n this._focus('Max');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minNum, maxInput)) {\r\n if (productRefinerValue) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minNum,\r\n rangeEnd: maxInput\r\n });\r\n } else {\r\n this._focus('Max');\r\n }\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _focus(inputType: InputType): void {\r\n const ref = inputType === 'Max' ? this.maxInput : this.minInput;\r\n\r\n setTimeout(() => {\r\n if (ref && ref.current) {\r\n ref.current.focus();\r\n }\r\n }, 50);\r\n }\r\n\r\n private _getFormattedSelectedValue(selected: string | undefined, touched: boolean, validationError: string | undefined): string | undefined {\r\n if (touched || validationError || selected === undefined) {\r\n return selected;\r\n }\r\n return this._formatPrice(selected);\r\n }\r\n\r\n private _validateRange(min: number, max: number | undefined): boolean {\r\n const { refineItemCommonProps } = this.props;\r\n if (max === undefined) {\r\n return true;\r\n }\r\n\r\n if (min > max) {\r\n this.setState({\r\n validationErrorMin: refineItemCommonProps.validationErrorRange,\r\n validationErrorMax: refineItemCommonProps.validationErrorRange\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _formatPrice(amount: string | undefined): string {\r\n const locale = this.props.refineItemCommonProps.locale;\r\n const result = formatPrice(amount, this.currencyCode, locale, this.props.refineItemCommonProps.telemetry);\r\n\r\n if (amount !== undefined && !this._formattedPriceReverseLookup.has(result)) {\r\n this._formattedPriceReverseLookup.set(result, amount);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private _getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNum = Number(input);\r\n if (!isNaN(inputAsNum)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\r\n return reverseLookupResult || input;\r\n }\r\n\r\n // NOTE: Fix types once Shared Components build pipeline bug fixed\r\n // tslint:disable-next-line:no-any\r\n private _onRangeUpdate(sliderChangeNotification: any): void {\r\n // Need to filter out mousemove events as these cause errors after the menu updates and slider re-renders\r\n if (sliderChangeNotification.eventType !== 'mousemove') {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n }\r\n\r\n // tslint:disable-next-line\r\n private _onRangeUpdateEnd(sliderChangeNotification: any): void {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy: parentProductRefinerHierarchy,\r\n productRefinerValue: productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n\r\n // tslint:disable-next-line\r\n private _focusOnSliderThumb(sliderChangeNotification: any): void {\r\n if (sliderChangeNotification.id) {\r\n const element = document.getElementById(sliderChangeNotification.id);\r\n if (!!element) {\r\n setTimeout(\r\n () => {\r\n element.focus();\r\n }, 0);\r\n }\r\n }\r\n }\r\n\r\n private _handleRangeTooltipText(tooltip: number): string {\r\n return this._formatPrice(`${tooltip}`);\r\n }\r\n}","import * as React from 'react';\r\ninterface IErrorMessage {\r\n text?: string;\r\n}\r\n\r\nexport const ErrorMessage: React.FC<IErrorMessage> = ({ text }) => {\r\n return (\r\n <span className='ms-search-result-container__no-results-message'>\r\n <h5> {text} </h5>\r\n </span>\r\n );\r\n};","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport * as React from 'react';\r\n\r\nimport { Button, Collapse } from '@msdyn365-commerce-modules/utilities';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\r\nimport RefineItem from './refine-item';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { findMatchingRefinementCriterion, ProductRefinerTypeValue, ProductRefinerValueDataTypeValue } from './utilities';\r\n\r\n/**\r\n * Properties associated with the RefineSubmenu component\r\n */\r\nexport interface IRefineSubmenuProps {\r\n tempRangeTypeTODO: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n refinerExpandText?: string;\r\n refinerMinimizeText?: string;\r\n minimizedRefiners?: string;\r\n productRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinerValues: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n isExpandedOnInitialLoad: boolean;\r\n context: ICoreContext;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n highestLevelRefinerText?: string;\r\n onUpdateRefiners(notfication: Readonly<IRefineItemToggleNotification>): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine submenu state\r\n */\r\nexport interface IRefineSubmenuState extends React.ComponentState {\r\n expanded: boolean;\r\n}\r\n\r\n/**\r\n *\r\n * The RefineSubmenu component renders the submenu category and child items.\r\n * This computed observes the stateful category hierarchy object.\r\n * @extends {React.PureComponent<IRefineSubmenuProps>}\r\n */\r\nclass RefineSubmenu extends React.Component<IRefineSubmenuProps, IRefineSubmenuState> {\r\n\r\n private isMinimizedRefiner: boolean = false;\r\n\r\n constructor(props: IRefineSubmenuProps) {\r\n super(props);\r\n\r\n this._onToggleItem = this._onToggleItem.bind(this);\r\n this._onToggleSubmenu = this._onToggleSubmenu.bind(this);\r\n this._expandCategoryRefiner = this._expandCategoryRefiner.bind(this);\r\n\r\n let isExpanded = this.props.isExpandedOnInitialLoad;\r\n if (this.props.productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range) {\r\n isExpanded = true;\r\n }\r\n\r\n this.state = {\r\n expanded: isExpanded\r\n };\r\n\r\n if (this.props.minimizedRefiners) {\r\n const minimizedRefinersList = this.props.minimizedRefiners.split(',');\r\n this.isMinimizedRefiner = minimizedRefinersList.some(\r\n keyName => this.props.productRefinerHierarchy.KeyName && (keyName.toLowerCase() === this.props.productRefinerHierarchy.KeyName.toLocaleLowerCase())\r\n );\r\n }\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\r\n }\r\n\r\n const isRangeRefiner = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range);\r\n let key = '';\r\n if (isRangeRefiner) {\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(productRefinerHierarchy.Values[0], this.props.selectedRefinerValues);\r\n key = selectedRefinementCriterion ? `($${selectedRefinementCriterion.LeftValueBoundString && parseFloat(selectedRefinementCriterion.LeftValueBoundString).toFixed(2)} - $${selectedRefinementCriterion.RightValueBoundString && parseFloat(selectedRefinementCriterion.RightValueBoundString).toFixed(2)})` : '';\r\n }\r\n\r\n if (this.isMinimizedRefiner) {\r\n return (\r\n <div className='ms-refine-submenu list-group'>\r\n <div className='ms-refine-submenu__minimized-header'>{productRefinerHierarchy.KeyName} {key}</div>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className='ms-refine-submenu list-group'>\r\n <Button\r\n className={this.state.expanded ? 'ms-refine-submenu__toggle_expanded' : 'ms-refine-submenu__toggle_collapsed'}\r\n aria-label={productRefinerHierarchy.KeyName || 'refiner.Name'}\r\n onClick={this._onToggleSubmenu}\r\n aria-expanded={this.state.expanded}\r\n >\r\n {productRefinerHierarchy.KeyName} {key}\r\n </Button>\r\n <Collapse isOpen={this.state.expanded} timeout={350}>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n </Collapse>\r\n </div>\r\n );\r\n }\r\n\r\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n switch (productRefinerHierarchy.DataTypeValue) {\r\n case ProductRefinerValueDataTypeValue.Range:\r\n case ProductRefinerValueDataTypeValue.RangeInput:\r\n return this._renderRange(productRefinerHierarchy);\r\n default:\r\n return this._renderSingleMultiSelect(productRefinerHierarchy);\r\n }\r\n }\r\n\r\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context } = this.props;\r\n const isSingleSelect = productRefinerHierarchy.RefinerTypeValue === ProductRefinerTypeValue.Single;\r\n const role = isSingleSelect ? { role: 'radiogroup' } : undefined;\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n return (\r\n <RefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n key={index}\r\n context={context}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n );\r\n });\r\n if (this.isMinimizedRefiner) {\r\n return (\r\n <div className='ms-refine-submenu__list-min' id={`refine-submenu-minimize__${this.props.productRefinerHierarchy.RecordId}`}>\r\n <ul className='ms-refine-submenu__list' {...role} aria-label={productRefinerHierarchy.KeyName}>\r\n {listItems}\r\n </ul>\r\n <a\r\n onClick={this._expandCategoryRefiner}\r\n className='ms-refine-submenu__expand-button'\r\n role='button'\r\n id={`refine-submenu-minimize-button__${productRefinerHierarchy.RecordId}`}\r\n >\r\n {this.props.refinerExpandText}\r\n </a>\r\n </div>\r\n );\r\n }\r\n return (\r\n <ul className='ms-refine-submenu__list' {...role} aria-label={productRefinerHierarchy.KeyName}>\r\n {listItems}\r\n </ul>\r\n );\r\n }\r\n\r\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const { isDisabled, refineItemCommonProps, selectedRefinerValues, context, minValueSliderThumbAriaLabel, maxValueSliderThumbAriaLabel } = this.props;\r\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\r\n const refinerValuesList = this._getSortedValueList() || [];\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n // TODO BUGBUG 22424559 determine only from the DataTypeValue once live example is working (can test with the tempRangeTypeTODO derived from QSP until then)\r\n const rangeType = (productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.RangeInput || this.props.tempRangeTypeTODO === 'input') ?\r\n 'input' :\r\n 'slider';\r\n const key = selectedRefinementCriterion ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}` : `not-selected-${index}`;\r\n return (\r\n <li className={`${submenuClassNamePrefix}--range`} key={index}>\r\n <RangeRefineItem\r\n parentProductRefinerHierarchy={productRefinerHierarchy}\r\n productRefinerValue={child}\r\n selectedRefinementCriterion={selectedRefinementCriterion}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n rangeType={rangeType}\r\n key={key}\r\n context={context}\r\n minValueSliderThumbAriaLabel={minValueSliderThumbAriaLabel}\r\n maxValueSliderThumbAriaLabel={maxValueSliderThumbAriaLabel}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n />\r\n </li>\r\n );\r\n });\r\n return <ul className='ms-refine-submenu__list list-unstyled'>{listItems}</ul>;\r\n }\r\n\r\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\r\n this.props.onUpdateRefiners(itemToggleNotification);\r\n }\r\n\r\n private _onToggleSubmenu(): void {\r\n this.setState(prevState => ({\r\n expanded: !prevState.expanded\r\n }));\r\n }\r\n\r\n private _getSortedValueList(): ProductRefinerValue[] {\r\n const sortedList = this.props.productRefinerHierarchy.Values.sort((nextOption, curOption) => {\r\n const curOptionName =\r\n nextOption.LeftValueBoundString || nextOption.RightValueBoundString || '';\r\n const nextOptionName =\r\n curOption.LeftValueBoundString || curOption.RightValueBoundString || '';\r\n\r\n return curOptionName.localeCompare(nextOptionName);\r\n });\r\n\r\n const dividedList = {\r\n options: [] as ProductRefinerValue[],\r\n topLevel: [] as ProductRefinerValue[]\r\n };\r\n sortedList.forEach(option => {\r\n const optionName = option.LeftValueBoundString || option.RightValueBoundString || '';\r\n\r\n if (optionName === this.props.highestLevelRefinerText) {\r\n dividedList.topLevel.push(option);\r\n } else {\r\n dividedList.options.push(option);\r\n }\r\n });\r\n\r\n return [...dividedList.topLevel, ...dividedList.options];\r\n }\r\n\r\n private _expandCategoryRefiner(): void {\r\n const minimizedElement = document.getElementById(`refine-submenu-minimize__${this.props.productRefinerHierarchy.RecordId}`);\r\n const buttonElement = document.getElementById(`refine-submenu-minimize-button__${this.props.productRefinerHierarchy.RecordId}`);\r\n if (minimizedElement && buttonElement) {\r\n if (minimizedElement.className === 'ms-refine-submenu__list-min') {\r\n minimizedElement.className = 'ms-refine-submenu__list-full';\r\n buttonElement.textContent = this.props.refinerMinimizeText!;\r\n } else {\r\n minimizedElement.className = 'ms-refine-submenu__list-min';\r\n buttonElement.textContent = this.props.refinerExpandText!;\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default RefineSubmenu;"],"sourceRoot":""}