Skip to content

Commit a42ac15

Browse files
committed
refactor: on filters/sorting/pagination change only products will be reloaded
1 parent 9fc5a34 commit a42ac15

File tree

6 files changed

+321
-214
lines changed

6 files changed

+321
-214
lines changed

packages/theme/composables/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ export interface AgnosticSort {
236236
}
237237

238238
export interface AgnosticPagination {
239-
currentPage: number;
240-
totalPages: number;
241-
totalItems: number;
242-
itemsPerPage: number;
243-
pageOptions: number[];
239+
currentPage?: number;
240+
totalPages?: number;
241+
totalItems?: number;
242+
itemsPerPage?: number;
243+
pageOptions?: number[];
244244
}
245245

246246
export interface AgnosticAddress {

packages/theme/composables/useUiHelpers/index.ts

Lines changed: 132 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,55 +16,151 @@ const reduceFilters = (query) => (prev, curr: string) => {
1616
const useUiHelpers = () => {
1717
const route = useRoute();
1818
const router = useRouter();
19-
const { query } = route.value;
19+
let { query } = route.value;
2020

21-
const getFiltersDataFromUrl = (onlyFilters) => Object.keys(query)
22-
.filter((f) => (onlyFilters ? !nonFilters.has(f) : nonFilters.has(f)))
23-
// eslint-disable-next-line unicorn/prefer-object-from-entries
24-
.reduce(reduceFilters(query), {});
21+
const resolveQuery = () => {
22+
if (typeof window !== 'undefined') {
23+
query = router.resolve((window.location.pathname + window.location.search).slice(1)).route.query;
24+
}
2525

26-
const getFacetsFromURL = () => ({
27-
filters: getFiltersDataFromUrl(true),
28-
itemsPerPage: Number.parseInt(query.itemsPerPage as string, 10) || 10,
29-
page: Number.parseInt(query.page as string, 10) || 1,
30-
sort: query.sort as string || '',
31-
term: query.term as string,
32-
});
26+
return query;
27+
};
28+
29+
const getFiltersDataFromUrl = (onlyFilters = false) => {
30+
const currentQuery = resolveQuery();
31+
return Object.keys(currentQuery)
32+
.filter((f) => (onlyFilters ? !nonFilters.has(f) : f))
33+
// eslint-disable-next-line unicorn/prefer-object-from-entries
34+
.reduce(reduceFilters(currentQuery), {});
35+
};
36+
37+
const getFacetsFromURL = () => {
38+
const currentQuery = resolveQuery();
39+
40+
return {
41+
filters: getFiltersDataFromUrl(true),
42+
itemsPerPage: Number.parseInt(currentQuery.itemsPerPage as string, 10) || 10,
43+
page: Number.parseInt(currentQuery.page as string, 10) || 1,
44+
sort: currentQuery.sort as string || '',
45+
term: currentQuery.term as string,
46+
};
47+
};
3348

3449
const changeSearchTerm = (term: string) => term;
3550

36-
const getSearchTermFromUrl = () => ({
37-
page: Number.parseInt(query.page as string, 10) || 1,
38-
sort: query.sort || '',
39-
filters: getFiltersDataFromUrl(true),
40-
itemsPerPage: Number.parseInt(query.itemsPerPage as string, 10) || 10,
41-
term: query.term,
42-
});
51+
const getSearchTermFromUrl = () => {
52+
const currentQuery = resolveQuery();
53+
54+
return {
55+
page: Number.parseInt(currentQuery.page as string, 10) || 1,
56+
sort: currentQuery.sort || '',
57+
filters: getFiltersDataFromUrl(true),
58+
itemsPerPage: Number.parseInt(currentQuery.itemsPerPage as string, 10) || 10,
59+
term: currentQuery.term,
60+
};
61+
};
4362

4463
const getCatLink = (category: Category): string => `/c/${category.url_path}${category.url_suffix || ''}`;
4564

4665
const getAgnosticCatLink = (category: CategoryTreeInterface): string => `/c${category.slug}`;
4766

48-
const changeSorting = async (sort: string) => {
49-
await router.push({ query: { ...query, sort } });
67+
/**
68+
* Force push for a backward compatibility in other places, should be removed
69+
*
70+
* @param sort
71+
* @param forcePush
72+
*/
73+
const changeSorting = async (sort: string, forcePush = true) => {
74+
if (forcePush) {
75+
await router.push({ query: { ...query, sort } });
76+
} else {
77+
const routeData = router.resolve({
78+
query: {
79+
...getFiltersDataFromUrl(),
80+
sort,
81+
},
82+
});
83+
window.history.pushState(
84+
{},
85+
null,
86+
routeData.href,
87+
);
88+
}
5089
};
5190

52-
const changeFilters = async (filters: any) => {
53-
await router.push({
54-
query: {
55-
...getFiltersDataFromUrl(false),
56-
...filters,
57-
},
58-
});
91+
/**
92+
* Force push for a backward compatibility in other places, should be removed
93+
*
94+
* @param filters
95+
* @param forcePush
96+
*/
97+
const changeFilters = async (filters: any, forcePush = true) => {
98+
if (forcePush) {
99+
await router.push({
100+
query: {
101+
...getFiltersDataFromUrl(false),
102+
...filters,
103+
},
104+
});
105+
} else {
106+
const routeData = router.resolve({
107+
query: {
108+
...getFiltersDataFromUrl(),
109+
...filters,
110+
},
111+
});
112+
window.history.pushState(
113+
{},
114+
null,
115+
routeData.href,
116+
);
117+
}
59118
};
60119

61-
const changeItemsPerPage = async (itemsPerPage: number) => {
62-
await router.push({
63-
query: {
64-
...getFiltersDataFromUrl(false),
65-
itemsPerPage,
66-
},
67-
});
120+
const clearFilters = async (forcePush = true) => {
121+
if (forcePush) {
122+
await router.push({
123+
query: {},
124+
});
125+
} else {
126+
const routeData = router.resolve({
127+
query: {},
128+
});
129+
window.history.pushState(
130+
{},
131+
null,
132+
routeData.href,
133+
);
134+
}
135+
};
136+
137+
/**
138+
* Force push for a backward compatibility in other places, should be removed
139+
*
140+
* @param itemsPerPage
141+
* @param forcePush
142+
*/
143+
const changeItemsPerPage = async (itemsPerPage: number, forcePush = true) => {
144+
if (forcePush) {
145+
await router.push({
146+
query: {
147+
...getFiltersDataFromUrl(false),
148+
itemsPerPage,
149+
},
150+
});
151+
} else {
152+
const routeData = router.resolve({
153+
query: {
154+
...getFiltersDataFromUrl(),
155+
itemsPerPage,
156+
},
157+
});
158+
window.history.pushState(
159+
{},
160+
null,
161+
routeData.href,
162+
);
163+
}
68164
};
69165

70166
const setTermForUrl = async (term: string) => {
@@ -87,6 +183,7 @@ const useUiHelpers = () => {
87183
changeSorting,
88184
changeFilters,
89185
changeItemsPerPage,
186+
clearFilters,
90187
setTermForUrl,
91188
isFacetColor,
92189
isFacetCheckbox,

packages/theme/getters/types.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Country } from '~/modules/GraphQL/types';
22
import {
33
AgnosticAttribute, Countries, AgnosticPrice, AgnosticTotals,
44
AgnosticCoupon, AgnosticDiscount, AgnosticCategoryTree, AgnosticBreadcrumb,
5-
GroupedFacetInterface, AgnosticSort, AgnosticMediaGalleryItem,
5+
GroupedFacetInterface, AgnosticSort, AgnosticMediaGalleryItem, AgnosticPagination, AgnosticFacetSearchParams, FacetInterface,
66
} from '~/composables/types';
77

88
export interface AddressGetter {
@@ -64,7 +64,7 @@ export interface ForgotPasswordGetters<FORGOT_PASSWORD_RESULT> {
6464
}
6565

6666
export interface FacetsGetters<SEARCH_DATA, RESULTS, CRITERIA = any> {
67-
getAll: (searchData: FacetSearchResult<SEARCH_DATA>, criteria?: CRITERIA) => AgnosticFacet[];
67+
getAll: (searchData: FacetSearchResult<SEARCH_DATA>, criteria?: CRITERIA) => FacetInterface[];
6868
getGrouped: (searchData: FacetSearchResult<SEARCH_DATA>, criteria?: CRITERIA) => GroupedFacetInterface[];
6969
getCategoryTree: (searchData: FacetSearchResult<SEARCH_DATA>) => AgnosticCategoryTree;
7070
getSortOptions: (searchData: FacetSearchResult<SEARCH_DATA>) => AgnosticSort;

packages/theme/modules/catalog/category/components/filters/CategoryFilters.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export interface UseFiltersProviderInterface {
9595
}
9696
9797
export default defineComponent({
98-
name: 'CategoryFiltersSidebar',
98+
name: 'CategoryFilters',
9999
components: {
100100
SelectedFilters,
101101
CheckboxType: () => import('~/modules/catalog/category/components/filters/renderer/CheckboxType.vue'),
@@ -120,24 +120,28 @@ export default defineComponent({
120120
},
121121
},
122122
setup({ catUid }, { emit }) {
123-
const { changeFilters } = useUiHelpers();
123+
const { changeFilters, clearFilters } = useUiHelpers();
124124
const {
125125
selectedFilters, selectFilter, removeFilter, isFilterSelected,
126126
} = useFilters();
127127
128128
const doApplyFilters = () => {
129-
changeFilters(selectedFilters.value);
129+
changeFilters(selectedFilters.value, false);
130+
emit('reloadProducts');
130131
emit('close');
131132
};
132133
133134
const doRemoveFilter = ({ id, value }: { id: string, value: string }) => {
134135
removeFilter(id, value);
135-
changeFilters(selectedFilters.value);
136+
changeFilters(selectedFilters.value, false);
137+
emit('reloadProducts');
136138
emit('close');
137139
};
138140
139141
const doClearFilters = () => {
140-
changeFilters({});
142+
clearFilters(false);
143+
selectedFilters.value = {};
144+
emit('reloadProducts');
141145
emit('close');
142146
};
143147

packages/theme/modules/catalog/category/components/navbar/CategoryNavbar.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<SfSelect
2727
:value="sortBy.selected"
2828
class="navbar__select"
29-
@input="changeSorting"
29+
@input="doChangeSorting"
3030
>
3131
<SfSelectOption
3232
v-for="option in sortBy.options"
@@ -101,14 +101,18 @@ export default defineComponent({
101101
default: () => {},
102102
},
103103
},
104-
setup() {
104+
setup(_, { emit }) {
105105
const {
106106
toggleFilterSidebar, changeToCategoryListView, changeToCategoryGridView, isCategoryGridView,
107107
} = useUiState();
108108
const uiHelpers = useUiHelpers();
109-
109+
const doChangeSorting = (sort: string) => {
110+
uiHelpers.changeSorting(sort, false);
111+
emit('reloadProducts');
112+
};
110113
return {
111114
toggleFilterSidebar,
115+
doChangeSorting,
112116
...uiHelpers,
113117
changeToCategoryListView,
114118
changeToCategoryGridView,

0 commit comments

Comments
 (0)