Skip to content

Commit

Permalink
Merge pull request #2485 from graphcommerce-org/feature/various
Browse files Browse the repository at this point in the history
CMS Block integration in example
  • Loading branch information
paales authored Jan 23, 2025
2 parents fb35345 + 87e9f88 commit 86afdab
Show file tree
Hide file tree
Showing 47 changed files with 169 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-worms-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-product-configurable': patch
---

Solve issue where the GetConfigurableOptionsSelection query would be executed even if the product wasn't a ConfigurableProduct.
5 changes: 5 additions & 0 deletions .changeset/funny-rats-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-product': patch
---

ProductSpecs now uses `attribute { label }` instead of `useQuery(ProductSpecsTypes)`
5 changes: 5 additions & 0 deletions .changeset/large-balloons-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cms': patch
---

Added cmsBlocks query and `<CmsBlock />` component.
5 changes: 5 additions & 0 deletions .changeset/nice-starfishes-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart-items': patch
---

Solve issue where the CartItem href wouldn't be correct
5 changes: 5 additions & 0 deletions .changeset/spicy-mangos-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart': patch
---

When ordering a virtual product the checkout would still reference a Track & Trace
5 changes: 5 additions & 0 deletions .changeset/ten-flies-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart-items': patch
---

Exported cartItemToCartItemInput so it can be extended with plugins
6 changes: 6 additions & 0 deletions .changeset/tender-emus-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphcommerce/magento-store': patch
'@graphcommerce/next-ui': patch
---

Added a CurrencySymbol component that renders the current currency symbol
4 changes: 2 additions & 2 deletions docs/feature-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,13 @@ Features taken from the Magento Commerce 2 Feature List
registry. — [Commerce]
- [ ] Automatically update item counts and notify the registry owner as
purchases are made. — [Commerce]
- [ ] Allow customers to purchase physical and virtual gift cards. — [Commerce]
- [x] Allow customers to purchase physical and virtual gift cards. — [Commerce]
- [ ] Offer exclusive shopping experiences with private or flash sale sites. —
[Commerce]
- [ ] Streamline re-ordering by enabling shoppers to add products to the cart by
SKU. — [Commerce]
- [ ] Accelerate growth by collecting and displaying high-converting user
generated content powered by Yotpo. — [Commerce]
generated content powered by Yotpo. — [Commerce] f

### Customer accounts

Expand Down
6 changes: 3 additions & 3 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ roadmap.
- [ ] GraphCommerce Pro: Distribution of private npm packages for customers.
- [ ] GraphCommerce Pro: Distribution of private Magento modules for customers.
- [ ] Adobe Commerce: Returns functionality
- [ ] Adobe Commerce: Store credit functionality
- [x] Adobe Commerce: Store credit functionality
- [x] Adobe Commerce: Gift card functionality
- [ ] Adobe Commerce: Content staging functionality in preview mode.
- [ ] Storelocator UI. Generic Store Locator UI to allow for any datasource to
be used. Integrate with Magento's pickupLocations functionality.
Expand All @@ -36,7 +37,6 @@ roadmap.
- [ ] Upgrade to React 19 + Next.js app router support.
- [ ] Adobe Commerce: Reward points functionality
- [ ] Adobe Commerce: Gift wrapping functionality
- [ ] Adobe Commerce: Gift card functionality
- [ ] Adobe Commerce: Gift registry functionality
- [ ] Adobe Commerce: Multi Wishlist functionality
- [ ] Adobe Comemrce: Adobe Sensei integration
Expand All @@ -50,7 +50,7 @@ roadmap.
logging in.
- [ ] Magento 2.4.7: Implement attributesForm for customer_account_edit,
customer_account_create, customer_register_address, customer_address_edit
- [ ] Magento 2.4.7: sendEmailToFriend implementation
- [ ] Magento: sendEmailToFriend implementation
- [ ] Magento 2.4.7: Implement a new success page on the the new
guestOrderByToken
- [ ] Magento: Implement fixed_product_taxes
Expand Down
5 changes: 3 additions & 2 deletions examples/magento-open-source/components/Layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { DateFormat, Footer as FooterBase } from '@graphcommerce/next-ui'
import { Trans } from '@lingui/macro'
import { Button, Link } from '@mui/material'

