Skip to content

Commit

Permalink
Merge pull request #174 from vtex-apps/feat/assembly
Browse files Browse the repository at this point in the history
Feat/assembly
  • Loading branch information
jgfidelis committed Jul 26, 2019
2 parents edd1f90 + dc7b57d commit 83eb4f3
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 68 deletions.
8 changes: 8 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "vtex-react",
"env": {
"browser": true,
"es6": true,
"jest": true
}
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ 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
- Add capability to show assembly options of assembly options.

## [2.29.2] - 2019-07-23
### Changed
Expand Down
6 changes: 3 additions & 3 deletions react/__tests__/__snapshots__/ProductSummary.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ exports[`<ProductSummary /> component should match the snapshot for inline norma
exports[`<ProductSummary /> component should match the snapshot for inline price mode 1`] = `
<DocumentFragment>
<section
class="container containerInline overflow-hidden br3 h-100 w-100"
class="container containerInline overflow-hidden br3 h-100 w-100 overflow-y-auto"
>
<article
class="element pointer ph2 pt3 pb4 flex flex-column h-100"
Expand Down Expand Up @@ -167,7 +167,7 @@ exports[`<ProductSummary /> component should match the snapshot for inline price
</div>
</div>
<div
class="information w-70 pb2 pl3 pr3"
class="information w-70 pb2 ph3 overflow-y-auto"
>
<div
class="flex items-start justify-left tl w-90 t-mini pb2"
Expand All @@ -177,7 +177,7 @@ exports[`<ProductSummary /> component should match the snapshot for inline price
</div>
</div>
<div
class="mt3 nr2"
class="mv3 nr2"
>
<div
class="flex justify-end nr4 mb2 quantityStepperContainer"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
import React, { Fragment } from 'react'
import { arrayOf, number } from 'prop-types'
import { intlShape, injectIntl } from 'react-intl'
import { arrayOf, bool } from 'prop-types'
import { FormattedMessage } from 'react-intl'

import AttachmentItem from './AttachmentItem'

import { CHOICE_TYPES } from '../../utils/attachmentHelper'

import { addedOptionShape } from '../../utils/propTypes'

const formatAttachmentName = (option, intl) => {
const extraParams = {
sign: '+',
name: option.item.name,
quantity: option.extraQuantity || option.normalizedQuantity,
}
return intl.formatMessage(
{ id: 'store/productSummary.attachmentName' },
extraParams
)
}
const formatAttachmentName = option => (
<FormattedMessage
id="store/productSummary.attachmentName"
values={{
sign: '+',
name: option.item.name,
quantity: option.normalizedQuantity,
}}
/>
)

const AddedAttachmentsList = ({ addedOptions, parentPrice, intl }) => {
const AddedAttachmentsList = ({ addedOptions, showItemPrice }) => {
if (addedOptions.length === 0) {
return null
}
return (
<Fragment>
<AttachmentItem
productText={intl.formatMessage({ id: 'store/productSummary.unit' })}
price={parentPrice}
/>
{addedOptions.map(option => {
const isSingle = option.choiceType === CHOICE_TYPES.SINGLE
const productText = isSingle
? option.item.name
: formatAttachmentName(option, intl)
const isMultiple = option.choiceType === CHOICE_TYPES.MULTIPLE
const productText = isMultiple
? formatAttachmentName(option)
: option.item.name
return (
<AttachmentItem
productText={productText}
price={option.item.sellingPrice * option.normalizedQuantity}
key={productText}
price={
option.item.sellingPriceWithAssemblies * option.normalizedQuantity
}
key={`${option.item.name}-${option.choiceType}`}
assemblyOptions={option.item.assemblyOptions}
showItemPrice={showItemPrice}
/>
)
})}
</Fragment>
)
}

AddedAttachmentsList.defaultProps = {
showItemPrice: true,
}

AddedAttachmentsList.propTypes = {
intl: intlShape,
addedOptions: arrayOf(addedOptionShape).isRequired,
parentPrice: number.isRequired,
showItemPrice: bool,
}

export default injectIntl(AddedAttachmentsList)
export default AddedAttachmentsList
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import AddedAttachmentsList from './AddedAttachmentsList'
import RemovedAttachmentsList from './RemovedAttachmentsList'

import styles from '../../productSummary.css'

const AttachmentChildren = ({ addedOptions, removedOptions }) => {
if (addedOptions.length === 0 && removedOptions.length === 0) {
return null
}

return (
<div className={`${styles.attachmentChildrenContainer} ml3`}>
<AddedAttachmentsList addedOptions={addedOptions} showItemPrice={false} />
<RemovedAttachmentsList removedOptions={removedOptions} />
</div>
)
}

export default AttachmentChildren
58 changes: 41 additions & 17 deletions react/components/ProductSummaryAttachmentList/AttachmentItem.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
import React, { memo } from 'react'
import { string, number } from 'prop-types'
import { string, number, object, bool } from 'prop-types'
import ProductPrice from 'vtex.store-components/ProductPrice'
import { reject } from 'ramda'

import styles from '../../productSummary.css'
import AttachmentChildren from './AttachmentChildren'

const itemShouldHide = ({ item, extraQuantity }) =>
extraQuantity === 0 && item.sellingPriceWithAssemblies === 0

const AttachmentItem = ({
productText,
price,
assemblyOptions,
showItemPrice,
}) => {
const childrenAdded = (assemblyOptions && assemblyOptions.added) || []
const childrenRemoved = (assemblyOptions && assemblyOptions.removed) || []
const filteredChildrenAdded = reject(itemShouldHide, childrenAdded)
const parentColor =
filteredChildrenAdded.length > 0 || childrenRemoved.length > 0
? 'c-on-base'
: 'c-muted-2'

const AttachmentItem = ({ productText, price }) => {
return (
<div
className={`${styles.attachmentItemContainer} flex items-center justify-between pv1`}
>
<span className="t-small c-muted-2 tl pr3">{productText}</span>
{price != null && (
<ProductPrice
sellingPrice={price}
sellingPriceContainerClass="c-on-base"
sellingPriceLabelClass="dib"
sellingPriceClass="dib t-small c-muted-2"
showListPrice={false}
showLabels={false}
showInstallments={false}
/>
)}
<div className={`${styles.attachmentItemContainer} flex flex-column pv1`}>
<div className={`flex items-center justify-between`}>
<span className={`t-small ${parentColor} tl pr3`}>{productText}</span>
{price != null && showItemPrice && price > 0 && (
<ProductPrice
sellingPrice={price}
sellingPriceContainerClass="c-on-base"
sellingPriceLabelClass="dib"
sellingPriceClass="dib t-small c-muted-2"
showListPrice={false}
showLabels={false}
showInstallments={false}
/>
)}
</div>
<AttachmentChildren
addedOptions={filteredChildrenAdded}
removedOptions={childrenRemoved}
/>
</div>
)
}

AttachmentItem.propTypes = {
productText: string.isRequired,
price: number,
assemblyOptions: object,
showItemPrice: bool,
}

export default memo(AttachmentItem)
14 changes: 5 additions & 9 deletions react/components/ProductSummaryAttachmentList/AttachmentList.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
import React from 'react'
import { pathOr } from 'ramda'
import { pathOr, reject } from 'ramda'

import { useProductSummary } from 'vtex.product-summary-context/ProductSummaryContext'
import RemovedAttachmentsList from './RemovedAttachmentsList'
import AddedAttachmentsList from './AddedAttachmentsList'

import styles from '../../productSummary.css'

const shouldShowOption = option =>
option.extraQuantity > 0 || option.item.sellingPrice !== 0
const itemShouldHide = ({ item, extraQuantity }) =>
extraQuantity === 0 && item.sellingPriceWithAssemblies === 0

const AttachmentList = () => {
const { product } = useProductSummary()
const addedOptions = pathOr([], ['assemblyOptions', 'added'], product)
const removedOptions = pathOr([], ['assemblyOptions', 'removed'], product)
const parentPrice = pathOr(0, ['assemblyOptions', 'parentPrice'], product)

const filteredOption = addedOptions.filter(shouldShowOption)
const filteredOption = reject(itemShouldHide, addedOptions)

if (filteredOption.length === 0 && removedOptions.length === 0) {
return null
}

return (
<div className={`${styles.attachmentListContainer} pv2`}>
<AddedAttachmentsList
addedOptions={filteredOption}
parentPrice={parentPrice}
/>
<AddedAttachmentsList addedOptions={filteredOption} />
<RemovedAttachmentsList removedOptions={removedOptions} />
</div>
)
Expand Down
14 changes: 5 additions & 9 deletions react/legacy/components/AttachmentList.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import React from 'react'
import { productShape } from '../../utils/propTypes'
import { pathOr } from 'ramda'
import { pathOr, reject } from 'ramda'

import RemovedAttachmentsList from '../../components/ProductSummaryAttachmentList/RemovedAttachmentsList'
import AddedAttachmentsList from '../../components/ProductSummaryAttachmentList/AddedAttachmentsList'

import styles from '../../productSummary.css'

const shouldShowOption = option =>
option.extraQuantity > 0 || option.item.sellingPrice !== 0
const itemShouldHide = ({ item, extraQuantity }) =>
extraQuantity === 0 && item.sellingPriceWithAssemblies === 0

const AttachmentList = ({ product }) => {
const addedOptions = pathOr([], ['assemblyOptions', 'added'], product)
const removedOptions = pathOr([], ['assemblyOptions', 'removed'], product)
const parentPrice = pathOr(0, ['assemblyOptions', 'parentPrice'], product)

const filteredOption = addedOptions.filter(shouldShowOption)
const filteredOption = reject(itemShouldHide, addedOptions)

if (filteredOption.length === 0 && removedOptions.length === 0) {
return null
}

return (
<div className={`${styles.attachmentListContainer} pv2`}>
<AddedAttachmentsList
addedOptions={filteredOption}
parentPrice={parentPrice}
/>
<AddedAttachmentsList addedOptions={filteredOption} />
<RemovedAttachmentsList removedOptions={removedOptions} />
</div>
)
Expand Down
1 change: 1 addition & 0 deletions react/legacy/components/ProductQuantityStepper.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ProductQuantityStepper extends Component {
}

pushPixelCartEvents = ({ isAdditionOfProd, product }) => {
// TODO: update these events
const updatedProduct = {
id: path(['sku', 'itemId'], product),
name: path(['productName'], product),
Expand Down
6 changes: 3 additions & 3 deletions react/legacy/components/ProductSummaryInlinePrice.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const ProductSummaryInlinePrice = ({
const containerClasses = classNames(
styles.container,
styles.containerInline,
'overflow-hidden br3 h-100 w-100'
'overflow-hidden br3 h-100 w-100 overflow-y-auto'
)

const summaryClasses = classNames(
Expand Down Expand Up @@ -82,10 +82,10 @@ const ProductSummaryInlinePrice = ({
<div className={`${styles.imageContainer} db h-100`}>
<ProductImage {...imageProps} />
</div>
<div className={`${styles.information} w-70 pb2 pl3 pr3`}>
<div className={`${styles.information} w-70 pb2 ph3 overflow-y-auto`}>
<ProductSummaryName {...nameProps} {...nameClasses} />
<AttachmentList product={product} />
<div className="mt3 nr2">
<div className="mv3 nr2">
<div
className={`flex justify-end nr4 mb2 ${styles.quantityStepperContainer}`}
>
Expand Down
3 changes: 3 additions & 0 deletions react/productSummary.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@

.imagePlaceholder {
}

.attachmentChildrenContainer {
}

0 comments on commit 83eb4f3

Please sign in to comment.