Skip to content

Commit

Permalink
Merge 52ce466 into e6cb113
Browse files Browse the repository at this point in the history
  • Loading branch information
jgfidelis committed May 24, 2019
2 parents e6cb113 + 52ce466 commit ea7fbad
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 73 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [1.15.3] - 2019-05-24
### Changed

- Make Related products shelf fetch its items.

## [1.15.2] - 2019-05-24

## [1.15.1] - 2019-05-24
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
@@ -1,7 +1,7 @@
{
"name": "shelf",
"vendor": "vtex",
"version": "1.15.2",
"version": "1.15.3",
"title": "VTEX Shelf",
"description": "A shelf component",
"mustUpdateAt": "2019-04-03",
Expand Down
3 changes: 3 additions & 0 deletions messages/context.json
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions messages/en.json
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions messages/es.json
Expand Up @@ -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"
}
3 changes: 3 additions & 0 deletions messages/pt.json
Expand Up @@ -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"
}
177 changes: 105 additions & 72 deletions react/RelatedProducts.js
@@ -1,89 +1,122 @@
import React, { useMemo } 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),
const RelatedProducts = ({ productQuery, productList, recommendation: cmsRecommendation }) => {
const productId = path(['product', 'productId'], productQuery)
if (!productId) {
return null
}
const recommendation = fixRecommendation(cmsRecommendation)
const variables = useMemo(
() => ({
identifier: { field: 'id', value: productId },
type: recommendation,
}),
[productId, recommendation]
)

static defaultProps = {
recommendation: 'admin/editor.relatedProducts.similars',
productList: {
...ProductList.defaultProps,
titleText: 'Related Products',
},
}
return (
<Query
query={productRecommendations}
variables={variables}
partialRefetch
ssr={false}
>
{({data, loading}) => {
const { productRecommendations } = data
const productListProps = {
products: productRecommendations || [],
loading,
...productList,
}
return (
<div className={shelf.relatedProducts}>
<ProductList {...productListProps} />
</div>
)
}}
</Query>
)
}

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 (
<div className={shelf.relatedProducts}>
<ProductList {...productListProps} />
</div>
)
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
56 changes: 56 additions & 0 deletions 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
}
}
}
}
}
}

0 comments on commit ea7fbad

Please sign in to comment.