@graphcommerce/magento-product 9.0.0-canary.71 → 9.0.0-canary.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 9.0.0-canary.73
4
+
5
+ ## 9.0.0-canary.72
6
+
7
+ ### Minor Changes
8
+
9
+ - [#2332](https://github.com/graphcommerce-org/graphcommerce/pull/2332) [`73e897a`](https://github.com/graphcommerce-org/graphcommerce/commit/73e897a5a5f266d9ec274807720c71eb1a639074) - Use custom_attributesV2 for product specs when running on magento 247 or higher ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
10
+
3
11
  ## 9.0.0-canary.71
4
12
 
5
13
  ## 9.0.0-canary.70
@@ -42,7 +42,7 @@ export function ProductFiltersProAggregations(props: ProductFiltersProAggregatio
42
42
  (aggregation) => {
43
43
  const filterType = filterTypes[aggregation.attribute_code]
44
44
  if (!filterType) {
45
- console.log('Filter not recognized', aggregation.attribute_code, filterTypes)
45
+ // console.log('Filter not recognized', aggregation.attribute_code, filterTypes)
46
46
  return null
47
47
  }
48
48
 
@@ -1,8 +1,8 @@
1
1
  import { LazyHydrate, RenderType, extendableComponent, responsiveVal } from '@graphcommerce/next-ui'
2
2
  import { Box, BoxProps, Breakpoint, Theme, useTheme } from '@mui/material'
3
- import { ProductListItemFragment } from '../../Api/ProductListItem.gql'
4
3
  import { AddProductsToCartForm } from '../AddProductsToCart'
5
4
  import { ProductListItemProps } from '../ProductListItem/ProductListItem'
5
+ import { ProductListItemsFragment } from './ProductListItems.gql'
6
6
  import { ProductListItemRenderer } from './renderer'
7
7
 
8
8
  type ComponentState = {
@@ -30,11 +30,7 @@ type ColumnConfig = {
30
30
 
31
31
  type ColumnsConfig = Partial<Record<Breakpoint, ColumnConfig>>
32
32
 
33
- export type ProductItemsGridProps = {
34
- items?:
35
- | Array<(ProductListItemFragment & ProductListItemProps) | null | undefined>
36
- | null
37
- | undefined
33
+ export type ProductItemsGridProps = ProductListItemsFragment & {
38
34
  renderers: ProductListItemRenderer
39
35
  loadingEager?: number
40
36
  title: string
@@ -44,7 +40,7 @@ export type ProductItemsGridProps = {
44
40
  ComponentState
45
41
 
46
42
  const slots = ['root'] as const
47
- const name = 'ProductListItemsBase' as const
43
+ const name = 'ProductListItemsBase'
48
44
 
49
45
  const { withState } = extendableComponent<ComponentState, typeof name, typeof slots>(name, slots)
50
46
 
@@ -52,7 +52,7 @@ export type AnyFilterType =
52
52
  export function isFilterTypeEqual(filter?: unknown): filter is FilterEqualTypeInput {
53
53
  return Boolean(
54
54
  filter &&
55
- ('in' in (filter as FilterEqualTypeInput) || 'from' in (filter as FilterEqualTypeInput)),
55
+ ('in' in (filter as FilterEqualTypeInput) || 'eq' in (filter as FilterEqualTypeInput)),
56
56
  )
57
57
  }
58
58
 
@@ -72,7 +72,7 @@ export function toProductListParams(params: ProductFilterParams): ProductListPar
72
72
 
73
73
  const newFilers = Object.fromEntries(
74
74
  Object.entries(filters).filter(([, value]) => {
75
- if (isFilterTypeEqual(value)) return Boolean(value.in)
75
+ if (isFilterTypeEqual(value)) return Boolean(value.in || value.eq)
76
76
  if (isFilterTypeMatch(value)) return Boolean(value.match)
77
77
  if (isFilterTypeRange(value)) return Boolean(value.from || value.to)
78
78
  return false
@@ -1,5 +1,5 @@
1
1
  fragment ProductSpecs on Products {
2
- aggregations {
2
+ aggregations @skip(if: $useCustomAttributes) {
3
3
  attribute_code
4
4
  count
5
5
  label
@@ -9,4 +9,24 @@ fragment ProductSpecs on Products {
9
9
  value
10
10
  }
11
11
  }
12
+ items {
13
+ __typename
14
+ uid
15
+ ...ProductListItem
16
+ custom_attributesV2(filters: { is_visible_on_front: true }) @include(if: $useCustomAttributes) {
17
+ items {
18
+ code
19
+ __typename
20
+ ... on AttributeValue {
21
+ value
22
+ }
23
+ ... on AttributeSelectedOptions {
24
+ selected_options {
25
+ label
26
+ value
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
12
32
  }
@@ -1,6 +1,8 @@
1
1
  import { responsiveVal, Row, SectionContainer, extendableComponent } from '@graphcommerce/next-ui'
2
2
  import { Box, SxProps, Theme } from '@mui/material'
3
3
  import { ProductSpecsFragment } from './ProductSpecs.gql'
4
+ import { ProductSpecsAggregations } from './ProductSpecsAggregations'
5
+ import { ProductSpecsCustomAttributes } from './ProductSpecsCustomAttributes'
4
6
 
5
7
  export type ProductSpecsProps = ProductSpecsFragment & {
6
8
  title?: string
@@ -13,7 +15,7 @@ const parts = ['root', 'specs', 'options'] as const
13
15
  const { classes } = extendableComponent(name, parts)
14
16
 
15
17
  export function ProductSpecs(props: ProductSpecsProps) {
16
- const { aggregations, title, children, sx = [] } = props
18
+ const { aggregations, items, title, children, sx = [] } = props
17
19
  const filter = ['price', 'category_id', 'size', 'new', 'sale', 'color']
18
20
  const specs = aggregations?.filter(
19
21
  (attr) => !filter.includes(attr?.attribute_code ?? '') && attr?.options?.[0]?.value !== '0',
@@ -46,16 +48,8 @@ export function ProductSpecs(props: ProductSpecsProps) {
46
48
  },
47
49
  })}
48
50
  >
49
- {specs?.map((aggregation) => (
50
- <li key={aggregation?.attribute_code}>
51
- <div>{aggregation?.label}</div>
52
- <Box className={classes.options} sx={{ display: 'grid', gridAutoFlow: 'row' }}>
53
- {aggregation?.options?.map((option) => (
54
- <span key={option?.value}>{option?.label === '1' ? 'Yes' : option?.label}</span>
55
- ))}
56
- </Box>
57
- </li>
58
- ))}
51
+ {aggregations && <ProductSpecsAggregations aggregations={aggregations} />}
52
+ {items && <ProductSpecsCustomAttributes items={items} />}
59
53
  </Box>
60
54
  {children}
61
55
  </SectionContainer>
@@ -0,0 +1,34 @@
1
+ import { extendableComponent } from '@graphcommerce/next-ui'
2
+ import { Box } from '@mui/material'
3
+ import { ProductSpecsFragment } from './ProductSpecs.gql'
4
+
5
+ const name = 'ProductSpecs' as const
6
+ const parts = ['root', 'specs', 'options'] as const
7
+ const { classes } = extendableComponent(name, parts)
8
+
9
+ export type ProductSpecsAggregationsProps = Pick<ProductSpecsFragment, 'aggregations'>
10
+
11
+ export function ProductSpecsAggregations(props: ProductSpecsAggregationsProps) {
12
+ const { aggregations } = props
13
+ const filter = ['price', 'category_id', 'size', 'new', 'sale', 'color']
14
+ const specs = aggregations?.filter(
15
+ (attr) => !filter.includes(attr?.attribute_code ?? '') && attr?.options?.[0]?.value !== '0',
16
+ )
17
+
18
+ if (specs?.length === 0) return null
19
+
20
+ return (
21
+ <>
22
+ {specs?.map((aggregation) => (
23
+ <li key={aggregation?.attribute_code}>
24
+ <div>{aggregation?.label}</div>
25
+ <Box className={classes.options} sx={{ display: 'grid', gridAutoFlow: 'row' }}>
26
+ {aggregation?.options?.map((option) => (
27
+ <span key={option?.value}>{option?.label === '1' ? 'Yes' : option?.label}</span>
28
+ ))}
29
+ </Box>
30
+ </li>
31
+ ))}
32
+ </>
33
+ )
34
+ }
@@ -0,0 +1,47 @@
1
+ import { useQuery } from '@graphcommerce/graphql'
2
+ import { extendableComponent } from '@graphcommerce/next-ui'
3
+ import { Box } from '@mui/material'
4
+ import { ProductSpecsFragment } from './ProductSpecs.gql'
5
+ import { ProductSpecsTypesDocument } from './ProductSpecsTypes.gql'
6
+
7
+ const name = 'ProductSpecs' as const
8
+ const parts = ['root', 'specs', 'options'] as const
9
+ const { classes } = extendableComponent(name, parts)
10
+
11
+ export type ProductSpecsCustomAttributesProps = Pick<ProductSpecsFragment, 'items'>
12
+
13
+ export function ProductSpecsCustomAttributes(props: ProductSpecsCustomAttributesProps) {
14
+ const { items } = props
15
+
16
+ const specs = items?.[0]?.custom_attributesV2?.items
17
+
18
+ const productSpecsTypes = useQuery(ProductSpecsTypesDocument)
19
+
20
+ if (items?.length === 0) return null
21
+
22
+ return (
23
+ <>
24
+ {specs?.map((item) => (
25
+ <li key={item?.code}>
26
+ <div>
27
+ {
28
+ productSpecsTypes?.data?.attributesList?.items?.find(
29
+ (type) => type?.code === item?.code,
30
+ )?.label
31
+ }
32
+ </div>
33
+ <Box className={classes.options} sx={{ display: 'grid', gridAutoFlow: 'row' }}>
34
+ {item?.__typename === 'AttributeSelectedOptions' && (
35
+ <>
36
+ {item?.selected_options?.map((option) => (
37
+ <span key={option?.value}>{option?.label === '1' ? 'Yes' : option?.label}</span>
38
+ ))}
39
+ </>
40
+ )}
41
+ {item?.__typename === 'AttributeValue' && <span key={item?.value}>{item.value}</span>}
42
+ </Box>
43
+ </li>
44
+ ))}
45
+ </>
46
+ )
47
+ }
@@ -0,0 +1,8 @@
1
+ query ProductSpecsTypes {
2
+ attributesList(entityType: CATALOG_PRODUCT, filters: { is_visible_on_front: true }) {
3
+ items {
4
+ code
5
+ label
6
+ }
7
+ }
8
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-product",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "9.0.0-canary.71",
5
+ "version": "9.0.0-canary.73",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -18,19 +18,19 @@
18
18
  "typescript": "5.5.3"
19
19
  },
20
20
  "peerDependencies": {
21
- "@graphcommerce/ecommerce-ui": "^9.0.0-canary.71",
22
- "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.71",
23
- "@graphcommerce/framer-next-pages": "^9.0.0-canary.71",
24
- "@graphcommerce/framer-scroller": "^9.0.0-canary.71",
25
- "@graphcommerce/graphql": "^9.0.0-canary.71",
26
- "@graphcommerce/graphql-mesh": "^9.0.0-canary.71",
27
- "@graphcommerce/image": "^9.0.0-canary.71",
28
- "@graphcommerce/magento-cart": "^9.0.0-canary.71",
29
- "@graphcommerce/magento-category": "^9.0.0-canary.71",
30
- "@graphcommerce/magento-store": "^9.0.0-canary.71",
31
- "@graphcommerce/next-ui": "^9.0.0-canary.71",
32
- "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.71",
33
- "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.71",
21
+ "@graphcommerce/ecommerce-ui": "^9.0.0-canary.73",
22
+ "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.73",
23
+ "@graphcommerce/framer-next-pages": "^9.0.0-canary.73",
24
+ "@graphcommerce/framer-scroller": "^9.0.0-canary.73",
25
+ "@graphcommerce/graphql": "^9.0.0-canary.73",
26
+ "@graphcommerce/graphql-mesh": "^9.0.0-canary.73",
27
+ "@graphcommerce/image": "^9.0.0-canary.73",
28
+ "@graphcommerce/magento-cart": "^9.0.0-canary.73",
29
+ "@graphcommerce/magento-category": "^9.0.0-canary.73",
30
+ "@graphcommerce/magento-store": "^9.0.0-canary.73",
31
+ "@graphcommerce/next-ui": "^9.0.0-canary.73",
32
+ "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.73",
33
+ "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.73",
34
34
  "@lingui/core": "^4.2.1",
35
35
  "@lingui/macro": "^4.2.1",
36
36
  "@lingui/react": "^4.2.1",