Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX#PWA-3180 Layered navigation Options are still visible even when n… #4180

Merged
merged 13 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Object {
"availableSortMethods": null,
"categoryDescription": "Jewelry category",
"categoryName": "Jewelry",
"filterOptions": undefined,
"filters": null,
"items": Array [
null,
Expand All @@ -17,6 +18,7 @@ Object {
null,
null,
],
"setFilterOptions": [Function],
"totalCount": null,
"totalPagesFromData": null,
}
Expand All @@ -32,6 +34,7 @@ Object {
],
"categoryDescription": "Jewelry category",
"categoryName": "Jewelry",
"filterOptions": undefined,
"filters": Array [
Object {
"label": "Label",
Expand All @@ -47,6 +50,7 @@ Object {
"name": "Necklace",
},
],
"setFilterOptions": [Function],
"totalCount": 2,
"totalPagesFromData": 1,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ jest.mock('@apollo/client', () => {
};
});

const mockGetFiltersAttributeCode = {
data: {
products: {
aggregations: [
{
label: 'Label'
}
]
}
}
};

const mockProductFiltersByCategoryData = {
data: {
products: {
Expand Down Expand Up @@ -91,21 +103,22 @@ const mockCategoryData = {

const mockGetSortMethods = jest.fn();
const mockGetFilters = jest.fn();
const mockfilterData = jest.fn();

jest.mock('@magento/peregrine/lib/context/eventing', () => ({
useEventingContext: jest.fn().mockReturnValue([{}, { dispatch: jest.fn() }])
}));

const Component = props => {
const talonprops = useCategoryContent(props);

return <i {...talonprops} />;
};

useQuery.mockReturnValue({ data: mockCategoryData });
describe('useCategoryContent tests', () => {
it('returns the proper shape', () => {
useLazyQuery
.mockReturnValueOnce([mockfilterData, mockGetFiltersAttributeCode])
.mockReturnValueOnce([
mockGetFilters,
mockProductFiltersByCategoryData
Expand All @@ -124,6 +137,7 @@ describe('useCategoryContent tests', () => {

it('handles default category id', () => {
useLazyQuery
.mockReturnValueOnce([mockfilterData, mockGetFiltersAttributeCode])
.mockReturnValueOnce([
mockGetFilters,
mockProductFiltersByCategoryData
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { gql } from '@apollo/client';

export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
query getProductFiltersByCategory(
$categoryIdFilter: FilterEqualTypeInput!
) {
Expand All @@ -11,9 +11,8 @@ export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
attribute_code
options {
label
value
count
}
position
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { useLazyQuery, useQuery } from '@apollo/client';
import { useEffect, useState } from 'react';
import { useLazyQuery, useQuery, gql } from '@apollo/client';

import mergeOperations from '../../../util/shallowMerge';
import { useEventingContext } from '../../../context/eventing';
Expand Down Expand Up @@ -29,15 +29,98 @@ export const useCategoryContent = props => {
getCategoryAvailableSortMethodsQuery
} = operations;

const placeholderItems = Array.from({ length: pageSize }).fill(null);
const [
getFiltersAttributeCode,
{ data: filterAttributeData }
] = useLazyQuery(getProductFiltersByCategoryQuery, {
fetchPolicy: 'cache-and-network',
nextFetchPolicy: 'cache-first'
});

const [getFilters, { data: filterData }] = useLazyQuery(
getProductFiltersByCategoryQuery,
{
fetchPolicy: 'cache-and-network',
nextFetchPolicy: 'cache-first'
useEffect(() => {
if (categoryId) {
getFiltersAttributeCode({
variables: {
categoryIdFilter: {
eq: categoryId
}
}
});
}
);
}, [categoryId, getFiltersAttributeCode]);

const availableFilterData = filterAttributeData
? filterAttributeData.products?.aggregations
: null;
const availableFilters = availableFilterData
?.map(eachitem => eachitem.attribute_code)
?.sort();

// Function to generate the dynamic query based on filter parameters
const generateDynamicFiltersQuery = filterParams => {
const categoryUid = `category_uid:{eq:"${categoryId}"}`;
let filterConditions = Object.keys(filterParams)
.map(key => {
const condition = Array.isArray(filterParams[key])
? 'in'
: 'eq';
const value = Array.isArray(filterParams[key])
? JSON.stringify(filterParams[key])
: `"${filterParams[key]}"`;
return `${key}:{${condition}:${value}}`;
})
.join(',');

filterConditions = [categoryUid, filterConditions].join(',');

return gql`
query getProductFiltersByCategory{
products(
filter: {
${filterConditions}
}
) {
aggregations {
label
attribute_code
count
options {
label
value
count
}
}
}
}
`;
};

const [filterOptions, setFilterOptions] = useState();

const selectedFilters = {};

if (filterOptions) {
for (const [group, items] of filterOptions) {
availableFilters?.map(eachitem => {
if (eachitem === group && eachitem !== 'price') {
const sampleArray = [];
for (const item of items) {
sampleArray.push(item.value);
}
selectedFilters[group] = sampleArray;
}
});
}
}

const dynamicQuery = generateDynamicFiltersQuery(selectedFilters);

const placeholderItems = Array.from({ length: pageSize }).fill(null);

const [getFilters, { data: filterData }] = useLazyQuery(dynamicQuery, {
fetchPolicy: 'cache-and-network',
nextFetchPolicy: 'cache-first'
});

const [getSortMethods, { data: sortData }] = useLazyQuery(
getCategoryAvailableSortMethodsQuery,
Expand All @@ -58,20 +141,13 @@ export const useCategoryContent = props => {
}
}
);

const [, { dispatch }] = useEventingContext();

useEffect(() => {
if (categoryId) {
getFilters({
variables: {
categoryIdFilter: {
eq: categoryId
}
}
});
getFilters();
}
}, [categoryId, getFilters]);
}, [categoryId, filterOptions, getFilters]);

useEffect(() => {
if (categoryId) {
Expand All @@ -85,7 +161,7 @@ export const useCategoryContent = props => {
}
}, [categoryId, getSortMethods]);

const filters = filterData ? filterData.products.aggregations : null;
const filters = filterData ? filterData.products?.aggregations : null;
const items = data ? data.products.items : placeholderItems;
const totalPagesFromData = data
? data.products.page_info.total_pages
Expand Down Expand Up @@ -122,6 +198,8 @@ export const useCategoryContent = props => {
categoryName,
categoryDescription,
filters,
filterOptions,
setFilterOptions,
items,
totalCount,
totalPagesFromData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const CategoryContent = props => {
categoryName,
categoryDescription,
filters,
setFilterOptions,
items,
totalCount,
totalPagesFromData
Expand Down Expand Up @@ -79,7 +80,7 @@ const CategoryContent = props => {
) : null;

const sidebar = shouldShowFilterButtons ? (
<FilterSidebar filters={filters} />
<FilterSidebar filters={filters} setFilterOptions={setFilterOptions} />
) : shouldShowFilterShimmer ? (
<FilterSidebarShimmer />
) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const mockHandleApply = jest.fn();

const mockScrollTo = jest.fn();

const mockFilterOptions = jest.fn();

const mockGetBoundingClientRect = jest.fn();

let mockFilterState;
Expand Down Expand Up @@ -125,21 +127,24 @@ const Component = () => {

const givenDefaultValues = () => {
inputProps = {
filters: []
filters: [],
setFilterOptions: mockFilterOptions
};

mockFilterState = new Map();
};

const givenFilters = () => {
inputProps = {
filters: mockFilters
filters: mockFilters,
setFilterOptions: mockFilterOptions
};
};

const givenSelectedFilters = () => {
inputProps = {
filters: mockFilters
filters: mockFilters,
setFilterOptions: mockFilterOptions
};

mockFilterState = new Map([['group', 'item']]);
Expand All @@ -148,7 +153,8 @@ const givenSelectedFilters = () => {
const givenFiltersAndAmountToShow = () => {
inputProps = {
filters: mockFilters,
filterCountToOpen: mockFiltersOpenCount
filterCountToOpen: mockFiltersOpenCount,
setFilterOptions: mockFilterOptions
};
};

Expand Down
10 changes: 8 additions & 2 deletions packages/venia-ui/lib/components/FilterSidebar/filterSidebar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useCallback, useRef } from 'react';
import React, { useMemo, useCallback, useRef, useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
import { array, arrayOf, shape, string, number } from 'prop-types';
import { useFilterSidebar } from '@magento/peregrine/lib/talons/FilterSidebar';
Expand All @@ -17,7 +17,7 @@ const SCROLL_OFFSET = 150;
* @param {Object} props.filters - filters to display
*/
const FilterSidebar = props => {
const { filters, filterCountToOpen } = props;
const { filters, filterCountToOpen, setFilterOptions } = props;
const talonProps = useFilterSidebar({ filters });
const {
filterApi,
Expand Down Expand Up @@ -50,6 +50,12 @@ const FilterSidebar = props => {
[handleApply, filterRef]
);

useEffect(() => {
if (filterState) {
setFilterOptions(filterState);
}
}, [filterState, setFilterOptions]);

const filtersList = useMemo(
() =>
Array.from(filterItems, ([group, items], iteration) => {
Expand Down