{"version":3,"sources":["webpack:///src/actions/submit-helpfulness-vote.ts?be08","webpack:///src/index.ts?c6ae","webpack:///src/actions/inputs/submit-user-review-input.ts?921c","webpack:///src/actions/inputs/get-product-reviews-input.ts?bfba","webpack:///src/modules/write-review/index.ts?2b94","webpack:///src/common/rnrInterface.ts?25e5","webpack:///src/modules/reviews-list/components/review-card.tsx?2d16","webpack:///src/modules/reviews-list/components/components.tsx?c96f","webpack:///src/modules/ratings-histogram/ratings-histogram.tsx?4c32","webpack:///src/modules/reviews-list/reviews-list.tsx?b5d0","webpack:///src/actions/ratings-reviews-state-data-action.ts?6daf","webpack:///src/common/index.ts?ee63","webpack:///src/actions/inputs/submit-helpfulness-vote-input.ts?cfb5","webpack:///src/actions/report-review-concern.ts?11eb","webpack:///src/actions/inputs/get-user-review-input.ts?f98a","webpack:///src/modules/reviews-list/components/report-review-modal.tsx?22a9","webpack:///src/common/review-modal.tsx?7ef9","webpack:///src/actions/get-product-reviews.ts?ca83","webpack:///src/modules/reviews-list/index.ts?51cb","webpack:///src/modules/write-review/components/components.tsx?ead4","webpack:///src/modules/write-review/write-review.tsx?dea3","webpack:///src/actions/get-user-review.ts?1a29","webpack:///src/actions/inputs/report-review-concern-input.ts?c9d1","webpack:///src/modules/ratings-histogram/component/components.tsx?2a0b","webpack:///src/modules/reviews-list/reviews-list.view.tsx?6dd9","webpack:///src/actions/index.ts?e12b","webpack:///src/modules/ratings-histogram/ratings-histogram.view.tsx?4481","webpack:///src/modules/ratings-histogram/index.ts?834d","webpack:///src/actions/submit-user-review.ts?d4c7","webpack:///src/modules/write-review/write-review.view.tsx?9069"],"names":["submitHelpfulnessVoteDataAction","id","action","async","input","ctx","reviewId","length","tenantId","locale","authToken","inputIsValid","Error","requestUrl","serviceEndpoint","requestBody","isHelpful","requestHeader","headers","Authorization","then","response","status","catch","error","trace","telemetry","exception","debug","SubmitUserReviewInput","productId","channelId","userReviewData","authorization","getCacheKey","getCacheObjectType","dataCacheType","this","GetProductReviewsInput","localeListFilter","orderBy","starFilters","skipItems","pageSize","pageToken","dataSources","TOGGLE_REVIEW_MODAL_BUTTON_ID","TOGGLE_EDIT_MODAL_BUTTON_CARD_ID","ReviewCard","props","cardProps","className","isUserReview","key","review","name","userName","rating","date","renderDate","submittedDateTime","reviewTitle","title","reviewText","ratingHelpfulLabel","undefined","resources","wasReviewHelpfulText","like","voteHelpfulButton","dislike","edit","editButton","report","reportToggle","responseName","userResponse","responderName","responseText","responseDate","cardBodyProps","responseProps","reviewProps","controlsProps","headerProps","readOnly","avgRating","ariaLabel","reviewRatingNarratorText","context","parentId","typeName","parentType","data","isVoted","i","votedReviews","approved","isVotedFor","isDisabled","label","yesButtonText","noButtonText","voteCount","helpfulPositive","helpfulNegative","user","request","onClick","updateReviewHelpfulness","isAuthenticated","href","signInUrl","tag","toggleWriteReviewModal","editReviewCardText","Intl","DateTimeFormat","month","day","year","format","Date","reportConcernText","reportedReviews","includes","reportedText","ref","reportedReviewId","returnRef","toggleReportReviewModal","innerRef","ReviewCount","currentPage","reviewsCount","reviewsShownOnEachPage","pageReviewCountText","_getReviewStartNumber","_getReviewEndNumber","PageControls","payLoad","telemetryContent","Next","nextAttribute","contentAction","etext","Previous","previousAttribute","_hasPreviousPage","_getPreviousPageData","_paginationAriaLabel","pageReviewAriaLabel","previousButtonText","_hasNextPage","_getNextPageData","nextButtonText","_getPagesCount","_getReviewsShown","Math","min","ceil","isNextPage","page","pageModifier","pageReviewCount","updateReviews","selectedSortByOption","selectedFilterByOption","RatingsHistogram","super","handleHeadingChange","event","config","heading","text","target","value","selectFilterBy","bind","ratingsSummary","result","ratingCount","totalRatingsCount","completeClass","viewProps","callbacks","moduleProps","histogramItems","averageRating","averageRatingAriaLabel","hideCount","averageNumber","summary","totalReviews","ratingsSummaryProps","editProps","onEdit","requestContext","histogramProps","renderView","stars","filterKey","actionContext","update","ReviewsList","sortByDropdownOptions","mostHelpfulSortOptionText","mostRecentSortOptionText","highestRatedSortOptionText","lowestRatedSortOptionText","filterByDropdownOptions","allRatinsFilterByOptionText","fiveStarFilterByOptionText","fourStarFilterByOptionText","threeStarFilterByOptionText","twoStarFilterByOptionText","oneStarFilterByOptionText","componentDidMount","reviewsList","pagingInfo","totalItems","items","setState","listOfReviews","state","isFilterApplied","ratingsReviewsState","filterKeyValue","Number","dropdownItemsCount","isNaN","filterByOption","find","option","selectedIndex","warning","_userReview","userReview","_reviewCard","_reviewCards","reviewList","reviewElements","isTakenDown","isPublished","push","_userReportModalToggle","reportingReviewId","_toggleReviewModal","_onReportModalOpen","updateReviewHelpfulnessVote","_userReviewModal","product","isOpen","isReviewModalOpen","userReviewRating","userReviewTitle","userReviewText","onModalToggle","onTitleChange","_onTitleChange","onTextChange","_onTextChange","onRatingChange","_onRatingChange","onReviewComplete","_onReviewComplete","renderContextId","_userReviewModalToggle","hasError","hasReviewError","reviewsListCallbacks","updateReviewTitle","updateReviewText","updateRating","isSuccess","_reportReviewModal","isReportModalOpen","reportedKey","_onReportModalClose","onRadioChange","_onRadioChange","reportReview","_reportReview","hasReportError","reported","currentTarget","getAttribute","_reportReviewCallback","getUserToken","_value","reportedReview","updateSortByDropdown","notification","selectedOption","updateFilterByDropdown","_updateVoteUi","alreadyExists","list","map","concat","token","onReviewSubmitted","isSuccessful","submitReview","toggleModal","toggleReportModal","showSpinner","telemetryPageName","friendlyName","reviewModal","reportReviewModal","filterByDropdown","labelText","filterByDropdownText","dropdownId","dropdownOptions","onSelectOption","controlledByParent","sortByDropdown","sortByDropdownText","reviewCount","refineReviewsProps","reviewsListProps","reviewCards","pageControls","noReviewsMessage","noReviewsWithFilterMessage","noReviewsWithSelectedFilterMessage","sortByOptions","filterByOptions","createRatingsReviewsStateInput","getGenericActionDataAction","SubmitHelpfulnessVoteInput","reportReviewConcernDataAction","concernCategory","GetUserReviewInput","reportConcernDropdownOptions","ReportReviewModal","SubmitReview","submitReviewAttribute","SuccessButton","successAttribute","Cancel","cancelAttribute","reportSpamText","offensiveContentText","profanityContentText","modal","toggle","applicationNode","returnFocusRef","modalHeader","modalFooter","modalBody","header","headerSubmitted","feedbackThankYouText","cancelButton","cancelReportReviewText","submitButton","reportReviewButtonText","succesfulButton","okReportReviewText","reportMessage","reportModalMessage","reportSubmittedMessage","radioButtons","radioPairs","color","errorMessageText","pairs","inputId","checked","type","onChange","htmlFor","ReviewModal","submitButtonAttribute","cancelButtonAttribute","modalHeaderNode","discardReviewButtonText","onSubmit","disabled","submitDisabled","submitReviewButtonText","ratingsInput","ratingLabel","ratingsLabel","titleInput","titleLabel","textInput","textLabel","privacyPolicyUrl","privacyPolicyLink","form","autoComplete","inputRow","editReviewModalTitle","writeReviewModalTitle","stripWhiteSpacesFromString","selectRatingAriaLabel","initialRating","selectRatingLabel","maxLength","app","reviewTitleMaxLength","reviewTitleLabel","reviewTextMaxLength","rows","reviewTextLabel","policyTextBlocks","privacyPolicyTextFormat","split","isSeparatorAtStart","startsWith","isSeparatorAtEnd","endsWith","PrivacyPolicy","privacyPolicyAttribute","privacyPolicyTitle","replace","RegExp","trim","onReviewSubmission","RecordId","toString","apiSettings","productName","Name","userEmail","emailAddress","firstName","getReviewInput","createInputForProductReviews","getReviewsForGivenProduct","filter","getReviewsForGivenProductDataAction","SignInMessage","SignInButton","SignIn","attributes","ModalToggle","WriteReview","PureComponent","writeReviewCallbacks","_modalToggleRef","createRef","userInfo","signInMessage","signInButton","signInLabel","signInAriaLabel","modalToggle","editReviewButtonText","reviewButtonLabel","_buildUserReviewModal","getUserReviewDataAction","errorMessage","ReportReviewConcernInput","HistogramItems","renderItem","star5Count","star4Count","star3Count","star2Count","star1Count","count","totalCount","percentage","formattedPercent","NumberFormat","style","barItemAriaLabel","starLabel","bar","max","buttonProps","AverageRatingNumber","TotalReviews","buildReviewCard","createReviewModal","createReportModal","histogramItem","item","submitReviewDataAction"],"mappings":"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","file":"static/js/6.bef18216889b2dd8.chunk.js","sourcesContent":["/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { createObservableDataAction, IAction, IActionContext, sendRequest } from '@msdyn365-commerce/core';\n\nimport { SubmitHelpfulnessVoteInput } from './inputs/submit-helpfulness-vote-input';\n\nasync function submitHelpfulnessVote(input: SubmitHelpfulnessVoteInput, ctx: IActionContext): Promise {\n if (!inputIsValid(input)) {\n throw new Error(\n `[SubmitHelpfulnessVote] Invalid input. ReviewId=${input.reviewId},tenantId=${input.tenantId}, locale= ${\n input.locale\n },`\n );\n }\n\n const requestUrl =\n `${input.serviceEndpoint}/v2.0/votes/review/${input.reviewId}` +\n `?tenantId=${input.tenantId}` +\n `&locale=${input.locale}`;\n\n const requestBody = {\n isHelpful: !!input.isHelpful\n };\n\n const requestHeader = {\n headers: {\n Authorization: `id_token ${input.authToken}`\n }\n };\n\n return sendRequest(requestUrl, 'post', requestBody, requestHeader)\n .then(response => {\n return response.status === 200 || response.status === 201;\n })\n .catch((error) => {\n ctx.trace('[SubmitHelpfulnessVote] Failed to vote on a review');\n ctx.telemetry.exception(error);\n ctx.telemetry.debug('[SubmitHelpfulnessVote] Failed to vote on a review');\n return false;\n });\n}\n\nfunction inputIsValid(input: SubmitHelpfulnessVoteInput): boolean {\n return (\n input &&\n input.reviewId.length > 0 &&\n input.tenantId.length > 0 &&\n input.locale.length > 0 &&\n input.authToken.length > 0\n );\n}\n\nexport const submitHelpfulnessVoteDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/ratings-reviews/submit-helpfulness-vote',\n action: >submitHelpfulnessVote\n});\n\nexport default submitHelpfulnessVoteDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport reportReviewConcern from './actions/report-review-concern';\nimport submitHelpfulnessVote from './actions/submit-helpfulness-vote';\n\nexport * from './actions';\nexport * from './common';\nexport * from './modules/ratings-histogram';\nexport * from './modules/reviews-list';\nexport * from './modules/write-review';\n\nexport {\n reportReviewConcern,\n submitHelpfulnessVote\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, IActionInput } from '@msdyn365-commerce/core';\n\nimport { IUserReviewData } from './submit-user-review-input-data';\n\n/**\n * SubmitUserReview Input Action.\n */\nexport class SubmitUserReviewInput implements IActionInput {\n /**\n * The Id representing the product to get the ratings for.\n */\n public productId?: string;\n\n /**\n * The ID representing the tenant.\n */\n public tenantId: string;\n\n /**\n * The calling organization's channel id.\n */\n public channelId: string;\n\n /**\n * The locale for which to get the ratings from.\n */\n public locale: string;\n\n /**\n * The user's review data.\n */\n public userReviewData: IUserReviewData;\n\n /**\n * The user's authorization token.\n */\n public authorization: string;\n\n /**\n * The ratings and reviews service endpoint.\n */\n public serviceEndpoint: string;\n\n constructor(\n productId: string | undefined,\n tenantId: string,\n channelId: string,\n locale: string,\n userReviewData: IUserReviewData,\n authorization: string,\n serviceEndpoint: string\n ) {\n this.productId = productId;\n this.tenantId = tenantId;\n this.channelId = channelId;\n this.locale = locale;\n this.userReviewData = userReviewData;\n this.authorization = authorization;\n this.serviceEndpoint = serviceEndpoint;\n }\n\n public getCacheKey = () => 'SubmitUserReview';\n\n public getCacheObjectType = () => 'SubmitUserReview';\n\n public dataCacheType = (): CacheType => 'none';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, IActionInput } from '@msdyn365-commerce/core';\n\nexport type OrderBy =\n | 'None'\n | 'MostRecent'\n | 'Oldest'\n | 'HighestRating'\n | 'LowestRating'\n | 'MostHelpful'\n | 'LeastHelpful'\n | 'MostAsked'\n | 'MostAnswered'\n | 'LeastConcerns'\n | 'MostConcerns'\n | 'ReviewerNameAsc'\n | 'ReviewerNameDesc';\n\n/**\n * ReviewsGetRatingsSummary Input Action.\n */\nexport class GetProductReviewsInput implements IActionInput {\n /**\n * The Id representing the product to get the reviews for.\n */\n public productId: string;\n\n /**\n * The ID representing the tenant.\n */\n public tenantId: string;\n\n /**\n * The market for which to get the reviews from.\n */\n public localeListFilter: string;\n\n /**\n * Number of reviews to be shown on each page.\n */\n public pageSize: number;\n\n /**\n * Order in which reviews to be shown.\n */\n public orderBy: string;\n\n /**\n * Need to set this value if reviews need to be filtered with specific star rating .\n */\n public starFilters?: string;\n\n /**\n * Need to set this value if we need to skip few reviews.\n */\n public skipItems: number;\n\n /**\n * The continuation token.\n */\n public pageToken: string | null;\n\n /**\n * Selects which data sources to use to retrieve data.\n */\n public dataSources: string | null;\n\n /**\n * The ratings and reviews service endpoint.\n */\n public serviceEndpoint: string;\n\n constructor(\n productId: string,\n tenantId: string,\n localeListFilter: string,\n serviceEndpoint: string,\n orderBy: string = 'MostHelpful',\n starFilters: string = '',\n skipItems: number = 0,\n pageSize: number = 10,\n pageToken: string | null = null,\n dataSources: string | null = null\n ) {\n this.productId = productId;\n this.tenantId = tenantId;\n this.localeListFilter = localeListFilter;\n\n // Max page size which Rnr API supports is 25.\n // Hence if config has page size more than 25, we'll default it to 25.\n this.pageSize = pageSize > 25 ? 25 : pageSize;\n this.orderBy = orderBy;\n this.starFilters = starFilters;\n this.skipItems = skipItems;\n this.pageToken = pageToken;\n this.dataSources = dataSources;\n this.serviceEndpoint = serviceEndpoint;\n }\n\n public getCacheKey = () => `${this.productId}-${this.tenantId}-${this.localeListFilter}-${this.pageSize}-${this.orderBy}-${this.starFilters}-${this.skipItems}`;\n\n public getCacheObjectType = () => 'ProductReview';\n\n public dataCacheType = (): CacheType => 'request';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport WriteReview from './write-review';\nimport WriteReviewView from './write-review.view';\n\nexport * from './write-review';\nexport * from './write-review.data';\nexport { IWriteReviewConfig, IWriteReviewProps, IWriteReviewResources } from './write-review.props.autogenerated';\nexport * from './write-review.view';\n\nexport {\n WriteReview,\n WriteReviewView\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { OrderBy } from '../actions/inputs/get-product-reviews-input';\n\nexport interface IRnrKeyValuePair {\n key: string;\n value: string;\n}\n\nexport interface IRnrOrderByKeyValuePair {\n key: OrderBy;\n value: string;\n}\n\nexport function setFocusOnElement(id: string): void {\n const element = document.getElementById(id);\n if (element) {\n element.focus();\n }\n}\n\nexport const TOGGLE_REVIEW_MODAL_BUTTON_ID: string = 'reviewproductid';\nexport const TOGGLE_EDIT_MODAL_BUTTON_ID: string = 'ms-write-review__edit';\nexport const TOGGLE_EDIT_MODAL_BUTTON_CARD_ID: string = 'ms-reviews-list__edit';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Review } from '@msdyn365-commerce/commerce-entities';\nimport { RatingComponent } from '@msdyn365-commerce/components';\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\nimport { Button, format, INodeProps } from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nimport { TOGGLE_EDIT_MODAL_BUTTON_CARD_ID } from '../../../common/rnrInterface';\n\nexport interface IReviewCardResources {\n wasReviewHelpfulText: string;\n yesButtonText: string;\n noButtonText: string;\n editReviewCardText: string;\n reportedText: string;\n reportConcernText: string;\n reviewRatingNarratorText: string;\n}\n\nexport interface IReviewCardProps {\n review: Review;\n resources: IReviewCardResources;\n context: ICoreContext>;\n isUserReview?: boolean;\n parentId: string;\n parentType: string;\n reportedReviews: string[];\n returnRef: React.RefObject | undefined;\n reportedReviewId: string;\n votedReviews: { reviewId: string; approved: boolean }[];\n toggleWriteReviewModal?(): void;\n toggleReportReviewModal(reviewId: string): void;\n updateReviewHelpfulness(reviewId: string, isHelpful: boolean): void;\n}\n\nexport interface IReviewCardViewProps {\n cardProps: INodeProps;\n name: React.ReactElement;\n rating: React.ReactElement;\n date: React.ReactElement;\n reviewTitle: React.ReactElement;\n reviewText: React.ReactElement;\n ratingHelpfulLabel?: React.ReactElement;\n like?: React.ReactElement;\n dislike?: React.ReactElement;\n edit: React.ReactNode;\n report: React.ReactNode;\n responseName: React.ReactNode;\n responseDate: React.ReactNode;\n responseText: React.ReactNode;\n cardBodyProps: INodeProps;\n responseProps: INodeProps;\n reviewProps: INodeProps;\n controlsProps: INodeProps;\n headerProps: INodeProps;\n}\n\n/**\n * Review card component.\n */\n\nexport const ReviewCard = (props: IReviewCardProps): IReviewCardViewProps => {\n const className = props.isUserReview ? 'ms-reviews-list__card ms-reviews-list__user-review' : 'ms-reviews-list__card';\n return {\n cardProps: { className, key: props.review.reviewId },\n name:

\n {props.review.userName}\n

,\n rating: rating(props),\n date:

\n {renderDate(props, props.review.submittedDateTime)}\n

,\n reviewTitle:

\n {props.review.title}\n

,\n reviewText:

\n {props.review.reviewText}\n

,\n ratingHelpfulLabel: props.isUserReview ? undefined :

\n {props.resources.wasReviewHelpfulText}\n

,\n like: props.isUserReview ? undefined : voteHelpfulButton(props, true),\n dislike: props.isUserReview ? undefined : voteHelpfulButton(props, false),\n edit: editButton(props),\n report: reportToggle(props),\n responseName: props.review.userResponse ?

\n {props.review.userResponse.responderName}\n

: undefined,\n responseText: props.review.userResponse ?

\n {props.review.userResponse.responseText}\n

: undefined,\n responseDate: props.review.userResponse ?

\n {renderDate(props, props.review.userResponse.submittedDateTime)}\n

: undefined,\n cardBodyProps: { className: 'ms-reviews-list__card-body' },\n responseProps: { className: 'ms-reviews-list__response' },\n reviewProps: { className: 'ms-reviews-list__review' },\n controlsProps: { className: 'ms-reviews-list__card-controls' },\n headerProps: { className: 'ms-reviews-list__card-header' }\n };\n};\n\nconst rating = (props: IReviewCardProps) => {\n return (\n \n );\n};\n\nconst isVotedFor = (props: IReviewCardProps, isHelpful: boolean): boolean => {\n for (let i = 0; i < props.votedReviews.length; i++) {\n if (props.votedReviews[i].reviewId === props.review.reviewId) {\n return props.votedReviews[i].approved === isHelpful;\n }\n }\n\n return false;\n};\n\nconst voteHelpfulButton = (props: IReviewCardProps, isHelpful: boolean) => {\n const isVoted = isVotedFor(props, isHelpful);\n const isDisabled = props.isUserReview || isVoted ? 'disabled' : '';\n let className = isHelpful ? 'ms-reviews-list__like' : 'ms-reviews-list__dislike';\n className = `${className} ${isDisabled}`;\n const label = isHelpful ? props.resources.yesButtonText : props.resources.noButtonText;\n let voteCount = (isHelpful ? props.review.helpfulPositive : props.review.helpfulNegative) || 0;\n voteCount = isVoted ? voteCount + 1 : voteCount;\n const title = `(${voteCount})`;\n const user = props.context.request.user;\n const onClickMethod = () => {\n props.updateReviewHelpfulness(props.review.reviewId!, isHelpful);\n };\n const onClick = isDisabled ? undefined : onClickMethod;\n\n if (user.isAuthenticated) {\n return (\n {title}\n );\n }\n return (\n {title}\n );\n};\n\nconst editButton = (props: IReviewCardProps) => {\n if (props.isUserReview) {\n return ();\n }\n\n return undefined;\n};\n\nconst renderDate = (props: IReviewCardProps, date?: Date): string | Date => {\n if (!date) {\n return '';\n }\n\n try {\n return new Intl.DateTimeFormat(props.context.request.locale, { month: 'long', day: 'numeric', year: 'numeric' }).format(new Date(date));\n } catch {\n return date;\n }\n};\n\nconst reportToggle = (props: IReviewCardProps) => {\n const user = props.context.request.user;\n if (props.isUserReview) {\n return undefined;\n } else if (!user.isAuthenticated) {\n return ();\n }\n\n if (props.reportedReviews.includes(props.review.reviewId!)) {\n return (

\n {props.resources.reportedText}\n

);\n }\n\n const ref = props.review.reviewId === props.reportedReviewId ? props.returnRef : undefined;\n const onClick = () => {\n props.toggleReportReviewModal(props.review.reviewId!);\n };\n return ();\n\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { format, getPayloadObject, getTelemetryAttributes, ILabeledDropdownOption, ITelemetryContent, TelemetryConstant } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nexport interface IReviewCountResources {\n pageReviewCountText: string;\n}\n\nexport interface IReviewCountProps {\n resources: IReviewCountResources;\n currentPage: number;\n reviewsCount: number;\n reviewsShownOnEachPage: number;\n}\n\nexport const ReviewCount: React.FC = (props: IReviewCountProps) => {\n const { currentPage, resources, reviewsCount, reviewsShownOnEachPage } = props;\n\n return (\n \n {format(\n resources.pageReviewCountText,\n _getReviewStartNumber(currentPage, reviewsShownOnEachPage),\n _getReviewEndNumber(currentPage, reviewsCount, reviewsShownOnEachPage),\n reviewsCount\n )}\n \n );\n};\n\nexport interface IPageControlResources {\n previousButtonText: string;\n nextButtonText: string;\n pageReviewAriaLabel: string;\n}\n\nexport interface IPageControlsProps {\n resources: IPageControlResources;\n currentPage: number;\n reviewsCount: number;\n reviewsShownOnEachPage: number;\n selectedSortByOption: ILabeledDropdownOption;\n selectedFilterByOption: ILabeledDropdownOption;\n telemetryContent?: ITelemetryContent;\n updateReviews(skipItems: number, selectedSortByOption: ILabeledDropdownOption, selectedFilterByOption: ILabeledDropdownOption, currentPage: number, isFilterApplied: boolean): Promise;\n}\n\nexport const PageControls: React.FC = (props: IPageControlsProps) => {\n const { currentPage, resources, reviewsCount, reviewsShownOnEachPage } = props;\n const previousPageClick = () => {\n return _getPreviousPageData(props);\n };\n const nextPageClick = () => {\n return _getNextPageData(props);\n };\n const payLoad = getPayloadObject('click', props.telemetryContent!, TelemetryConstant.Next);\n const nextAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n payLoad.contentAction.etext = TelemetryConstant.Previous;\n const previousAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n\n return (\n
\n {_hasPreviousPage(currentPage) && (\n \n {resources.previousButtonText}\n \n )}\n {_hasNextPage(currentPage, reviewsCount, reviewsShownOnEachPage) && (\n \n {resources.nextButtonText}\n \n )}\n
\n );\n};\n\nconst _hasPreviousPage = (currentPage: number): boolean => {\n return currentPage > 1;\n};\n\nconst _hasNextPage = (currentPage: number, reviewsCount: number, reviewsShownOnEachPage: number): boolean => {\n return _getPagesCount(reviewsCount, reviewsShownOnEachPage) > currentPage;\n};\n\nconst _getReviewsShown = (reviewsShownOnEachPage: number) => {\n return Math.min(25, reviewsShownOnEachPage);\n};\n\nconst _getPagesCount = (reviewsCount: number, reviewsShownOnEachPage: number): number => {\n return Math.ceil(reviewsCount / _getReviewsShown(reviewsShownOnEachPage));\n};\n\nconst _paginationAriaLabel = (pageReviewAriaLabel: string, currentPage: number, reviewsCount: number, reviewsShownOnEachPage: number, isNextPage: boolean, page?: number): string => {\n const pageModifier = isNextPage ? 1 : -1;\n return format(\n pageReviewAriaLabel,\n _getReviewStartNumber(currentPage, reviewsShownOnEachPage, currentPage + pageModifier),\n _getReviewEndNumber(currentPage, reviewsCount, reviewsShownOnEachPage, currentPage + pageModifier),\n reviewsCount\n );\n};\n\nconst _getReviewStartNumber = (currentPage: number, reviewsShownOnEachPage: number, page?: number): number => {\n return ((page || currentPage) - 1) * _getReviewsShown(reviewsShownOnEachPage) + 1;\n};\n\nconst _getReviewEndNumber = (currentPage: number, reviewsCount: number, reviewsShownOnEachPage: number, page?: number): number => {\n const pageUsed = page || currentPage;\n const pageReviewCount = pageUsed * _getReviewsShown(reviewsShownOnEachPage);\n return pageReviewCount < reviewsCount ? pageReviewCount : reviewsCount;\n};\n\nconst _getPreviousPageData = async (props: IPageControlsProps) => {\n await props.updateReviews(\n _getReviewStartNumber(props.currentPage, props.reviewsShownOnEachPage) - 1 - _getReviewsShown(props.reviewsShownOnEachPage),\n props.selectedSortByOption,\n props.selectedFilterByOption,\n props.currentPage - 1,\n false\n );\n};\n\nconst _getNextPageData = async (props: IPageControlsProps) => {\n\n await props.updateReviews(\n _getReviewEndNumber(props.currentPage, props.reviewsCount, props.reviewsShownOnEachPage),\n props.selectedSortByOption,\n props.selectedFilterByOption,\n props.currentPage + 1,\n false\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { RatingComponent } from '@msdyn365-commerce/components';\nimport * as Msdyn365 from '@msdyn365-commerce/core';\nimport { format, IModuleProps, INodeProps } from '@msdyn365-commerce-modules/utilities';\nimport classname from 'classnames';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { createRatingsReviewsStateInput } from '../../actions/ratings-reviews-state-data-action';\nimport { AverageRatingNumber, HistogramItems, IHistogramItemViewProps, TotalReviews } from './component/components';\nimport { IRatingsHistogramData } from './ratings-histogram.data';\nimport { IRatingsHistogramProps } from './ratings-histogram.props.autogenerated';\n\nexport interface IRatingsHistogramViewProps extends IRatingsHistogramProps {\n className: string;\n histogramItems: IHistogramItemViewProps[];\n moduleProps: IModuleProps;\n heading: React.ReactNode;\n averageRating: React.ReactNode;\n averageNumber: React.ReactNode;\n totalReviews: React.ReactNode;\n histogramProps: INodeProps;\n ratingsSummaryProps: INodeProps;\n callbacks: IRatingsHistogramCallbacks;\n}\n\nexport interface IRatingsHistogramCallbacks {\n selectFilterBy(stars: number): void;\n}\n\n/**\n * RatingsHistogram component.\n * @extends {React.Component>}\n */\n@observer\nclass RatingsHistogram extends React.Component> {\n\n constructor(props: IRatingsHistogramProps) {\n super(props);\n this.selectFilterBy = this.selectFilterBy.bind(this);\n }\n\n public render(): JSX.Element | null {\n const { resources } = this.props;\n const { className, heading } = this.props.config;\n const { ratingsSummary: { result: ratingsSummary } } = this.props.data;\n const ratingCount = ratingsSummary && ratingsSummary.totalRatingsCount ? `${ratingsSummary.totalRatingsCount}` : '0';\n\n const completeClass = classname('ms-ratings-histogram', className);\n const viewProps: IRatingsHistogramViewProps = {\n ...this.props,\n className: completeClass,\n callbacks: {\n selectFilterBy: this.selectFilterBy\n },\n moduleProps: {\n moduleProps: this.props,\n className: completeClass\n },\n histogramItems: ratingsSummary ? HistogramItems({ ratingsSummary, resources: { ...resources }, locale: this.props.context.request.locale, onClick: this.selectFilterBy }) : [],\n averageRating: ratingsSummary && (\n \n ),\n averageNumber: ratingsSummary && ,\n totalReviews: ratingsSummary && ,\n ratingsSummaryProps: { className: 'ms-ratings-histogram__summary' },\n heading: heading && (\n \n ),\n histogramProps: { className: 'ms-ratings-histogram__histogram' }\n };\n\n return this.props.renderView(viewProps) as React.ReactElement;\n }\n\n public handleHeadingChange = (event: Msdyn365.ContentEditableEvent) => this.props.config.heading!.text = event.target.value;\n\n public selectFilterBy(stars: number): void {\n const filterKey = `${stars}`;\n this.props.context.actionContext.update(createRatingsReviewsStateInput({ filterKey }), { filterKey });\n }\n}\n\nexport default RatingsHistogram;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Review } from '@msdyn365-commerce/commerce-entities';\nimport { RatingComponent } from '@msdyn365-commerce/components';\nimport * as Msdyn365 from '@msdyn365-commerce/core';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\nimport { getRnrAuthEndpointId, getRnrEndpointId, getRnrPartnerId, getSelectedProductIdFromActionInput } from '@msdyn365-commerce-modules/retail-actions';\nimport { format, getTelemetryObject, ILabeledDropdownOnChangeNotification, ILabeledDropdownOption, IModuleProps, INodeProps, ITelemetryContent, LabeledDropdown } from '@msdyn365-commerce-modules/utilities';\nimport classname from 'classnames';\nimport { reaction } from 'mobx';\nimport { observer } from 'mobx-react';\nimport * as React from 'react';\n\nimport { reportReviewConcern, submitHelpfulnessVote } from '../..';\nimport { getReviewsForGivenProduct } from '../../actions/get-product-reviews';\nimport { GetProductReviewsInput } from '../../actions/inputs/get-product-reviews-input';\nimport { ReportReviewConcernInput, ReviewConcernCategory } from '../../actions/inputs/report-review-concern-input';\nimport { SubmitHelpfulnessVoteInput } from '../../actions/inputs/submit-helpfulness-vote-input';\nimport { IReviewModalViewProps, ReviewModal, submitReview } from '../../common/review-modal';\nimport { IRnrKeyValuePair, IRnrOrderByKeyValuePair } from '../../common/rnrInterface';\nimport { PageControls, ReviewCount } from './components/components';\nimport { IReportReviewModalViewProps, ReportReviewModal } from './components/report-review-modal';\nimport { IReviewCardViewProps, ReviewCard } from './components/review-card';\nimport { IReviewsListData } from './reviews-list.data';\nimport { IReviewsListProps } from './reviews-list.props.autogenerated';\n\nexport interface IReviewsListState {\n skipItems: number;\n listOfReviews: Review[];\n currentPage: number;\n reviewsCount: number;\n showSpinner: boolean;\n isFilterApplied: boolean;\n selectedSortByOption: ILabeledDropdownOption;\n selectedFilterByOption: ILabeledDropdownOption;\n userReviewRating: number;\n userReviewTitle: string;\n userReviewText: string;\n isReviewModalOpen: boolean;\n hasReviewError: boolean;\n isReportModalOpen: boolean;\n hasReportError: boolean;\n reportingReviewId: string;\n reportedKey: string;\n reported: boolean;\n reportedReviews: string[];\n votedReviews: { reviewId: string; approved: boolean }[];\n}\n\nexport interface IReviewsListCallbacks {\n toggleModal(): void;\n updateReviewTitle(title: string): void;\n updateReviewText(text: string): void;\n updateRating(rating: number): void;\n onReviewSubmitted(isSuccessful: boolean): void;\n submitReview(product: SimpleProduct, title: string, text: string, rating: number, context: Msdyn365.ICoreContext, userReview?: Review, onReviewSubmission?: (isSuccessful: boolean) => void): void;\n updateReviewHelpfulnessVote(reviewId: string, isHelpful: boolean): void;\n toggleReportModal(reviewId: string): void;\n reportReview(reviewId: string, reportedKey: string): void;\n updateSortByDropdown(notification: ILabeledDropdownOnChangeNotification): void;\n updateFilterByDropdown(notification: ILabeledDropdownOnChangeNotification): void;\n updateReviews(skipItems: number, selectedSortByOption: ILabeledDropdownOption, selectedFilterByOption: ILabeledDropdownOption, currentPage: number, isFilterApplied: boolean): void;\n}\n\nexport interface IReviewsListViewProps extends IReviewsListProps {\n state: IReviewsListState;\n className: string;\n callbacks: IReviewsListCallbacks;\n moduleProps: IModuleProps;\n reviewModal: IReviewModalViewProps;\n reportReviewModal: IReportReviewModalViewProps;\n sortByDropdown: React.ReactNode;\n filterByDropdown: React.ReactNode;\n averageRating: React.ReactNode;\n reviewCount: React.ReactElement;\n refineReviewsProps: INodeProps;\n reviewsListProps: INodeProps;\n reviewCards: IReviewCardViewProps[];\n userReview?: IReviewCardViewProps;\n pageControls: React.ReactNode;\n noReviewsMessage: React.ReactElement;\n noReviewsWithFilterMessage: React.ReactElement;\n heading: React.ReactNode;\n sortByOptions: IRnrOrderByKeyValuePair[];\n filterByOptions: IRnrOrderByKeyValuePair[];\n}\n\n/**\n *\n * ReviewsList component.\n * @extends {React.Component, IReviewsListState>}\n */\n@observer\nclass ReviewsList extends React.Component, IReviewsListState> {\n public sortByDropdownOptions: IRnrOrderByKeyValuePair[] = [\n { key: 'MostHelpful', value: this.props.resources.mostHelpfulSortOptionText },\n { key: 'MostRecent', value: this.props.resources.mostRecentSortOptionText },\n { key: 'HighestRating', value: this.props.resources.highestRatedSortOptionText },\n { key: 'LowestRating', value: this.props.resources.lowestRatedSortOptionText }\n ];\n\n public filterByDropdownOptions: IRnrKeyValuePair[] = [\n { key: '1;2;3;4;5', value: this.props.resources.allRatinsFilterByOptionText },\n { key: '5', value: this.props.resources.fiveStarFilterByOptionText },\n { key: '4', value: this.props.resources.fourStarFilterByOptionText },\n { key: '3', value: this.props.resources.threeStarFilterByOptionText },\n { key: '2', value: this.props.resources.twoStarFilterByOptionText },\n { key: '1', value: this.props.resources.oneStarFilterByOptionText }\n ];\n\n private readonly _userReviewModalToggle: React.RefObject;\n\n private readonly _userReportModalToggle: React.RefObject;\n\n private readonly telemetryContent?: ITelemetryContent;\n\n constructor(props: IReviewsListProps) {\n super(props);\n const { userReview: { result: userReview } } = this.props.data;\n\n this.state = {\n skipItems: 0,\n reviewsCount: 0,\n listOfReviews: [],\n currentPage: 1,\n showSpinner: false,\n isFilterApplied: false,\n selectedSortByOption: this.sortByDropdownOptions[0],\n selectedFilterByOption: this.filterByDropdownOptions[0],\n userReviewRating: userReview ? userReview.rating : 0,\n userReviewText: userReview ? userReview.reviewText : '',\n userReviewTitle: userReview ? userReview.title : '',\n isReviewModalOpen: false,\n hasReviewError: false,\n isReportModalOpen: false,\n hasReportError: false,\n reported: false,\n reportedKey: ReviewConcernCategory.SpamAdvertising,\n reportingReviewId: '',\n reportedReviews: [],\n votedReviews: []\n };\n\n this._userReviewModalToggle = React.createRef();\n this._userReportModalToggle = React.createRef();\n this.telemetryContent = getTelemetryObject(this.props.context.request.telemetryPageName!, this.props.friendlyName, this.props.telemetry);\n }\n\n public componentDidMount = async () => {\n this.props.data.reviewsList.then((reviewsList) => {\n if (\n reviewsList &&\n reviewsList.pagingInfo &&\n reviewsList.pagingInfo.totalItems &&\n reviewsList.items &&\n reviewsList.items.length > 0\n ) {\n this.setState({\n listOfReviews: reviewsList.items,\n reviewsCount: reviewsList.pagingInfo.totalItems\n });\n }\n });\n await this.updateReviews(0, this.state.selectedSortByOption, this.state.selectedFilterByOption, 1, this.state.isFilterApplied);\n\n reaction(\n () => this.props.data.ratingsReviewsState.result && this.props.data.ratingsReviewsState.result.filterKey,\n async (filterKey: string | undefined) => {\n const filterKeyValue = Number(filterKey);\n const dropdownItemsCount = this.filterByDropdownOptions.length;\n if (\n filterKey &&\n !isNaN(filterKeyValue) &&\n filterKeyValue < dropdownItemsCount\n ) {\n const filterByOption = this.filterByDropdownOptions.find((option: IRnrKeyValuePair) => option.key === filterKey);\n if (!filterByOption) {\n this.props.telemetry.warning(`[reviews-list] cannot find filter with key ${filterKey}`);\n } else {\n await this.updateReviews(0, this.state.selectedSortByOption, filterByOption, 1, true);\n const selectedIndex = dropdownItemsCount - filterKeyValue;\n this.setState({\n selectedFilterByOption: this.filterByDropdownOptions[selectedIndex]\n });\n }\n }\n }\n );\n };\n\n public render(): JSX.Element | null {\n const { className, heading, reviewsShownOnEachPage } = this.props.config;\n const { currentPage, reviewsCount, selectedFilterByOption, selectedSortByOption } = this.state;\n const { ratingsSummary: { result: ratingsSummary } } = this.props.data;\n const resources = this.props.resources;\n const completeClass = classname('ms-reviews-list', className);\n const viewProps: IReviewsListViewProps = {\n ...this.props,\n state: this.state,\n className: completeClass,\n moduleProps: {\n moduleProps: this.props,\n className: completeClass\n },\n callbacks: this.reviewsListCallbacks,\n reviewModal: this._userReviewModal(),\n reportReviewModal: this._reportReviewModal(),\n filterByDropdown: (\n \n ),\n sortByDropdown: ,\n averageRating: ratingsSummary && (\n \n ),\n reviewCount: ,\n refineReviewsProps: { className: 'ms-reviews-list__refiners' },\n reviewsListProps: { className: 'ms-reviews-list__reviews' },\n reviewCards: this._reviewCards(this.state.listOfReviews),\n userReview: this._userReview(),\n pageControls: (\n ),\n noReviewsMessage: \n {resources.noReviewsMessage}\n ,\n noReviewsWithFilterMessage: \n {resources.noReviewsWithSelectedFilterMessage}\n ,\n heading: heading && heading.text && (\n \n ),\n sortByOptions: this.sortByDropdownOptions,\n filterByOptions: this.filterByDropdownOptions\n } as IReviewsListViewProps;\n\n return this.props.renderView(viewProps) as React.ReactElement;\n }\n\n public handleHeadingChange = (event: Msdyn365.ContentEditableEvent) => this.props.config.heading!.text = event.target.value;\n\n private readonly _userReview = () => {\n const userReview = this.props.data.userReview.result;\n\n return userReview && this._reviewCard(userReview, true);\n };\n\n private readonly _reviewCards = (reviewList: Review[]) => {\n const userReview = this.props.data.userReview.result;\n const reviewElements: IReviewCardViewProps[] = [];\n\n for (const review of reviewList) {\n if (!review.isTakenDown && review.isPublished && userReview ? review.reviewId !== userReview.reviewId : true) {\n reviewElements.push(this._reviewCard(review, false));\n }\n }\n return reviewElements;\n };\n\n private readonly _reviewCard = (review: Review, userReview: boolean): IReviewCardViewProps => {\n return ReviewCard({\n review,\n resources: { ...this.props.resources },\n context: this.props.context,\n isUserReview: userReview,\n parentId: this.props.id,\n parentType: this.props.typeName,\n reportedReviews: this.state.reportedReviews,\n returnRef: this._userReportModalToggle,\n reportedReviewId: this.state.reportingReviewId,\n toggleWriteReviewModal: this._toggleReviewModal,\n toggleReportReviewModal: this._onReportModalOpen,\n updateReviewHelpfulness: this.updateReviewHelpfulnessVote,\n votedReviews: this.state.votedReviews\n });\n };\n\n private readonly _userReviewModal = (): IReviewModalViewProps => {\n return ReviewModal({\n userReview: this.props.data.userReview.result,\n product: this.props.data.product.result,\n resources: { ...this.props.resources },\n context: this.props.context,\n parentId: this.props.id,\n parentType: this.props.typeName,\n isOpen: this.state.isReviewModalOpen,\n rating: this.state.userReviewRating,\n reviewTitle: this.state.userReviewTitle,\n reviewText: this.state.userReviewText,\n onModalToggle: this._toggleReviewModal,\n onTitleChange: this._onTitleChange,\n onTextChange: this._onTextChange,\n onRatingChange: this._onRatingChange,\n onReviewComplete: this._onReviewComplete,\n renderContextId: 'writeReview-list',\n returnRef: this._userReviewModalToggle,\n hasError: this.state.hasReviewError\n });\n };\n\n private readonly _onTitleChange = (event: React.ChangeEvent): void => {\n this.reviewsListCallbacks.updateReviewTitle(event.target.value);\n };\n\n private readonly _onTextChange = (event: React.ChangeEvent): void => {\n this.reviewsListCallbacks.updateReviewText(event.target.value);\n };\n\n private readonly _onRatingChange = (value: number): void => {\n this.reviewsListCallbacks.updateRating(value);\n };\n\n private readonly _toggleReviewModal = (): void => {\n const userReview = this.props.data.userReview.result;\n if (this.state.isReviewModalOpen) {\n this.setState({ isReviewModalOpen: false, hasReviewError: false });\n\n } else {\n this.setState({\n isReviewModalOpen: true,\n userReviewText: userReview!.reviewText,\n userReviewTitle: userReview!.title,\n userReviewRating: userReview!.rating\n });\n }\n };\n\n private readonly _onReviewComplete = (isSuccess: boolean): void => {\n if (isSuccess) {\n this.setState({ isReviewModalOpen: false, hasReviewError: false });\n } else {\n this.setState({ hasReviewError: true });\n }\n };\n\n private readonly _reportReviewModal = () => {\n return ReportReviewModal({\n resources: { ...this.props.resources },\n context: this.props.context,\n isOpen: this.state.isReportModalOpen,\n returnRef: this._userReportModalToggle,\n reportedKey: this.state.reportedKey,\n onModalToggle: this._onReportModalClose,\n onRadioChange: this._onRadioChange,\n reportReview: this._reportReview,\n hasError: this.state.hasReportError,\n telemetryContent: this.telemetryContent\n });\n };\n\n private readonly _onReportModalOpen = (reviewId: string) => {\n this.setState({ isReportModalOpen: true, reportingReviewId: reviewId, reported: false, reportedKey: ReviewConcernCategory.SpamAdvertising });\n };\n\n private readonly _onReportModalClose = () => {\n this.setState({ isReportModalOpen: false, hasReportError: false });\n };\n\n private readonly _onRadioChange = (event: React.ChangeEvent) => {\n this.setState({ reportedKey: event.currentTarget.getAttribute('data-key') || '' });\n };\n\n private readonly _reportReviewCallback = (reviewId: string, reportedKey: string) => {\n reportReviewConcern(\n new ReportReviewConcernInput(\n reviewId,\n getRnrPartnerId(this.props.context.actionContext),\n this.props.context.request.locale,\n reportedKey,\n this.getUserToken(this.props.context.request),\n getRnrAuthEndpointId(this.props.context.actionContext)\n ),\n this.props.context.actionContext\n ).then((_value: boolean) => {\n const reportedReview = this.state.reportedReviews;\n reportedReview.push(reviewId);\n this.setState({ reported: true, reportedReviews: reportedReview, hasReportError: false });\n }).catch((error: boolean) => {\n this.setState({ hasReportError: true });\n });\n };\n\n private readonly _reportReview = () => {\n this._reportReviewCallback(this.state.reportingReviewId, this.state.reportedKey);\n };\n\n private readonly updateSortByDropdown = async (notification: ILabeledDropdownOnChangeNotification) => {\n await this.updateReviews(0, notification.selectedOption, this.state.selectedFilterByOption, 1, this.state.isFilterApplied);\n };\n\n private readonly updateFilterByDropdown = async (notification: ILabeledDropdownOnChangeNotification) => {\n await this.updateReviews(0, this.state.selectedSortByOption, notification.selectedOption, 1, true);\n };\n\n private readonly updateReviews = async (\n skipItems: number | 0,\n selectedSortByOption: ILabeledDropdownOption,\n selectedFilterByOption: ILabeledDropdownOption,\n currentPage: number,\n isFilterApplied: boolean\n ) => {\n const productId = getSelectedProductIdFromActionInput(this.props.context.actionContext);\n if (productId === undefined) {\n return;\n }\n const result = await getReviewsForGivenProduct(\n\n // Task #211227597 Remove this hardcoded values.\n new GetProductReviewsInput(\n productId,\n getRnrPartnerId(this.props.context.actionContext),\n this.props.context.request.locale,\n getRnrEndpointId(this.props.context.actionContext),\n selectedSortByOption.key,\n selectedFilterByOption.key,\n skipItems < 0 ? 0 : skipItems,\n this.props.config.reviewsShownOnEachPage\n ),\n this.props.context.actionContext\n );\n if (result && result.items && result.pagingInfo && result.pagingInfo.totalItems !== undefined) {\n this.setState({\n currentPage,\n listOfReviews: result.items,\n selectedSortByOption,\n selectedFilterByOption,\n reviewsCount: result.pagingInfo.totalItems,\n isFilterApplied\n });\n }\n };\n\n private readonly _updateVoteUi = (reviewId: string, isHelpful: boolean): void => {\n let alreadyExists = false;\n let list = this.state.votedReviews.map((review) => {\n if (review.reviewId === reviewId) {\n review.approved = isHelpful;\n alreadyExists = true;\n }\n return review;\n });\n\n if (!alreadyExists) {\n list = list.concat({ reviewId, approved: isHelpful });\n }\n\n this.setState({ votedReviews: list });\n };\n\n private readonly updateReviewHelpfulnessVote = (reviewId: string, isHelpful: boolean): void => {\n submitHelpfulnessVote(\n new SubmitHelpfulnessVoteInput(\n reviewId,\n getRnrPartnerId(this.props.context.actionContext),\n this.props.context.request.locale,\n isHelpful,\n this.getUserToken(this.props.context.request),\n getRnrAuthEndpointId(this.props.context.actionContext)\n ),\n this.props.context.actionContext\n ).then(() => {\n this._updateVoteUi(reviewId, isHelpful);\n }).catch((error: Error) => {\n throw new Error('[submitHelpfulnessVote]Error executing action');\n });\n };\n\n private readonly getUserToken = (context: Msdyn365.IRequestContext): string => {\n return context && context.user && context.user.token;\n };\n\n private readonly reviewsListCallbacks: IReviewsListCallbacks = {\n updateReviewTitle: (title: string): void => {\n this.setState({ userReviewTitle: title });\n },\n updateReviewText: (text: string): void => {\n this.setState({ userReviewText: text });\n },\n updateRating: (rating: number): void => {\n this.setState({ userReviewRating: rating });\n },\n onReviewSubmitted: (isSuccessful: boolean): void => {\n if (isSuccessful) {\n this.setState({ isReviewModalOpen: false, hasReviewError: false });\n } else {\n this.setState({ hasReviewError: true });\n }\n },\n submitReview,\n toggleModal: this._toggleReviewModal,\n updateReviewHelpfulnessVote: this.updateReviewHelpfulnessVote,\n toggleReportModal: (reviewId: string): void => {\n this.state.isReportModalOpen ? this._onReportModalOpen(reviewId) : this._onReportModalClose();\n },\n reportReview: this._reportReviewCallback,\n updateFilterByDropdown: this.updateFilterByDropdown,\n updateSortByDropdown: this.updateSortByDropdown,\n updateReviews: this.updateReviews\n };\n}\n\nexport default ReviewsList;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { createObservableDataAction, IAction, IActionInput } from '@msdyn365-commerce/core';\nimport { GenericInput, getGenericAction } from '@msdyn365-commerce-modules/retail-actions';\n\nexport interface IRatingsReviewsState {\n filterKey: string;\n}\n\nexport function createRatingsReviewsStateInput(result: IRatingsReviewsState): GenericInput {\n return new GenericInput('ratingsReviewsState', result, 'ratingsReviewsStateInput');\n}\n\nconst createInternalRatingsReviewsStateInput = (): IActionInput => {\n return createRatingsReviewsStateInput({ filterKey: '1;2;3;4;5' });\n};\n\nexport const getGenericActionDataAction = createObservableDataAction({\n action: >getGenericAction,\n input: createInternalRatingsReviewsStateInput\n});\n\nexport default getGenericActionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './review-modal';\nexport * from './rnrInterface';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, IActionInput } from '@msdyn365-commerce/core';\n\n/**\n * SubmitHelpfulnessVote Input Action.\n */\nexport class SubmitHelpfulnessVoteInput implements IActionInput {\n public reviewId: string;\n\n public tenantId: string;\n\n public locale: string;\n\n public serviceEndpoint: string;\n\n public isHelpful: boolean;\n\n public authToken: string;\n\n constructor(\n reviewId: string,\n tenantId: string,\n locale: string,\n isHelpful: boolean,\n authToken: string,\n serviceEndpoint: string\n ) {\n this.reviewId = reviewId;\n this.tenantId = tenantId;\n this.locale = locale;\n this.isHelpful = isHelpful;\n this.authToken = authToken;\n this.serviceEndpoint = serviceEndpoint;\n }\n\n public getCacheKey = () => 'SubmitHelpfulnessVote';\n\n public getCacheObjectType = () => 'SubmitHelpfulnessVote';\n\n public dataCacheType = (): CacheType => 'none';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { createObservableDataAction, IAction, IActionContext, sendRequest } from '@msdyn365-commerce/core';\n\nimport { ReportReviewConcernInput } from './inputs/report-review-concern-input';\n\nasync function reportReviewConcern(input: ReportReviewConcernInput, ctx: IActionContext): Promise {\n if (!inputIsValid(input)) {\n throw new Error(\n `[SubmitHelpfulnessVote] Invalid input. ReviewId=${input.reviewId},tenantId=${input.tenantId},locale= ${\n input.locale\n },`\n );\n }\n\n const requestUrl =\n `${input.serviceEndpoint}/v2.0/concerns/review/${input.reviewId}` +\n `?tenantId=${input.tenantId}` +\n `&locale=${input.locale}`;\n\n const requestBody = {\n concernCategory: input.concernCategory\n };\n\n const requestHeader = {\n headers: {\n Authorization: `id_token ${input.authToken}`\n }\n };\n\n return sendRequest(requestUrl, 'post', requestBody, requestHeader)\n .then(response => {\n return response.status === 200 || response.status === 201;\n })\n .catch((error) => {\n ctx.trace('[ReportReviewConcernInput] Failed to report a concern');\n ctx.telemetry.exception(error);\n ctx.telemetry.debug('[ReportReviewConcernInput] Failed to report a concern');\n return false;\n });\n}\n\nfunction inputIsValid(input: ReportReviewConcernInput): boolean {\n return (\n input &&\n input.reviewId.length > 0 &&\n input.tenantId.length > 0 &&\n input.locale.length > 0 &&\n input.authToken.length > 0\n );\n}\n\nexport const reportReviewConcernDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/ratings-reviews/report-review-concern',\n action: >reportReviewConcern\n});\n\nexport default reportReviewConcernDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, IActionInput } from '@msdyn365-commerce/core';\n\n/**\n * These are the get user review API inputs.\n */\nexport class GetUserReviewInput implements IActionInput {\n /**\n * The Id representing the product to get the ratings for.\n */\n public productId: string;\n\n /**\n * The ID representing the tenant.\n */\n public tenantId: string;\n\n /**\n * The user's authorization token.\n */\n public authorization: string;\n\n /**\n * The ratings and reviews service endpoint.\n */\n public serviceEndpoint: string;\n\n constructor(\n productId: string,\n tenantId: string,\n authorization: string,\n serviceEndpoint: string\n ) {\n this.productId = productId;\n this.tenantId = tenantId;\n this.authorization = authorization;\n this.serviceEndpoint = serviceEndpoint;\n }\n\n public getCacheKey = () => 'GetUserReview';\n\n public getCacheObjectType = () => 'GetUserReview';\n\n public dataCacheType = (): CacheType => 'none';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\nimport { Alert, getPayloadObject, getTelemetryAttributes, INodeProps, ITelemetryContent, Modal, ModalBody, ModalFooter, ModalHeader, TelemetryConstant } from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nimport { ReviewConcernCategory } from '../../../actions/inputs/report-review-concern-input';\nimport { IRnrKeyValuePair } from '../../../common/rnrInterface';\n\nexport interface IReportReviewModalProps {\n resources: IReportReviewModalResources;\n context: ICoreContext>;\n isOpen: boolean;\n returnRef: React.RefObject | undefined;\n reportedKey: string;\n hasError: boolean;\n telemetryContent?: ITelemetryContent;\n onModalToggle(): void;\n onRadioChange(event: React.ChangeEvent): void;\n reportReview(): void;\n}\n\nexport interface IReportReviewModalResources {\n reportConcernText: string;\n feedbackThankYouText: string;\n reportModalMessage: string;\n reportSubmittedMessage: string;\n reportSpamText: string;\n offensiveContentText: string;\n profanityContentText: string;\n okReportReviewText: string;\n cancelReportReviewText: string;\n reportReviewButtonText: string;\n errorMessageText: string;\n}\n\nexport interface IReportReviewModalViewProps {\n modal: INodeProps;\n modalHeader: INodeProps;\n modalFooter: INodeProps;\n modalBody: INodeProps;\n header: React.ReactElement;\n headerSubmitted: React.ReactElement;\n cancelButton: React.ReactElement;\n submitButton: React.ReactElement;\n succesfulButton: React.ReactElement;\n reportMessage: React.ReactElement;\n reportSubmittedMessage: React.ReactElement;\n radioButtons: React.ReactElement;\n error: React.ReactElement;\n}\n\nlet reportConcernDropdownOptions: IRnrKeyValuePair[];\n\n/**\n * CartLineItems component.\n */\n\nexport const ReportReviewModal = (props: IReportReviewModalProps): IReportReviewModalViewProps => {\n\n const payLoad = getPayloadObject('click', props.telemetryContent!, TelemetryConstant.SubmitReview);\n const submitReviewAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n payLoad.contentAction.etext = TelemetryConstant.SuccessButton;\n const successAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n payLoad.contentAction.etext = TelemetryConstant.Cancel;\n const cancelAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n\n reportConcernDropdownOptions = [\n { key: ReviewConcernCategory.SpamAdvertising, value: props.resources.reportSpamText },\n { key: ReviewConcernCategory.OffensiveContent, value: props.resources.offensiveContentText },\n { key: ReviewConcernCategory.Profanity, value: props.resources.profanityContentText }\n ];\n\n return {\n modal: { tag: Modal, className: 'ms-report-review-modal msc-modal-input-required', toggle: props.onModalToggle, applicationNode: 'renderPage', isOpen: props.isOpen, returnFocusRef: props.returnRef },\n modalHeader: { tag: ModalHeader, toggle: props.onModalToggle, className: 'ms-report-review-modal-header' },\n modalFooter: { tag: ModalFooter, className: 'ms-report-review-modal-footer' },\n modalBody: { tag: ModalBody, className: 'ms-report-review-modal-body' },\n header:

\n {props.resources.reportConcernText}\n

,\n headerSubmitted:

\n {props.resources.feedbackThankYouText}\n

,\n cancelButton: ,\n submitButton: ,\n succesfulButton: ,\n reportMessage:

\n {props.resources.reportModalMessage}\n

,\n reportSubmittedMessage:

\n {props.resources.reportSubmittedMessage}\n

,\n radioButtons: radioPairs(props),\n error: \n {props.resources.errorMessageText}\n \n };\n};\n\nconst radioPairs = (props: IReportReviewModalProps) => {\n const pairs = [];\n for (const option of reportConcernDropdownOptions) {\n const inputId = `report-review-${option.key}`;\n const checked = option.key === props.reportedKey;\n pairs.push(\n
\n \n \n
\n );\n }\n\n return (\n
\n {pairs}\n
\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Review } from '@msdyn365-commerce/commerce-entities';\nimport { RatingComponent } from '@msdyn365-commerce/components';\nimport { getUrlSync, IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\nimport { getRnrAuthEndpointId, getRnrPartnerId } from '@msdyn365-commerce-modules/retail-actions';\nimport {\n Alert, Button, getPayloadObject, getTelemetryAttributes, INodeProps, ITelemetryContent, Modal, ModalBody, ModalFooter, ModalHeader, TelemetryConstant\n} from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nimport { GetUserReviewInput } from '../actions/inputs/get-user-review-input';\nimport { SubmitUserReviewInput } from '../actions/inputs/submit-user-review-input';\nimport submitUserReview from '../actions/submit-user-review';\n\nexport interface IReviewModalProps {\n userReview?: Review;\n product?: SimpleProduct;\n renderContextId: string;\n resources: IReviewModalResources;\n context: ICoreContext>;\n parentId: string;\n parentType: string;\n isOpen: boolean;\n rating: number;\n reviewTitle: string;\n reviewText: string;\n returnRef: React.RefObject | undefined;\n hasError: boolean;\n telemetryContent?: ITelemetryContent;\n onModalToggle(): void;\n onTitleChange(event: React.ChangeEvent): void;\n onTextChange(event: React.ChangeEvent): void;\n onRatingChange(value: number): void;\n onReviewComplete?(isSuccess: boolean): void;\n}\n\nexport interface IReviewModalResources {\n selectRatingAriaLabel: string;\n selectRatingLabel: string;\n reviewTitleLabel: string;\n reviewTextLabel: string;\n privacyPolicyTitle: string;\n privacyPolicyTextFormat: string;\n writeReviewModalTitle: string;\n editReviewModalTitle: string;\n submitReviewButtonText: string;\n discardReviewButtonText: string;\n errorMessageText: string;\n}\n\nexport interface IReviewModalViewProps {\n modal: INodeProps;\n modalHeader: React.ReactElement;\n modalFooter: INodeProps;\n modalBody: INodeProps;\n cancelButton: React.ReactElement;\n submitButton: React.ReactElement;\n rating: React.ReactElement;\n ratingLabel: React.ReactElement;\n titleInput: React.ReactElement;\n titleLabel: React.ReactElement;\n textInput: React.ReactElement;\n textLabel: React.ReactElement;\n privacyPolicyUrl: React.ReactElement;\n form: INodeProps;\n inputRow: INodeProps;\n error: React.ReactElement;\n}\n\n/**\n * CartLineItems component.\n */\n\nexport const ReviewModal = (props: IReviewModalProps): IReviewModalViewProps => {\n const onClickSubmit = () => {\n onSubmit(props);\n };\n const payLoad = getPayloadObject('click', props.telemetryContent!, TelemetryConstant.SubmitReview);\n const submitButtonAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n payLoad.contentAction.etext = TelemetryConstant.Cancel;\n const cancelButtonAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n return {\n modal: { tag: Modal, className: 'ms-review-modal msc-modal-input-required', toggle: props.onModalToggle, applicationNode: 'renderPage', isOpen: props.isOpen, returnFocusRef: props.returnRef },\n modalHeader: modalHeaderNode(props),\n modalFooter: { tag: ModalFooter, className: 'ms-review-modal-footer' },\n modalBody: { tag: ModalBody, className: 'ms-review-modal-body' },\n cancelButton: ,\n submitButton: \n {props.resources.submitReviewButtonText}\n ,\n rating: ratingsInput(props),\n ratingLabel: ratingsLabel(props),\n titleInput: titleInput(props),\n titleLabel: titleLabel(props),\n textInput: textInput(props),\n textLabel: textLabel(props),\n privacyPolicyUrl: privacyPolicyLink(props),\n form: { tag: 'form', className: 'ms-review-modal-form', autoComplete: 'off' },\n inputRow: { tag: 'div', className: 'ms-review-modal-row', autoComplete: 'off' },\n error: \n {props.resources.errorMessageText}\n \n };\n};\n\nconst modalHeaderNode = (props: IReviewModalProps) => {\n return (\n \n { props.userReview && props.userReview.reviewId ? props.resources.editReviewModalTitle : props.resources.writeReviewModalTitle }\n \n );\n};\n\nconst submitDisabled = (props: IReviewModalProps) => {\n return !props.rating || !stripWhiteSpacesFromString(props.reviewText) || !stripWhiteSpacesFromString(props.reviewTitle);\n};\n\nconst ratingsInput = (props: IReviewModalProps) => {\n return (\n \n );\n};\n\nconst ratingsLabel = (props: IReviewModalProps) => {\n return ();\n};\n\nconst titleInput = (props: IReviewModalProps) => {\n const maxLength = props.context.app.config.reviewTitleMaxLength;\n\n return (\n \n );\n};\n\nconst titleLabel = (props: IReviewModalProps) => {\n return ();\n};\n\nconst reviewTextWidth: number = 50;\n\nconst textInput = (props: IReviewModalProps) => {\n const maxLength = props.context.app.config.reviewTextMaxLength;\n return (\n \n );\n};\n\nconst textLabel = (props: IReviewModalProps) => {\n return ();\n};\n\nconst privacyPolicyLink = (props: IReviewModalProps) => {\n const policyTextBlocks = props.resources.privacyPolicyTextFormat.split('{0}');\n const isSeparatorAtStart = props.resources.privacyPolicyTextFormat.startsWith('{0}');\n const isSeparatorAtEnd = props.resources.privacyPolicyTextFormat.endsWith('{0}');\n const privacyPolicyUrl = getUrlSync('rnrPrivacyPolicy', props.context.actionContext);\n const payLoad = getPayloadObject('click', props.telemetryContent!, TelemetryConstant.PrivacyPolicy);\n const privacyPolicyAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\n\n return (\n

\n {isSeparatorAtStart ? '' : policyTextBlocks[0]}\n \n {props.resources.privacyPolicyTitle}\n \n {isSeparatorAtEnd ? '' : (isSeparatorAtStart ? policyTextBlocks[0] : policyTextBlocks[1]) }\n

\n );\n};\n\nconst onSubmit = (props: IReviewModalProps): void => {\n if (props.product) {\n submitReview(props.product, props.reviewTitle, props.reviewText, props.rating, props.context, props.userReview, props.onReviewComplete);\n }\n};\n\n/**\n * This method strips content of extra white spaces.\n * @param text The text to be stripped of extra white spaces.\n */\nconst stripWhiteSpacesFromString = (text: string): string => {\n return text\n .replace(new RegExp('\\\\r?\\\\n|\\\\r+', 'g'), ' ')\n .replace(new RegExp('\\\\s+', 'g'), ' ')\n .trim();\n};\n\nexport const submitReview = (product: SimpleProduct, title: string, text: string, rating: number, context: ICoreContext, userReview?: Review, onReviewSubmission?: (isSuccessful: boolean) => void) => {\n const { request } = context;\n const { user } = request;\n if (user && request) {\n const input = new SubmitUserReviewInput(\n product.RecordId.toString(),\n getRnrPartnerId(context.actionContext),\n request.apiSettings.channelId.toString(),\n request.locale,\n {\n productName: product && product.Name,\n rating,\n reviewText: stripWhiteSpacesFromString(text),\n title: stripWhiteSpacesFromString(title),\n userEmail: user.emailAddress,\n userName: user.name\n },\n request.user.token,\n getRnrAuthEndpointId(context.actionContext)\n );\n\n submitUserReview(input, context.actionContext).then(reviewId => {\n const review = reviewId ? {\n rating,\n title: stripWhiteSpacesFromString(title),\n reviewText: stripWhiteSpacesFromString(text),\n submittedDateTime: new Date(),\n helpfulPositive: userReview ? userReview.helpfulPositive : 0,\n helpfulNegative: userReview ? userReview.helpfulNegative : 0,\n reviewId,\n userName: request.user.firstName || request.user.name\n } : userReview;\n\n const getReviewInput = new GetUserReviewInput(input.productId!, input.tenantId, input.authorization, input.serviceEndpoint);\n context.actionContext.update(getReviewInput, review);\n\n if (onReviewSubmission) {\n onReviewSubmission(!!reviewId);\n }\n }).catch(() => {\n const productId = product.RecordId;\n context.telemetry.error(`Failed to submit review for product with recordId: ${productId}`);\n context.telemetry.debug(`Failed to submit review for product with recordId: ${productId}`);\n if (onReviewSubmission) {\n onReviewSubmission(false);\n }\n });\n }\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Reviews } from '@msdyn365-commerce/commerce-entities';\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, IAny, ICreateActionContext, IGeneric, sendRequest } from '@msdyn365-commerce/core';\nimport { getRnrEndpointId, getRnrPartnerId, getSelectedProductIdFromActionInput } from '@msdyn365-commerce-modules/retail-actions';\n\nimport { GetProductReviewsInput } from './inputs/get-product-reviews-input';\n\n/**\n * TODO: Use this function to create the input required to make the API call.\n * @param input\n */\nexport const createInputForProductReviews = (input: ICreateActionContext>): IActionInput => {\n const productId = getSelectedProductIdFromActionInput(input);\n if (productId) {\n // Task #211227597 Remove these hardcoded values.\n return new GetProductReviewsInput(productId, getRnrPartnerId(input), input.requestContext.locale, getRnrEndpointId(input));\n }\n throw new Error('[GetProductReviews] Not all necessary parameters found while creating Input for GetProductReviewsApi');\n};\n\nexport async function getReviewsForGivenProduct(input: GetProductReviewsInput, ctx: IActionContext): Promise {\n if (!inputIsValid(input)) {\n throw new Error(\n `[GetProductReviews] Invalid input. ProductId = ${input.productId}, TenantId = ${input.tenantId}, localeListFilter = ${input.localeListFilter}`\n );\n }\n let requestUrl =\n `${input.serviceEndpoint}/v2.0/reviews/product/${input.productId}` +\n `?tenantId=${input.tenantId}` +\n `&localeListFilter=${input.localeListFilter}` +\n `&pageSize=${input.pageSize}` +\n `&orderBy=${input.orderBy}` +\n `&skipItems=${input.skipItems}`;\n\n if (input.starFilters !== undefined && input.starFilters.length > 0) {\n requestUrl = `${requestUrl}&starFilters=${input.starFilters}`;\n }\n\n if (input.pageToken !== null) {\n requestUrl = `${requestUrl}&pageToken=${input.pageToken}`;\n }\n return sendRequest(requestUrl, 'get')\n .then(response => {\n if (response.data && response.data.items && response.data.items.length > 0) {\n return {\n items: response.data.items.filter(i => !i.isTakenDown),\n pagingInfo: response.data.pagingInfo\n };\n }\n ctx.trace('[GetProductReviews] No reviews found for this product.');\n return response.data;\n })\n .catch(error => {\n ctx.trace('[GetProductReviews] Failed to get reviews for product');\n ctx.telemetry.exception(error);\n ctx.telemetry.debug('[GetProductReviews] Failed to get reviews for product');\n throw error;\n });\n}\n\nfunction inputIsValid(input: GetProductReviewsInput): boolean {\n return input && input.productId.length > 0 && input.tenantId.length > 0 && input.localeListFilter.length > 0 && input.pageSize > 0;\n}\n\nexport const getReviewsForGivenProductDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/ratings-reviews/get-product-reviews',\n action: >getReviewsForGivenProduct,\n input: createInputForProductReviews\n});\n\nexport default getReviewsForGivenProductDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport ReviewsList from './reviews-list';\nimport ReviewsListView from './reviews-list.view';\n\nexport * from './components/components';\nexport * from './components/report-review-modal';\nexport * from './components/review-card';\nexport * from './reviews-list';\nexport * from './reviews-list.data';\nexport * from './reviews-list.props.autogenerated';\nexport * from './reviews-list.view';\n\nexport {\n ReviewsList,\n ReviewsListView\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { getPayloadObject, getTelemetryAttributes, ITelemetryContent, TelemetryConstant } from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nexport const SignInMessage: React.FC<{ text: string }> = (props: { text: string }) => {\n return (

\n {props.text}\n

);\n};\n\nexport const SignInButton: React.FC<{ text: string; href: string; ariaLabel: string; telemetryContent?: ITelemetryContent }> = (props: { text: string; href: string; ariaLabel: string; telemetryContent?: ITelemetryContent }) => {\n const { text, href, ariaLabel, telemetryContent } = props;\n const payLoad = getPayloadObject('click', telemetryContent!, TelemetryConstant.SignIn);\n const attributes = getTelemetryAttributes(telemetryContent!, payLoad);\n return (\n {text}\n );\n};\n\ninterface IModalToggleProps {\n innerRef: React.RefObject | undefined;\n id: string;\n text: string;\n ariaLabel: string;\n telemetryContent?: ITelemetryContent;\n onClick(): void;\n}\n\nexport const ModalToggle: React.FC = (props: IModalToggleProps) => {\n const { text, onClick, ariaLabel, innerRef, telemetryContent, id } = props;\n const payLoad = getPayloadObject('click', telemetryContent!, TelemetryConstant.WriteReview);\n const attributes = getTelemetryAttributes(telemetryContent!, payLoad);\n return (\n {text}\n );\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Review } from '@msdyn365-commerce/commerce-entities';\nimport * as Msdyn365 from '@msdyn365-commerce/core';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\nimport { getTelemetryObject, IModuleProps, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\nimport classnames from 'classnames';\nimport React from 'react';\n\nimport { IReviewModalViewProps, ReviewModal, submitReview } from '../../common/review-modal';\nimport { TOGGLE_REVIEW_MODAL_BUTTON_ID } from '../../common/rnrInterface';\nimport { ModalToggle, SignInButton, SignInMessage } from './components/components';\nimport { IWriteReviewData } from './write-review.data';\nimport { IWriteReviewProps } from './write-review.props.autogenerated';\n\nexport interface IWriteReviewCallbacks {\n toggleModal(): void;\n updateReviewTitle(title: string): void;\n updateReviewText(text: string): void;\n updateRating(rating: number): void;\n onReviewSubmitted(isSuccessful: boolean): void;\n submitReview(product: SimpleProduct, title: string, text: string, rating: number, context: Msdyn365.ICoreContext, userReview?: Review, onReviewSubmission?: (isSuccessful: boolean) => void): void;\n}\n\nexport interface IWriteReviewState {\n rating: number;\n reviewTitle: string;\n reviewText: string;\n isReviewModalOpen: boolean;\n hasReviewError: boolean;\n}\n\nexport interface IWriteReviewViewProps extends IWriteReviewProps {\n state: IWriteReviewState;\n className: string;\n callbacks: IWriteReviewCallbacks;\n signInMessage: React.ReactNode;\n signInButton: React.ReactNode;\n modalToggle: React.ReactNode;\n reviewModal: IReviewModalViewProps;\n moduleProps: IModuleProps;\n heading: React.ReactNode;\n}\n\n/**\n * This module is enables user's to leave ratings and reviews on a specific product\n * WriteReview module.\n * @extends {React.PureComponent>}\n */\nclass WriteReview extends React.PureComponent, IWriteReviewState> {\n private readonly _modalToggleRef: React.RefObject | undefined;\n\n private readonly telemetryContent: ITelemetryContent;\n\n public constructor(props: IWriteReviewProps) {\n super(props);\n const { userReview: { result: userReview } } = this.props.data;\n this._toggleReviewModal = this._toggleReviewModal.bind(this);\n this._modalToggleRef = React.createRef();\n const rating = userReview ? userReview.rating : 0;\n const reviewTitle = userReview ? userReview.title : '';\n const reviewText = userReview ? userReview.reviewText : '';\n\n this.state = {\n isReviewModalOpen: false,\n rating,\n reviewTitle,\n reviewText,\n hasReviewError: false\n };\n this.telemetryContent = getTelemetryObject(this.props.context.request.telemetryPageName!, this.props.friendlyName, this.props.telemetry);\n }\n\n public render(): JSX.Element {\n const { resources } = this.props;\n const { className, heading } = this.props.config;\n const { product: { result: product }, userReview: { result: userReview } } = this.props.data;\n\n const userInfo = this.props.context && this.props.context.request && this.props.context.request.user;\n const completeClass = classnames('ms-write-review', 'msc-modal-input-required', className);\n const viewProps = {\n ...this.props,\n state: this.state,\n className: completeClass,\n moduleProps: {\n moduleProps: this.props,\n className: completeClass,\n id: null\n },\n callbacks: this.writeReviewCallbacks,\n signInMessage: ,\n signInButton: ,\n modalToggle: product && (\n \n ),\n reviewModal: this._buildUserReviewModal(),\n heading: heading && heading.text && (\n \n )\n } as IWriteReviewViewProps;\n\n return this.props.renderView(viewProps) as React.ReactElement;\n }\n\n public handleHeadingChange = (event: Msdyn365.ContentEditableEvent) => this.props.config.heading!.text = event.target.value;\n\n private readonly _onTitleChange = (event: React.ChangeEvent): void => {\n this.writeReviewCallbacks.updateReviewTitle(event.target.value);\n };\n\n private readonly _onTextChange = (event: React.ChangeEvent): void => {\n this.writeReviewCallbacks.updateReviewText(event.target.value);\n };\n\n private readonly _onRatingChange = (value: number): void => {\n this.writeReviewCallbacks.updateRating(value);\n };\n\n private readonly _toggleReviewModal = (): void => {\n const userReview = this.props.data.userReview.result;\n if (this.state.isReviewModalOpen) {\n this.setState({ isReviewModalOpen: false, hasReviewError: false });\n } else if (userReview) {\n this.setState({\n isReviewModalOpen: true,\n reviewText: userReview.reviewText,\n reviewTitle: userReview.title,\n rating: userReview.rating\n });\n } else {\n this.setState({\n isReviewModalOpen: true,\n reviewText: '',\n reviewTitle: '',\n rating: 0\n });\n }\n };\n\n /**\n * This method builds the user review modal.\n * @param config The module config.\n */\n private _buildUserReviewModal(): IReviewModalViewProps {\n return ReviewModal({\n userReview: this.props.data.userReview.result,\n product: this.props.data.product.result,\n resources: { ...this.props.resources },\n context: this.props.context,\n parentId: this.props.id,\n parentType: this.props.typeName,\n isOpen: this.state.isReviewModalOpen,\n rating: this.state.rating,\n reviewTitle: this.state.reviewTitle,\n reviewText: this.state.reviewText,\n onModalToggle: this._toggleReviewModal,\n onTitleChange: this._onTitleChange,\n onTextChange: this._onTextChange,\n onRatingChange: this._onRatingChange,\n onReviewComplete: this.writeReviewCallbacks.onReviewSubmitted,\n renderContextId: 'writeReview',\n returnRef: this._modalToggleRef,\n hasError: this.state.hasReviewError,\n telemetryContent: this.telemetryContent\n });\n }\n\n private readonly writeReviewCallbacks: IWriteReviewCallbacks = {\n toggleModal: this._toggleReviewModal,\n updateReviewTitle: (title: string): void => {\n this.setState({ reviewTitle: title });\n },\n updateReviewText: (text: string): void => {\n this.setState({ reviewText: text });\n },\n updateRating: (rating: number): void => {\n this.setState({ rating });\n },\n onReviewSubmitted: (isSuccessful: boolean): void => {\n if (isSuccessful) {\n this.setState({ isReviewModalOpen: false, hasReviewError: false });\n } else {\n this.setState({ hasReviewError: true });\n }\n },\n submitReview\n };\n}\n\nexport default WriteReview;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Review } from '@msdyn365-commerce/commerce-entities';\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, ICreateActionContext, sendRequest } from '@msdyn365-commerce/core';\nimport { getRnrAuthEndpointId, getRnrPartnerId, getSelectedProductIdFromActionInput } from '@msdyn365-commerce-modules/retail-actions';\n\nimport { GetUserReviewInput } from './inputs/get-user-review-input';\n\n/**\n * This method builds the input for the getUserReviewApi call.\n * @param input\n */\nconst createInput = (input: ICreateActionContext): IActionInput => {\n const productId = getSelectedProductIdFromActionInput(input);\n const userInfo = input.requestContext.user;\n if (productId && userInfo && userInfo.isAuthenticated) {\n // Task #211227597 Remove these hardcoded values.\n return new GetUserReviewInput(productId, getRnrPartnerId(input), userInfo.token, getRnrAuthEndpointId(input));\n }\n throw new Error('[GetUserReview] Not all necessary parameters found while creating Input for GetUserReviewAPI');\n};\n\n/**\n * This method gets the user's review from the RnR service endpoint.\n * @param input\n * @param ctx\n */\nasync function getUserReview(input: GetUserReviewInput, ctx: IActionContext): Promise {\n if (!inputIsValid(input)) {\n const errorMessage = `[GettUserReview] Failed to get user's review due to bad input ${input}`;\n ctx.trace(errorMessage);\n throw new Error(errorMessage);\n }\n\n const requestUrl = `${input.serviceEndpoint}/v2.0/reviews/product/${input.productId}/user?tenantId=${input.tenantId}`;\n\n return sendRequest(requestUrl, 'get', null, { headers: { Authorization: `id_token ${input.authorization}` } }).then((response) => {\n return response.data;\n }).catch((error) => {\n ctx.trace('[GettUserReview] Failed to get user\\'s review for product');\n ctx.telemetry.exception(error);\n ctx.telemetry.debug('[GettUserReview] Failed to get user\\'s review for product');\n ctx.trace(error);\n throw (error);\n });\n}\n\nfunction inputIsValid(input: GetUserReviewInput): boolean {\n return input.productId.length > 0 && input.authorization.length > 0 && input.tenantId.length > 0;\n}\n\nexport const getUserReviewDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/ratings-reviews/get-user-review',\n action: >getUserReview,\n input: createInput\n});\n\nexport default getUserReviewDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CacheType, IActionInput } from '@msdyn365-commerce/core';\n\nexport const enum ReviewConcernCategory {\n OffensiveContent = '1',\n ReviewResponse = '7',\n SpamAdvertising = '8',\n Profanity = '9'\n}\n\n/**\n * ReportReviewConcern Input Action.\n */\nexport class ReportReviewConcernInput implements IActionInput {\n public reviewId: string;\n\n public tenantId: string;\n\n public locale: string;\n\n public serviceEndpoint: string;\n\n public concernCategory: string;\n\n public authToken: string;\n\n constructor(\n reviewId: string,\n tenantId: string,\n locale: string,\n concernCategory: string,\n authToken: string,\n serviceEndpoint: string\n ) {\n this.reviewId = reviewId;\n this.tenantId = tenantId;\n this.locale = locale;\n this.concernCategory = concernCategory;\n this.authToken = authToken;\n this.serviceEndpoint = serviceEndpoint;\n }\n\n public getCacheKey = () => 'ReportReviewConcern';\n\n public getCacheObjectType = () => 'ReportReviewConcern';\n\n public dataCacheType = (): CacheType => 'none';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { RatingsSummary } from '@msdyn365-commerce/commerce-entities';\nimport {\n format,\n INodeProps,\n Progress\n} from '@msdyn365-commerce-modules/utilities';\nimport React from 'react';\n\nexport interface IHistogramItemsProps {\n ratingsSummary: RatingsSummary;\n resources: IHistogramItemsResources;\n locale: string;\n onClick(stars: number): void;\n}\n\nexport interface IHistogramItemsResources {\n barItemAriaLabel: string;\n}\n\nexport interface IHistogramItemViewProps {\n starLabel: React.ReactElement;\n bar: React.ReactElement;\n percentage: React.ReactElement;\n buttonProps: INodeProps;\n}\n\n/**\n * CartLineItems component.\n */\n\nexport const HistogramItems = (props: IHistogramItemsProps): IHistogramItemViewProps[] => {\n const { ratingsSummary } = props;\n const totalRatingsCount: number = ratingsSummary.totalRatingsCount || 0;\n return [\n renderItem(props, 5, ratingsSummary.star5Count, totalRatingsCount),\n renderItem(props, 4, ratingsSummary.star4Count, totalRatingsCount),\n renderItem(props, 3, ratingsSummary.star3Count, totalRatingsCount),\n renderItem(props, 2, ratingsSummary.star2Count, totalRatingsCount),\n renderItem(props, 1, ratingsSummary.star1Count, totalRatingsCount)\n ];\n};\n\nconst renderItem = (props: IHistogramItemsProps, stars: number, count?: number, totalCount?: number): IHistogramItemViewProps => {\n count = count || 0;\n totalCount = totalCount || 0;\n const percentage = totalCount === 0 ? 0 : count / totalCount;\n const formattedPercent = new Intl.NumberFormat(props.locale, { style: 'percent' }).format(percentage);\n const ariaLabel = format(props.resources.barItemAriaLabel, stars, formattedPercent);\n\n return {\n starLabel: \n {stars}\n ,\n percentage: \n {formattedPercent}\n ,\n bar: ,\n buttonProps: { tag: 'button', className: 'ms-ratings-histogram__item', onClick: () => {\n props.onClick(stars);\n } }\n };\n};\n\nexport const AverageRatingNumber: React.FC<{ summary: RatingsSummary }> = (props: { summary: RatingsSummary }) => {\n return (

\n {props.summary.averageRating}\n {' '}\n / 5\n

);\n};\n\nexport const TotalReviews: React.FC<{ summary: RatingsSummary }> = (props: { summary: RatingsSummary }) => {\n return (

\n {props.summary.totalRatingsCount}\n

);\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IModuleProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IReviewModalViewProps } from '../../common/review-modal';\nimport { IReportReviewModalViewProps } from './components/report-review-modal';\nimport { IReviewCardViewProps } from './components/review-card';\nimport { IReviewsListState, IReviewsListViewProps } from './reviews-list';\n\nconst ReviewsListview: React.FC = props => {\n const {\n averageRating,\n filterByDropdown,\n heading,\n moduleProps,\n noReviewsMessage,\n noReviewsWithFilterMessage,\n pageControls,\n refineReviewsProps,\n reportReviewModal,\n reviewsListProps,\n reviewCards,\n reviewCount,\n reviewModal,\n sortByDropdown,\n state,\n userReview\n } = props;\n\n if (!userReview && reviewCards.length === 0 && !state.isFilterApplied) {\n return (\n {noReviewsMessage}\n );\n }\n\n return (\n \n {heading}\n {averageRating}\n {reviewCount}\n \n {sortByDropdown}\n {filterByDropdown}\n \n \n {userReview && buildReviewCard(userReview)}\n {reviewCards.map(review => {\n return buildReviewCard(review);\n })}\n \n { reviewCards.length === 0 && state.isFilterApplied && noReviewsWithFilterMessage}\n {pageControls}\n {createReviewModal(reviewModal, moduleProps)}\n {createReportModal(reportReviewModal, state)}\n \n );\n};\n\nconst buildReviewCard = (props: IReviewCardViewProps) => {\n return (\n \n \n {props.rating}\n {props.name}\n \n \n \n {props.reviewTitle}\n {props.date}\n {props.reviewText}\n \n \n {props.responseName}\n {props.responseDate}\n {props.responseText}\n \n \n {props.ratingHelpfulLabel}\n {props.like}\n {props.dislike}\n {props.edit}\n {props.report}\n \n \n \n );\n};\n\nconst createReviewModal = (props: IReviewModalViewProps, moduleProps: IModuleProps): JSX.Element => {\n return (\n \n {props.modalHeader}\n \n \n \n {props.rating}\n {props.ratingLabel}\n \n \n {props.titleLabel}\n {props.titleInput}\n \n \n {props.textLabel}\n {props.textInput}\n \n {props.privacyPolicyUrl}\n {props.error}\n \n \n \n {props.submitButton}\n {props.cancelButton}\n \n \n );\n};\n\nconst createReportModal = (props: IReportReviewModalViewProps, state: IReviewsListState): JSX.Element => {\n return (\n \n \n {state.reported ? props.headerSubmitted : props.header}\n \n \n {state.reported ? props.reportSubmittedMessage : [props.reportMessage, props.radioButtons, props.error]}\n \n \n {state.reported ? props.succesfulButton : [props.submitButton, props.cancelButton]}\n \n \n );\n};\n\nexport default ReviewsListview;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './get-product-reviews';\nexport * from './get-user-review';\nexport * from './inputs/get-product-reviews-input';\nexport * from './inputs/get-user-review-input';\nexport * from './inputs/report-review-concern-input';\nexport * from './inputs/submit-helpfulness-vote-input';\nexport * from './inputs/submit-user-review-input';\nexport * from './inputs/submit-user-review-input-data';\nexport * from './ratings-reviews-state-data-action';\nexport * from './report-review-concern';\nexport * from './submit-helpfulness-vote';\nexport * from './submit-user-review';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { Module, Node } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IHistogramItemViewProps } from './component/components';\nimport { IRatingsHistogramViewProps } from './ratings-histogram';\n\nconst RatingsHistogramView: React.FC = props => {\n const { heading, histogramItems, histogramProps, moduleProps } = props;\n\n return (\n \n {heading}\n \n {histogramItems.map(item => {\n return histogramItem(item);\n })}\n \n \n );\n};\n\nconst histogramItem = (props: IHistogramItemViewProps) => {\n return (\n \n {props.starLabel}\n {props.bar}\n {props.percentage}\n \n );\n};\n\nexport default RatingsHistogramView;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport RatingsHistogram from './ratings-histogram';\nimport RatingsHistogramView from './ratings-histogram.view';\n\nexport * from './component/components';\nexport * from './ratings-histogram';\nexport * from './ratings-histogram.data';\nexport { IRatingsHistogramConfig, IRatingsHistogramProps, IRatingsHistogramResources } from './ratings-histogram.props.autogenerated';\nexport * from './ratings-histogram.view';\n\nexport {\n RatingsHistogram,\n RatingsHistogramView\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { createObservableDataAction, IAction, IActionContext, sendRequest } from '@msdyn365-commerce/core';\n\nimport { SubmitUserReviewInput } from './inputs/submit-user-review-input';\n\n/**\n * This data action allows submitting review to the reviews service.\n * @param input This user review submission text.\n * @param ctx The data action context.\n */\nasync function submitReview(input: SubmitUserReviewInput, ctx: IActionContext): Promise {\n if (!inputIsValid(input)) {\n ctx.trace(`[SubmitUserReview] Failed to submit reviews for product due to bad input ${input}`);\n return '';\n }\n\n const requestUrl = `${input.serviceEndpoint}/v2.0/reviews/product/${input.productId}/user?` +\n `tenantId=${input.tenantId}&` +\n `channelId=${input.channelId}&` +\n `locale=${input.locale}`;\n\n return sendRequest(requestUrl, 'post', input.userReviewData, { headers: { Authorization: `id_token ${input.authorization}` } }).then((response) => {\n if (response.status !== 200 && response.status !== 201) {\n ctx.trace('[SubmitUserReview] Failed to submit reviews for product');\n ctx.trace(response.data);\n return '';\n }\n return response.data;\n }).catch((error) => {\n ctx.trace('[SubmitUserReview] Failed to submit reviews for product');\n ctx.telemetry.exception(error);\n ctx.telemetry.debug('[SubmitUserReview] Failed to submit reviews for product');\n ctx.trace(error);\n return '';\n });\n}\n\nfunction inputIsValid(input: SubmitUserReviewInput): boolean {\n return input && !!input.productId && !!input.tenantId;\n}\n\nexport const submitReviewDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/ratings-reviews/submit-user-review',\n action: >submitReview\n});\n\nexport default submitReviewDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { IModuleProps, Module, Node } from '@msdyn365-commerce-modules/utilities';\nimport * as React from 'react';\n\nimport { IReviewModalViewProps } from '../../common/review-modal';\nimport { IWriteReviewViewProps } from './write-review';\n\nconst WriteReviewView: React.FC = props => {\n const { heading, signInMessage, signInButton, modalToggle, reviewModal, moduleProps } = props;\n const isAuthenticated = props.context.request.user.isAuthenticated;\n return (\n \n {heading}\n {!isAuthenticated ? <>\n {signInMessage}\n {signInButton}\n : <>\n {modalToggle}\n {createReviewModal(reviewModal, moduleProps)}\n }\n \n );\n};\n\nconst createReviewModal = (props: IReviewModalViewProps, moduleProps: IModuleProps): JSX.Element => {\n return (\n \n {props.modalHeader}\n \n \n \n {props.rating}\n {props.ratingLabel}\n \n \n {props.titleLabel}\n {props.titleInput}\n \n \n {props.textLabel}\n {props.textInput}\n \n {props.privacyPolicyUrl}\n {props.error}\n \n \n \n {props.submitButton}\n {props.cancelButton}\n \n \n );\n};\n\nexport default WriteReviewView;\n"],"sourceRoot":""}