diff --git a/CHANGELOG.md b/CHANGELOG.md index 674b7305..414c6705 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed + +- Make Related products shelf fetch its items. ## [1.15.0] - 2019-05-17 diff --git a/manifest.json b/manifest.json index c3693edb..cbee3f7e 100644 --- a/manifest.json +++ b/manifest.json @@ -24,5 +24,6 @@ "vtex.slider": "0.x", "vtex.store-icons": "0.x", "vtex.pixel-manager": "0.x" - } -} + }, + "$schema": "https://raw.githubusercontent.com/vtex/node-vtex-api/master/gen/manifest.schema" +} \ No newline at end of file diff --git a/messages/context.json b/messages/context.json index 3d46c491..aaaeb521 100644 --- a/messages/context.json +++ b/messages/context.json @@ -27,6 +27,9 @@ "admin/editor.relatedProducts.similars": "admin/editor.relatedProducts.similars", "admin/editor.relatedProducts.view": "admin/editor.relatedProducts.view", "admin/editor.relatedProducts.buy": "admin/editor.relatedProducts.buy", + "admin/editor.relatedProducts.accessories": "admin/editor.relatedProducts.accessories", + "admin/editor.relatedProducts.viewAndBought": "admin/editor.relatedProducts.viewAndBought", + "admin/editor.relatedProducts.suggestions": "admin/editor.relatedProducts.suggestions", "store/shelf.title": "store/shelf.title", "admin/editor.tabbed-shelf.title": "Component title", "admin/editor.tabbed-shelf.description": "Component description", diff --git a/messages/en.json b/messages/en.json index 77a2c410..cf4526b5 100644 --- a/messages/en.json +++ b/messages/en.json @@ -27,6 +27,9 @@ "admin/editor.relatedProducts.similars": "Similar products", "admin/editor.relatedProducts.view": "Who saw this, also saw...", "admin/editor.relatedProducts.buy": "Who bought this, also bought...", + "admin/editor.relatedProducts.accessories": "Accessories products", + "admin/editor.relatedProducts.viewAndBought": "Who saw this, also bought...", + "admin/editor.relatedProducts.suggestions": "Suggestions", "store/shelf.title": "Best Products", "admin/editor.tabbed-shelf.title": "Tabbed Shelf", "admin/editor.tabbed-shelf.description": "Tabbed Shelf featured product module", diff --git a/messages/es.json b/messages/es.json index 522a062f..f3b0fcc7 100644 --- a/messages/es.json +++ b/messages/es.json @@ -27,5 +27,8 @@ "admin/editor.relatedProducts.similars": "Productos similares", "admin/editor.relatedProducts.view": "Quién vio esto, también vio...", "admin/editor.relatedProducts.buy": "Quién compró esto, también compró...", + "admin/editor.relatedProducts.accessories": "Productos de accesorios", + "admin/editor.relatedProducts.viewAndBought": "Quien vio esto, también compró ...", + "admin/editor.relatedProducts.suggestions": "Sugerencias", "store/shelf.title": "Mejores Productos" } diff --git a/messages/pt.json b/messages/pt.json index b6e012d9..5666284b 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -27,5 +27,8 @@ "admin/editor.relatedProducts.similars": "Produtos similares", "admin/editor.relatedProducts.view": "Quem viu isto, também viu...", "admin/editor.relatedProducts.buy": "Quem comprou isto, também comprou...", + "admin/editor.relatedProducts.accessories": "Produtos de acessórios", + "admin/editor.relatedProducts.viewAndBought": "Quem viu isto, comprou também...", + "admin/editor.relatedProducts.suggestions": "Sugestões", "store/shelf.title": "Melhores Produtos" } diff --git a/react/RelatedProducts.js b/react/RelatedProducts.js index 902b92b4..6efa3d58 100644 --- a/react/RelatedProducts.js +++ b/react/RelatedProducts.js @@ -1,89 +1,116 @@ +import React from 'react' import PropTypes from 'prop-types' -import { path } from 'ramda' -import React, { Component } from 'react' +import { path, last } from 'ramda' +import { Query } from 'react-apollo' + +import productRecommendations from './queries/productRecommendations.gql' import ProductList from './ProductList' import { productListSchemaPropTypes } from './propTypes' -import { shelfItemPropTypes } from './propTypes' import shelf from './shelf.css' + +// Previous values were in a wrong format with the message string in the enum value. +const fixRecommendation = recommendation => { + if (recommendation.includes('admin/editor.relatedProducts.')) { + return last(recommendation.split('.')) + } + return recommendation +} + /** * Related Products Component. Queries and shows the related products */ -export default class RelatedProducts extends Component { - static propTypes = { - /** Main product to have related products queried */ - slug: PropTypes.string, - /** Graphql productQuery response. */ - productQuery: PropTypes.shape({ - /** Product to have related products queried */ - product: PropTypes.shape({ - /** Recommendations property */ - recommendations: PropTypes.shape({ - /** View recommendations (who saw this product, also saw...) */ - view: PropTypes.arrayOf(shelfItemPropTypes.item), - /** Buy recommendations (who bought this product, also bought...) */ - buy: PropTypes.arrayOf(shelfItemPropTypes.item), - /** Similar products */ - similars: PropTypes.arrayOf(shelfItemPropTypes.item), - }), - }), - }), - /** ProductList schema configuration */ - productList: PropTypes.shape(productListSchemaPropTypes), - } - static defaultProps = { - recommendation: 'admin/editor.relatedProducts.similars', - productList: { - ...ProductList.defaultProps, - titleText: 'Related Products', - }, +const RelatedProducts = ({ productQuery, productList, recommendation: cmsRecommendation }) => { + const productId = path(['product', 'productId'], productQuery) + if (!productId) { + return null } + const recommendation = fixRecommendation(cmsRecommendation) + const variables = { identifier: { field: 'id', value: productId }, type: recommendation } + return ( + + {({data, loading}) => { + const { productRecommendations } = data + const productListProps = { + products: productRecommendations || [], + loading, + ...productList, + } + return ( +
+ +
+ ) + }} +
+ ) +} - static getSchema = props => { - const productListSchema = ProductList.getSchema(props) - productListSchema.properties.titleText.default = - RelatedProducts.defaultProps.productList.titleText +RelatedProducts.propTypes = { + /** Main product to have related products queried */ + slug: PropTypes.string, + /** Graphql productQuery response. */ + productQuery: PropTypes.shape({ + /** Product to have related products queried */ + product: PropTypes.shape({ + productId: PropTypes.string, + }), + loading: PropTypes.bool, + }), + /** ProductList schema configuration */ + productList: PropTypes.shape(productListSchemaPropTypes), +} - return { - title: 'admin/editor.relatedProducts.title', - description: 'admin/editor.relatedProducts.description', - type: 'object', - properties: { - recommendation: { - title: 'admin/editor.relatedProducts.recommendation', - description: 'admin/editor.relatedProducts.recommendation.description', - type: 'string', - default: RelatedProducts.defaultProps.recommendation, - enum: [ - 'admin/editor.relatedProducts.similars', - 'admin/editor.relatedProducts.view', - 'admin/editor.relatedProducts.buy', - ], - }, - productList: productListSchema, - }, - } - } +RelatedProducts.defaultProps = { + recommendation: 'similars', + productList: { + ...ProductList.defaultProps, + titleText: 'Related Products', + }, +} - render() { - const { productQuery, productList } = this.props - const recommendation = this.props.recommendation.split('.').pop() - const products = path( - ['product', 'recommendations', recommendation], - productQuery - ) - const productListProps = { - products, - loading: productQuery.loading, - ...productList, - } +RelatedProducts.getSchema = props => { + const productListSchema = ProductList.getSchema(props) + productListSchema.properties.titleText.default = + RelatedProducts.defaultProps.productList.titleText - return ( -
- -
- ) + return { + title: 'admin/editor.relatedProducts.title', + description: 'admin/editor.relatedProducts.description', + type: 'object', + properties: { + recommendation: { + title: 'admin/editor.relatedProducts.recommendation', + description: 'admin/editor.relatedProducts.recommendation.description', + type: 'string', + default: RelatedProducts.defaultProps.recommendation, + enum: [ + 'similars', + 'view', + 'buy', + 'accessories', + 'viewAndBought', + 'suggestions' + ], + enumNames: [ + 'admin/editor.relatedProducts.similars', + 'admin/editor.relatedProducts.view', + 'admin/editor.relatedProducts.buy', + 'admin/editor.relatedProducts.accessories', + 'admin/editor.relatedProducts.viewAndBought', + 'admin/editor.relatedProducts.suggestions', + ], + }, + productList: productListSchema, + }, } } + +export default RelatedProducts \ No newline at end of file diff --git a/react/queries/productRecommendations.gql b/react/queries/productRecommendations.gql new file mode 100644 index 00000000..d30c244f --- /dev/null +++ b/react/queries/productRecommendations.gql @@ -0,0 +1,56 @@ +query ProductRecommendations( + $identifier: ProductUniqueIdentifier + $type: CrossSelingInputEnum +) { + productRecommendations(identifier: $identifier, type: $type) { + cacheId + productId + productName + description + categories + categoryTree { + name + href + } + link + linkText + brand + items { + name + itemId + referenceId { + Value + } + images { + imageId + imageLabel + imageTag + imageUrl + imageText + } + sellers { + sellerId + sellerName + addToCartLink + sellerDefault + commertialOffer { + Price + ListPrice + PriceWithoutDiscount + RewardValue + PriceValidUntil + AvailableQuantity + Tax + CacheVersionUsedToCallCheckout + Installments { + Value + InterestRate + TotalValuePlusInterestRate + NumberOfInstallments + Name + } + } + } + } + } +}