export function Footer() {
export function Footer(props: { socialLinks?: React.ReactNode }) {
const { socialLinks } = props
const cartEnabled = useCheckoutGuestEnabled()
const config = useQuery(StoreConfigDocument)

Expand All @@ -14,7 +15,7 @@ export function Footer() {

return (
<FooterBase
socialLinks={<div />}
socialLinks={socialLinks}
storeSwitcher={<StoreSwitcherButton />}
customerService={
<Button href='/service' variant='pill'>
Expand Down
6 changes: 6 additions & 0 deletions examples/magento-open-source/components/Layout/Layout.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ query Layout {
__typename
}
...MenuQueryFragment

cmsBlocks(identifiers: ["footer_links_block"]) {
items {
...CmsBlock
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CmsBlock } from '@graphcommerce/magento-cms'
import type { LayoutDefaultProps } from '@graphcommerce/next-ui'
import { LayoutDefault } from '@graphcommerce/next-ui'
import { Footer } from './Footer'
Expand All @@ -8,13 +9,15 @@ export type LayoutMinimalProps = LayoutQuery &
Omit<LayoutDefaultProps, 'header' | 'footer' | 'cartFab' | 'noSticky'>

export function LayoutMinimal(props: LayoutMinimalProps) {
const { menu, children, ...uiProps } = props
const { menu, children, cmsBlocks, ...uiProps } = props

const footerBlock = cmsBlocks?.items?.find((item) => item?.identifier === 'footer_links_block')

return (
<LayoutDefault
{...uiProps}
header={<Logo />}
footer={<Footer />}
footer={<Footer socialLinks={footerBlock ? <CmsBlock cmsBlock={footerBlock} /> : <div />} />}
sx={{ background: (theme) => theme.palette.background.paper }}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CartFab, useCartEnabled } from '@graphcommerce/magento-cart'
import { magentoMenuToNavigation } from '@graphcommerce/magento-category'
import { CmsBlock } from '@graphcommerce/magento-cms'
import { CustomerFab, CustomerMenuFabItem } from '@graphcommerce/magento-customer'
import { SearchFab, SearchField } from '@graphcommerce/magento-search'
import { WishlistFab, WishlistMenuFabItem } from '@graphcommerce/magento-wishlist'
Expand Down Expand Up @@ -36,13 +37,15 @@ export type LayoutNavigationProps = LayoutQuery &
Omit<LayoutDefaultProps, 'footer' | 'header' | 'cartFab' | 'menuFab'>

export function LayoutNavigation(props: LayoutNavigationProps) {
const { menu, children, ...uiProps } = props
const { menu, children, cmsBlocks, ...uiProps } = props

const selection = useNavigationSelection()
const router = useRouter()

const cartEnabled = useCartEnabled()

const footerBlock = cmsBlocks?.items?.find((item) => item?.identifier === 'footer_links_block')

return (
<>
<NavigationProvider
Expand Down Expand Up @@ -167,7 +170,9 @@ export function LayoutNavigation(props: LayoutNavigationProps) {
</MobileTopRight>
</>
}
footer={<Footer />}
footer={
<Footer socialLinks={footerBlock ? <CmsBlock cmsBlock={footerBlock} /> : <div />} />
}
cartFab={<CartFab BadgeProps={{ color: 'secondary' }} />}
menuFab={<NavigationFab onClick={() => selection.set([])} />}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Image } from '@graphcommerce/image'
import { useDisplayInclTax } from '@graphcommerce/magento-cart/hooks'
import type { ProductLinkProps } from '@graphcommerce/magento-product'
import { productLink, productPath, type ProductLinkProps } from '@graphcommerce/magento-product'
import { Money } from '@graphcommerce/magento-store'
import type { ActionCardProps } from '@graphcommerce/next-ui'
import { ActionCard, actionCardImageSizes, filterNonNullableKeys } from '@graphcommerce/next-ui'
Expand Down Expand Up @@ -107,7 +107,7 @@ export function CartItemActionCard(props: CartItemActionCardProps) {
title={
url_key ? (
<Link
href={url_key}
href={productPath(url_key)}
underline='hover'
sx={{
color: 'inherit',
Expand Down
1 change: 1 addition & 0 deletions packages/magento-cart-items/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export * from './components/SelectedCustomizableOptions/SelectedCustomizableOpti
export * from './components/UpdateItemQuantity/UpdateItemQuantity'
export * from './components/EditCartItem'
export * from './hooks/useRemoveItemFromCart'
export * from './utils/cartItemToCartItemInput'
4 changes: 3 additions & 1 deletion packages/magento-cart/components/CartSummary/CartSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ export function CartSummary(props: CartSummaryProps) {
<Box>
<SectionContainer
variantLeft='h5'
labelLeft={<Trans id='Confirmation + Track & trace' />}
labelLeft={
is_virtual ? <Trans id='Confirmation' /> : <Trans id='Confirmation + Track & trace' />
}
sx={{ '& .SectionHeader-root': { marginTop: 0, paddingBottom: '8px' } }}
/>
<Typography variant='body1'>{email || ''}</Typography>
Expand Down
4 changes: 4 additions & 0 deletions packages/magento-cms/components/CmsBlock/CmsBlock.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fragment CmsBlock on CmsBlock {
identifier
content
}
10 changes: 10 additions & 0 deletions packages/magento-cms/components/CmsBlock/CmsBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { CmsBlockFragment } from './CmsBlock.gql'

export type CmsBlockProps = { cmsBlock: CmsBlockFragment | null | undefined }

export function CmsBlock(props: CmsBlockProps) {
const { cmsBlock } = props
if (!cmsBlock?.content) return null
// eslint-disable-next-line react/no-danger
return <div dangerouslySetInnerHTML={{ __html: cmsBlock.content }} />
}
7 changes: 7 additions & 0 deletions packages/magento-cms/graphql/CmsBlocks.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
query CmsBlocks($identifiers: [String!]!) {
cmsBlocks(identifiers: $identifiers) {
items {
...CmsBlock
}
}
}
2 changes: 2 additions & 0 deletions packages/magento-cms/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './components/CmsBlock/CmsBlock'
export * from './components/CmsBlock/CmsBlock.gql'
export * from './components/CmsPageContent/CmsPageContent'
export * from './components/CmsPageContent/CmsPageContent.gql'
export * from './components/CmsPageMeta/CmsPageMeta'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function ConfigurableProductOption(props: ConfigurableProductOptionProps)
attribute_code,
url_key,
render,
__typename,
...other
} = props
const fieldName = `cartItems.${index}.selected_options.${optionIndex}` as const
Expand All @@ -55,7 +56,11 @@ export function ConfigurableProductOption(props: ConfigurableProductOptionProps)
// .slice(0, optionIndex)
.filter((o) => o !== selectedOption)

const { configured } = useConfigurableOptionsForSelection({ url_key, selectedOptions })
const { configured } = useConfigurableOptionsForSelection({
__typename,
url_key,
selectedOptions,
})

const available =
configured?.configurable_product_options_selection?.options_available_for_selection?.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function ConfigurableProductOptions(props: ConfigurableProductOptionsProp
'values',
])

const { configured } = useConfigurableOptionsSelection({ url_key: product.url_key, index })
const { configured } = useConfigurableOptionsSelection({ ...product, index })
const unavailable =
configured &&
(configured?.configurable_product_options_selection?.options_available_for_selection ?? [])
Expand Down Expand Up @@ -75,6 +75,7 @@ export function ConfigurableProductOptions(props: ConfigurableProductOptionsProp
index={index}
optionIndex={optionIndex}
sx={sx}
__typename={product.__typename}
url_key={product.url_key}
{...other}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fragment UseConfigurableOptions on ProductInterface {
__typename
url_key
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import { useFormAddProductsToCart } from '@graphcommerce/magento-product'
import { findByTypename, nonNullable } from '@graphcommerce/next-ui'
import { useWatch } from '@graphcommerce/react-hook-form'
import { GetConfigurableOptionsSelectionDocument } from '../graphql/GetConfigurableOptionsSelection.gql'

export type UseConfigurableOptionsSelection = { url_key?: string | null } & AddToCartItemSelector
import type { UseConfigurableOptionsFragment } from '../graphql/UseConfigurableOptions.gql'

type UseConfigurableOptionsForSelection = {
url_key?: string | null
selectedOptions: string[]
}
} & UseConfigurableOptionsFragment

export function useConfigurableOptionsForSelection(variables: UseConfigurableOptionsForSelection) {
const { url_key, selectedOptions } = variables
const { __typename, url_key, selectedOptions } = variables

const selection = useQuery(GetConfigurableOptionsSelectionDocument, {
variables: { urlKey: url_key ?? '', selectedOptions },
skip: !url_key,
skip: __typename !== 'ConfigurableProduct' || !url_key,
})

const configured = selection.error
Expand All @@ -29,15 +27,17 @@ export function useConfigurableOptionsForSelection(variables: UseConfigurableOpt
return { ...selection, configured }
}

export type UseConfigurableOptionsSelection = UseConfigurableOptionsFragment & AddToCartItemSelector

export function useConfigurableOptionsSelection(props: UseConfigurableOptionsSelection) {
const { url_key, index = 0 } = props
const { __typename, url_key, index = 0 } = props

const { control } = useFormAddProductsToCart()
const selectedOptions = (useWatch({ control, name: `cartItems.${index}.selected_options` }) ?? [])
.filter(nonNullable)
.filter(Boolean)

return useConfigurableOptionsForSelection({ url_key, selectedOptions })
return useConfigurableOptionsForSelection({ __typename, url_key, selectedOptions })
}

export function useConfigurableSelectedVariant(props: UseConfigurableOptionsSelection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function ProductPageDescription(
props: PluginProps<ProductPageDescriptionProps & AddToCartItemSelector>,
) {
const { Prev, product, index, ...rest } = props
const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })

return (
<Prev
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { AddToCartItemSelector, ProductPageGalleryProps } from '@graphcommerce/magento-product'
import type { PluginConfig, PluginProps } from '@graphcommerce/next-config'
import { isTypename } from '@graphcommerce/next-ui'
import { useConfigurableOptionsSelection } from '../../hooks'

export const config: PluginConfig = {
Expand All @@ -13,7 +14,7 @@ export function ProductPageGallery(
) {
const { Prev, product, index, ...rest } = props

const { configured } = useConfigurableOptionsSelection({ url_key: product.url_key, index })
const { configured } = useConfigurableOptionsSelection({ ...product, index })
const media_gallery =
(configured?.configurable_product_options_selection?.media_gallery?.length ?? 0) > 0 &&
configured?.configurable_product_options_selection?.variant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ export function ProductPageJsonLd<T extends { '@type': string }, P extends JsonL
props: PluginProps<ProductPageJsonLdProps<T, P>> & AddToCartItemSelector,
) {
const { Prev, product, index, ...rest } = props
const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })
return <Prev product={(variant ?? product) as P} {...rest} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function ProductPageMeta(props: PluginProps<ProductPageMetaProps> & AddTo
const { Prev, product, index, ...rest } = props
const { replace, asPath } = useRouter()

const variant = useConfigurableSelectedVariant({ url_key: product?.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })

const isValidVariant = (variant?.url_rewrites ?? []).length > 0 && variant?.url_key
const targetUrl = isValidVariant ? productLink(variant) : productLink(product)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export const config: PluginConfig = {

export function ProductPageName(props: PluginProps<ProductPageNameProps> & AddToCartItemSelector) {
const { Prev, product, index, ...rest } = props
const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })
return <Prev product={variant ?? product} {...rest} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function ProductPagePrice(
props: PluginProps<ProductPagePriceProps> & AddToCartItemSelector,
) {
const { Prev, product, index, ...rest } = props
const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })

if (product.__typename !== 'ConfigurableProduct') return <Prev {...props} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function ProductPagePriceTiers(
props: PluginProps<ProductPagePriceTiersProps> & AddToCartItemSelector,
) {
const { Prev, product, index, ...rest } = props
const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
const variant = useConfigurableSelectedVariant({ ...product, index })

if (!variant || product.__typename !== 'ConfigurableProduct')
return <Prev product={product} {...rest} />
Expand Down
Loading

0 comments on commit 86afdab

Please sign in to comment.