{"version":3,"file":"static/js/a6f99d67099b638b48c8.bundle.js","mappings":"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","sources":["webpack://Dobbies.Commerce/./src/modules/dobbies-product-page-summary/dobbies-product-page-summary.action.ts?fc19","webpack://Dobbies.Commerce/./src/modules/dobbies-product-page-summary/dobbies-product-page-summary.tsx?f8a0","webpack://Dobbies.Commerce/./lib/dobbies-product-page-summary/module-registration.js?3fbc","webpack://Dobbies.Commerce/external var \"React\"?0d3b","webpack://Dobbies.Commerce/external var \"ReactDOM\"?853b"],"sourcesContent":["/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n getCatalogId,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IRequestContext\r\n} from '@msdyn365-commerce/core';\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { getAttributeValuesAsync, getByIdsAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport {\r\n ArrayExtensions,\r\n buildCacheKey,\r\n generateImageUrl,\r\n getProductUrlSync,\r\n getSelectedProductIdFromActionInput,\r\n QueryResultSettingsProxy,\r\n removeDomainQspFromUrl\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { IPageSummaryData } from '@msdyn365-commerce-modules/page-summary';\r\nimport { IDobbiesProductPageSummaryConfig } from './dobbies-product-page-summary.props.autogenerated';\r\n\r\n/**\r\n * Product Page Summary Input.\r\n */\r\nexport class ProductPageSummaryInput implements IActionInput {\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n public config: IDobbiesProductPageSummaryConfig;\r\n\r\n public productId: number;\r\n\r\n public catalogId?: number;\r\n\r\n public constructor(\r\n config: IDobbiesProductPageSummaryConfig,\r\n apiSettings: ICommerceApiSettings,\r\n productId: number,\r\n requestContext?: IRequestContext\r\n ) {\r\n this.config = config || {};\r\n this.apiSettings = apiSettings;\r\n this.productId = productId;\r\n\r\n if (requestContext) {\r\n this.catalogId = getCatalogId(requestContext);\r\n }\r\n }\r\n\r\n public getCacheObjectType = (): string => 'ProductPageSummary';\r\n\r\n public getCacheKey = (): string =>\r\n `${buildCacheKey('ProductPageSummary', this.apiSettings)}-${this.config.title}-${this.productId}-${this.catalogId ?? 0}`;\r\n\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\nexport interface IProductPageSummary extends IPageSummaryData {\r\n price?: number;\r\n productId?: number;\r\n productBrand?: string;\r\n}\r\n\r\nconst createInput = (args: ICreateActionContext) => {\r\n const productId = getSelectedProductIdFromActionInput(args);\r\n\r\n if (productId) {\r\n return new ProductPageSummaryInput(\r\n args.config,\r\n args.requestContext.apiSettings,\r\n +productId,\r\n args.requestContext\r\n );\r\n }\r\n throw new Error('Unable to create ProductPageSummaryAction input, no productId found on module config or query');\r\n};\r\n\r\n// Checks product attributes for the presence of brand attribute to extract the brand name for product metadata\r\nconst getProductBrand = async (\r\n context: IActionContext,\r\n recordId: number,\r\n channelId: number,\r\n catalogId: number\r\n): Promise => {\r\n const productAttributes = await getAttributeValuesAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context)\r\n },\r\n recordId,\r\n channelId,\r\n catalogId\r\n );\r\n for (const productAttribute of productAttributes) {\r\n if (productAttribute.Name === 'Brand') {\r\n return productAttribute.TextValue;\r\n }\r\n }\r\n return;\r\n};\r\n\r\nconst action = async (input: ProductPageSummaryInput, context: IActionContext): Promise => {\r\n const { config, productId, apiSettings } = input;\r\n // const jsonUrl =\r\n // context.requestContext.app.config.pdpSeoJsonUrl ||\r\n // 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD4Pas';\r\n // const res = await Msdyn365.sendRequest(jsonUrl, 'get');\r\n const excelUrl =\r\n context.requestContext.app.config.pdpSeoTSVUrl ||\r\n 'https://files-eu-prod.cms.commerce.dynamics.com/cms/api/ctdwmwnctb/binary/MD8qTr';\r\n const excelRes = await Msdyn365.sendRequest(excelUrl, 'get');\r\n const prodID = productId.toString();\r\n // const pdpSeoData = res.data && res.data[prodID];\r\n\r\n let simpleProductsData: SimpleProduct[] | undefined;\r\n try {\r\n simpleProductsData = ArrayExtensions.validValues(\r\n await getByIdsAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context)\r\n },\r\n apiSettings.channelId,\r\n [productId],\r\n null,\r\n input.catalogId ?? 0\r\n )\r\n );\r\n } catch {\r\n // Do nothing, if there's an error we fall back to values defined from config\r\n }\r\n if (ArrayExtensions.hasElements(simpleProductsData)) {\r\n const simpleProductData = simpleProductsData[0];\r\n let productUrl: string | undefined;\r\n try {\r\n productUrl = getProductUrlSync(simpleProductData, context);\r\n const canonicalDomain = context.requestContext.canonicalDomain;\r\n if (productUrl && canonicalDomain) {\r\n productUrl = `https://${canonicalDomain}${productUrl}`.toLocaleLowerCase();\r\n productUrl = removeDomainQspFromUrl(productUrl, context.requestContext);\r\n } else {\r\n productUrl = undefined;\r\n }\r\n } catch {\r\n productUrl = undefined;\r\n }\r\n let productBrand: string | undefined;\r\n try {\r\n productBrand = await getProductBrand(context, productId, apiSettings.channelId, input.catalogId ?? 0);\r\n } catch {\r\n productBrand = undefined;\r\n }\r\n const excelDataStr = excelRes.data as string;\r\n const splittedExcelData = excelDataStr.split('\\n');\r\n let title = simpleProductData.Name;\r\n let desc = simpleProductData.Description ? simpleProductData.Description : simpleProductData.Name;\r\n let canonical = productUrl;\r\n for (const dataRow of splittedExcelData) {\r\n if (!dataRow || !dataRow.trim()) {\r\n continue;\r\n }\r\n const rowSplitted = dataRow.trim().split('\\t');\r\n const curl = rowSplitted[0];\r\n if (prodID && (prodID === curl || curl.includes(prodID))) {\r\n title = rowSplitted.length > 1 ? rowSplitted[1] : simpleProductData.Name;\r\n desc = rowSplitted.length > 2 ? rowSplitted[2] : simpleProductData.Description;\r\n canonical = rowSplitted.length > 3 ? rowSplitted[3] : productUrl;\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: title,\r\n description: desc,\r\n sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl,\r\n productId: simpleProductData.RecordId,\r\n price: simpleProductData.AdjustedPrice,\r\n productBrand\r\n };\r\n }\r\n }\r\n if (config.descriptionLimit && desc) {\r\n desc = desc.substring(0, config.descriptionLimit);\r\n }\r\n return {\r\n title: title,\r\n description: desc,\r\n sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n canonicalUrl: canonical,\r\n faviconUrl: config && config.faviconUrl,\r\n productId: simpleProductData.RecordId,\r\n price: simpleProductData.AdjustedPrice,\r\n productBrand\r\n };\r\n // return {\r\n // title: pdpSeoData ? pdpSeoData.title : simpleProductData.Name,\r\n // description: pdpSeoData ? pdpSeoData.description : simpleProductData.Description,\r\n // sharingImageUrl: generateImageUrl(simpleProductData.PrimaryImageUrl, apiSettings),\r\n // canonicalUrl: pdpSeoData ? pdpSeoData.canonicalUrl : productUrl,\r\n // faviconUrl: config && config.faviconUrl,\r\n // productId: simpleProductData.RecordId,\r\n // price: simpleProductData.AdjustedPrice,\r\n // productBrand\r\n // };\r\n\r\n // If the action fails fallback to values defined from config\r\n } else if (config) {\r\n return {\r\n title: config.title,\r\n description: config.descriptionLimit ? config.description?.substring(0, config.descriptionLimit) : config.description,\r\n sharingImageUrl: config.sharingImage && config.sharingImage.src,\r\n faviconUrl: config && config.faviconUrl\r\n };\r\n }\r\n return {};\r\n};\r\n\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/page-summary/product-page-summary',\r\n action: >action,\r\n input: createInput\r\n});\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { HtmlHeadInclude, IAny, IGeneric } from '@msdyn365-commerce/core';\r\nimport * as React from 'react';\r\n\r\nimport { IDobbiesProductPageSummaryData } from './dobbies-product-page-summary.data';\r\nimport { IDobbiesProductPageSummaryProps } from './dobbies-product-page-summary.props.autogenerated';\r\n\r\n/**\r\n *\r\n * ProductPageSummary component.\r\n * @extends {React.PureComponent}\r\n */\r\nclass ProductPageSummary extends React.PureComponent> {\r\n public render(): JSX.Element {\r\n if (this.props.data.productPageSummary.result === undefined) {\r\n throw new Error('PageSummaryData input to page-summary is undefined. Unable to generate page-summary');\r\n }\r\n let {\r\n data: {\r\n productPageSummary: {\r\n // result: { title, description, keywords, sharingImageUrl, faviconUrl }\r\n result: { title, description, sharingImageUrl, faviconUrl }\r\n }\r\n }\r\n } = this.props;\r\n\r\n const {\r\n config,\r\n context,\r\n data: {\r\n productPageSummary: {\r\n result: { canonicalUrl, productId, productBrand, price }\r\n }\r\n }\r\n } = this.props;\r\n\r\n // Product SEO metadata specific information - non-overridable\r\n const productName = title;\r\n const productDescription = description;\r\n const productImageUrl = sharingImageUrl;\r\n\r\n // Override values coming from data action if config values are provided\r\n title = config.title || title;\r\n description = config.description || description;\r\n // keywords = config.keywords || keywords;\r\n sharingImageUrl = (config.sharingImage && config.sharingImage.src) || sharingImageUrl;\r\n faviconUrl = config.faviconUrl || faviconUrl;\r\n\r\n // Construct page title with suffix and prefix if provided from app settings\r\n const pageTitle = this._constructPageTitle(title, context && context.request && context.request.app);\r\n return (\r\n <>\r\n \r\n {pageTitle && {pageTitle}}\r\n {description && }\r\n {/* {keywords && } */}\r\n {canonicalUrl && }\r\n {faviconUrl && }\r\n \r\n {this._renderProductMetadata(\r\n productName,\r\n productDescription,\r\n productImageUrl,\r\n canonicalUrl,\r\n productId,\r\n price,\r\n context.request.channel?.Currency,\r\n productBrand\r\n )}\r\n {!config.disableOgTags && this._renderOgTags(pageTitle, description, sharingImageUrl)}\r\n {!config.disableTwitterTags && this._renderTwitterTags(pageTitle, description, sharingImageUrl)}\r\n \r\n );\r\n }\r\n\r\n /**\r\n * Renders the facebook and other social media specific metadata tags.\r\n *\r\n * @param title Page title.\r\n * @param description Product description.\r\n * @param sharingImageUrl Primary product image url.\r\n */\r\n private _renderOgTags(title: string | undefined, description: string | undefined, sharingImageUrl: string | undefined): JSX.Element {\r\n return (\r\n \r\n {title && }\r\n {description && }\r\n {sharingImageUrl && }\r\n \r\n \r\n );\r\n }\r\n\r\n /**\r\n * Constructs and renders the JSON-LD tag used to output product specific metadata used by search engine crawlers.\r\n *\r\n * @param productName Product name.\r\n * @param description Product description.\r\n * @param sharingImageUrl Primary product image url.\r\n * @param canonicalUrl Product canonical url.\r\n * @param productId Master product id.\r\n * @param price Proudct price.\r\n * @param currencyCode Current channel currency code.\r\n * @param productBrand Product brand.\r\n */\r\n private _renderProductMetadata(\r\n productName: string | undefined,\r\n description: string | undefined,\r\n sharingImageUrl: string | undefined,\r\n canonicalUrl: string | undefined,\r\n productId: number | undefined,\r\n price: number | undefined,\r\n currencyCode: string | undefined,\r\n productBrand: string | undefined\r\n ): JSX.Element {\r\n // Construct the JSON-LD data that contains the product metadata information used by search enginge crawlers\r\n const productMetaData = JSON.stringify({\r\n '@context': 'http://schema.org',\r\n '@type': 'Product',\r\n name: productName,\r\n description,\r\n image: sharingImageUrl,\r\n sku: productId,\r\n brand: {\r\n '@type': 'Brand',\r\n name: productBrand\r\n },\r\n offers: {\r\n '@type': 'Offer',\r\n url: canonicalUrl,\r\n priceCurrency: currencyCode,\r\n price\r\n }\r\n });\r\n return (\r\n \r\n {/* eslint-disable-next-line react/no-danger -- Implementation is a copy.*/}\r\n