@graphcommerce/magento-product 9.0.0-canary.57 → 9.0.0-canary.58
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 +6 -0
- package/components/ProductFiltersPro/ProductFiltersProAggregations.tsx +17 -9
- package/components/ProductListFilters/ProductListFilters.tsx +13 -19
- package/components/ProductListItems/ProductFilterTypes.graphql +8 -0
- package/components/ProductListItems/filterTypes.tsx +0 -2
- package/components/ProductListItems/filteredProductList.tsx +9 -9
- package/components/ProductListItems/getFilterTypes.ts +33 -4
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 9.0.0-canary.58
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- [#2328](https://github.com/graphcommerce-org/graphcommerce/pull/2328) [`ee04368`](https://github.com/graphcommerce-org/graphcommerce/commit/ee04368444f732e5541a595db6e2ef66d15add68) - Move to attributesList to get a list of filterable attributes instead of using an introspection query. `productFiltersProSectionRenderer` and `productFiltersProChipRenderer` keys now now one of `AttributeFrontendInputEnum`. ([@paales](https://github.com/paales))
|
8
|
+
|
3
9
|
## 9.0.0-canary.57
|
4
10
|
|
5
11
|
## 9.0.0-canary.56
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { AttributeFrontendInputEnum } from '@graphcommerce/graphql-mesh'
|
1
2
|
import { ProductListFiltersFragment } from '../ProductListFilters/ProductListFilters.gql'
|
2
3
|
import { ProductFilterEqualChip } from './ProductFilterEqualChip'
|
3
4
|
import { ProductFilterEqualSection } from './ProductFilterEqualSection'
|
@@ -11,20 +12,24 @@ export type FilterProps = {
|
|
11
12
|
aggregation: NonNullable<NonNullable<ProductListFiltersFragment['aggregations']>[number]>
|
12
13
|
}
|
13
14
|
|
14
|
-
export type FilterRenderer = Record<
|
15
|
+
export type FilterRenderer = Record<AttributeFrontendInputEnum, React.FC<FilterProps>>
|
15
16
|
|
16
17
|
export type ProductFiltersProAggregationsProps = {
|
17
|
-
renderer?: FilterRenderer
|
18
|
+
renderer?: Partial<FilterRenderer>
|
18
19
|
}
|
19
20
|
|
20
|
-
export const productFiltersProSectionRenderer = {
|
21
|
-
|
22
|
-
|
21
|
+
export const productFiltersProSectionRenderer: Partial<FilterRenderer> = {
|
22
|
+
SELECT: ProductFilterEqualSection,
|
23
|
+
MULTISELECT: ProductFilterEqualSection,
|
24
|
+
BOOLEAN: ProductFilterEqualSection,
|
25
|
+
PRICE: ProductFilterRangeSection,
|
23
26
|
}
|
24
27
|
|
25
|
-
export const productFiltersProChipRenderer = {
|
26
|
-
|
27
|
-
|
28
|
+
export const productFiltersProChipRenderer: Partial<FilterRenderer> = {
|
29
|
+
SELECT: ProductFilterEqualChip,
|
30
|
+
MULTISELECT: ProductFilterEqualChip,
|
31
|
+
BOOLEAN: ProductFilterEqualChip,
|
32
|
+
PRICE: ProductFilterRangeChip,
|
28
33
|
}
|
29
34
|
|
30
35
|
export function ProductFiltersProAggregations(props: ProductFiltersProAggregationsProps) {
|
@@ -36,7 +41,10 @@ export function ProductFiltersProAggregations(props: ProductFiltersProAggregatio
|
|
36
41
|
{excludeCategory(applyAggregationCount(aggregations, appliedAggregations, params)).map(
|
37
42
|
(aggregation) => {
|
38
43
|
const filterType = filterTypes[aggregation.attribute_code]
|
39
|
-
if (!filterType)
|
44
|
+
if (!filterType) {
|
45
|
+
console.log('Filter not recognized', aggregation.attribute_code, filterTypes)
|
46
|
+
return null
|
47
|
+
}
|
40
48
|
|
41
49
|
const Component = renderer?.[filterType]
|
42
50
|
if (!Component) {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { ChipMenuProps } from '@graphcommerce/next-ui'
|
2
|
-
import { FilterTypes } from '../ProductListItems/
|
2
|
+
import { FilterTypes } from '../ProductListItems/getFilterTypes'
|
3
3
|
import { FilterCheckboxType } from './FilterCheckboxType'
|
4
4
|
import { FilterEqualType } from './FilterEqualType'
|
5
5
|
import { FilterRangeType } from './FilterRangeType'
|
@@ -23,22 +23,16 @@ export function ProductListFilters(props: ProductFiltersProps) {
|
|
23
23
|
return null
|
24
24
|
|
25
25
|
switch (filterTypes[aggregation.attribute_code]) {
|
26
|
-
case '
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
{...aggregation}
|
37
|
-
{...chipMenuProps}
|
38
|
-
/>
|
39
|
-
)
|
40
|
-
}
|
41
|
-
|
26
|
+
case 'BOOLEAN':
|
27
|
+
return (
|
28
|
+
<FilterCheckboxType
|
29
|
+
key={aggregation.attribute_code}
|
30
|
+
{...aggregation}
|
31
|
+
{...chipMenuProps}
|
32
|
+
/>
|
33
|
+
)
|
34
|
+
case 'SELECT':
|
35
|
+
case 'MULTISELECT':
|
42
36
|
return (
|
43
37
|
<FilterEqualType
|
44
38
|
key={aggregation.attribute_code}
|
@@ -46,8 +40,7 @@ export function ProductListFilters(props: ProductFiltersProps) {
|
|
46
40
|
{...chipMenuProps}
|
47
41
|
/>
|
48
42
|
)
|
49
|
-
|
50
|
-
case 'FilterRangeTypeInput':
|
43
|
+
case 'PRICE':
|
51
44
|
return (
|
52
45
|
<FilterRangeType
|
53
46
|
key={aggregation.attribute_code}
|
@@ -56,6 +49,7 @@ export function ProductListFilters(props: ProductFiltersProps) {
|
|
56
49
|
/>
|
57
50
|
)
|
58
51
|
}
|
52
|
+
|
59
53
|
// console.log(
|
60
54
|
// 'Filter not recognized',
|
61
55
|
// aggregation.attribute_code,
|
@@ -67,8 +67,6 @@ export function isFilterTypeRange(filter: AnyFilterType): filter is FilterRangeT
|
|
67
67
|
)
|
68
68
|
}
|
69
69
|
|
70
|
-
export type FilterTypes = Partial<Record<string, string>>
|
71
|
-
|
72
70
|
export function toProductListParams(params: ProductFilterParams): ProductListParams {
|
73
71
|
const { sort, dir, filters, ...rest } = params
|
74
72
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import type {
|
2
2
|
FilterEqualTypeInput,
|
3
|
-
FilterMatchTypeInput,
|
4
3
|
FilterRangeTypeInput,
|
5
4
|
SortEnum,
|
6
5
|
} from '@graphcommerce/graphql-mesh'
|
7
|
-
import { useRouter } from 'next/router'
|
8
|
-
import { FilterTypes, ProductListParams } from './filterTypes'
|
9
6
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
10
7
|
import { equal } from '@wry/equality'
|
8
|
+
import { useRouter } from 'next/router'
|
9
|
+
import { ProductListParams } from './filterTypes'
|
10
|
+
import { FilterTypes } from './getFilterTypes'
|
11
11
|
|
12
12
|
export function parseParams(
|
13
13
|
url: string,
|
@@ -44,20 +44,20 @@ export function parseParams(
|
|
44
44
|
|
45
45
|
const [from, to] = value.split('-')
|
46
46
|
switch (typeMap[param]) {
|
47
|
-
case '
|
48
|
-
|
47
|
+
case 'BOOLEAN':
|
48
|
+
case 'SELECT':
|
49
|
+
case 'MULTISELECT':
|
50
|
+
categoryVariables.filters[param] = { in: value.split(',') } as FilterEqualTypeInput
|
49
51
|
return undefined
|
50
|
-
case '
|
52
|
+
case 'PRICE':
|
51
53
|
categoryVariables.filters[param] = {
|
52
54
|
...(from !== '*' && { from }),
|
53
55
|
...(to !== '*' && { to }),
|
54
56
|
} as FilterRangeTypeInput
|
55
57
|
return undefined
|
56
|
-
case 'FilterEqualTypeInput':
|
57
|
-
categoryVariables.filters[param] = { in: value.split(',') } as FilterEqualTypeInput
|
58
|
-
return undefined
|
59
58
|
}
|
60
59
|
|
60
|
+
// console.log('Filter not recognized', param, typeMap[param])
|
61
61
|
error = true
|
62
62
|
return undefined
|
63
63
|
}, undefined)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import { gql, ApolloClient, NormalizedCacheObject, TypedDocumentNode } from '@graphcommerce/graphql'
|
2
|
-
import type { Exact } from '@graphcommerce/graphql-mesh'
|
2
|
+
import type { AttributeFrontendInputEnum, Exact } from '@graphcommerce/graphql-mesh'
|
3
|
+
import { filterNonNullableKeys, nonNullable } from '@graphcommerce/next-ui'
|
4
|
+
import { ProductFilterTypesDocument } from './ProductFilterTypes.gql'
|
3
5
|
|
4
6
|
type FilterInputTypesQueryVariables = Exact<{ [key: string]: never }>
|
5
7
|
|
@@ -25,13 +27,40 @@ const FilterInputTypesDocument = gql`
|
|
25
27
|
}
|
26
28
|
` as TypedDocumentNode<FilterInputTypesQuery, FilterInputTypesQueryVariables>
|
27
29
|
|
30
|
+
export type FilterTypes = Partial<Record<string, AttributeFrontendInputEnum>>
|
31
|
+
|
28
32
|
export async function getFilterTypes(
|
29
33
|
client: ApolloClient<NormalizedCacheObject>,
|
30
|
-
|
34
|
+
isSearch: boolean = false,
|
35
|
+
): Promise<FilterTypes> {
|
36
|
+
if (import.meta.graphCommerce.magentoVersion >= 247) {
|
37
|
+
const types = await client.query({
|
38
|
+
query: ProductFilterTypesDocument,
|
39
|
+
variables: {
|
40
|
+
filters: isSearch ? { is_filterable_in_search: true } : {},
|
41
|
+
},
|
42
|
+
})
|
43
|
+
|
44
|
+
const typeMap: FilterTypes = Object.fromEntries(
|
45
|
+
filterNonNullableKeys(types.data.attributesList?.items, ['frontend_input'])
|
46
|
+
.map((i) => [i.code, i.frontend_input])
|
47
|
+
.filter(nonNullable),
|
48
|
+
)
|
49
|
+
|
50
|
+
return typeMap
|
51
|
+
}
|
52
|
+
|
31
53
|
const filterInputTypes = await client.query({ query: FilterInputTypesDocument })
|
32
54
|
|
33
|
-
const typeMap:
|
34
|
-
filterInputTypes.data?.__type.inputFields
|
55
|
+
const typeMap: FilterTypes = Object.fromEntries(
|
56
|
+
filterInputTypes.data?.__type.inputFields
|
57
|
+
.map<[string, AttributeFrontendInputEnum] | undefined>((field) => {
|
58
|
+
if (field.type.name === 'FilterEqualTypeInput') return [field.name, 'SELECT']
|
59
|
+
if (field.type.name === 'FilterRangeTypeInput') return [field.name, 'PRICE']
|
60
|
+
if (field.type.name === 'FilterMatchTypeInput') return [field.name, 'TEXT']
|
61
|
+
return undefined
|
62
|
+
})
|
63
|
+
.filter(nonNullable),
|
35
64
|
)
|
36
65
|
|
37
66
|
return typeMap
|
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.
|
5
|
+
"version": "9.0.0-canary.58",
|
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.
|
22
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.
|
23
|
-
"@graphcommerce/framer-next-pages": "^9.0.0-canary.
|
24
|
-
"@graphcommerce/framer-scroller": "^9.0.0-canary.
|
25
|
-
"@graphcommerce/graphql": "^9.0.0-canary.
|
26
|
-
"@graphcommerce/graphql-mesh": "^9.0.0-canary.
|
27
|
-
"@graphcommerce/image": "^9.0.0-canary.
|
28
|
-
"@graphcommerce/magento-cart": "^9.0.0-canary.
|
29
|
-
"@graphcommerce/magento-category": "^9.0.0-canary.
|
30
|
-
"@graphcommerce/magento-store": "^9.0.0-canary.
|
31
|
-
"@graphcommerce/next-ui": "^9.0.0-canary.
|
32
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.
|
33
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.
|
21
|
+
"@graphcommerce/ecommerce-ui": "^9.0.0-canary.58",
|
22
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.58",
|
23
|
+
"@graphcommerce/framer-next-pages": "^9.0.0-canary.58",
|
24
|
+
"@graphcommerce/framer-scroller": "^9.0.0-canary.58",
|
25
|
+
"@graphcommerce/graphql": "^9.0.0-canary.58",
|
26
|
+
"@graphcommerce/graphql-mesh": "^9.0.0-canary.58",
|
27
|
+
"@graphcommerce/image": "^9.0.0-canary.58",
|
28
|
+
"@graphcommerce/magento-cart": "^9.0.0-canary.58",
|
29
|
+
"@graphcommerce/magento-category": "^9.0.0-canary.58",
|
30
|
+
"@graphcommerce/magento-store": "^9.0.0-canary.58",
|
31
|
+
"@graphcommerce/next-ui": "^9.0.0-canary.58",
|
32
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.58",
|
33
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.58",
|
34
34
|
"@lingui/core": "^4.2.1",
|
35
35
|
"@lingui/macro": "^4.2.1",
|
36
36
|
"@lingui/react": "^4.2.1",
|