@scayle/storefront-product-listing 2.0.0 → 2.0.2
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 +34 -11
- package/dist/index.d.mts +1 -2
- package/dist/index.mjs +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/composables/useAppliedFilters.js +9 -5
- package/dist/runtime/composables/useFiltersForListing.d.ts +1 -2
- package/dist/runtime/composables/useProductsForListing.d.ts +1 -2
- package/dist/runtime/rpc/methods/categories.js +4 -3
- package/dist/runtime/utils/filters.d.ts +3 -3
- package/dist/runtime/utils/filters.js +3 -3
- package/package.json +11 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @scayle/storefront-product-listing
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Refined `useAppliedFilters` to update the `appliedFilter` value only when query parameters beginning with the specified `filtersPrefix` change, preventing unnecessary updates of `appliedFilter` when unrelated query parameters are modified
|
|
8
|
+
|
|
9
|
+
**Before:**
|
|
10
|
+
|
|
11
|
+
Any change to query parameters, regardless of their name, such as `?someQueryParam=true`, would trigger a reactive update of `appliedFilter`.
|
|
12
|
+
|
|
13
|
+
**After:**
|
|
14
|
+
|
|
15
|
+
Only changes to query parameters that begin with the specified prefix (e.g., `filters`) will trigger an update. For example, only `?filters[someQueryParam]=true` will cause `appliedFilter` to update, while unrelated query parameters will be ignored.
|
|
16
|
+
|
|
17
|
+
## 2.0.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Resolved an issue where the `appliedFilter` in `useAppliedFilters` was updated on every route change even if the query didn't change.
|
|
22
|
+
|
|
23
|
+
This caused unnecessary updates in places where there is a reactive dependency on the `appliedFilter`.
|
|
24
|
+
The `appliedFilter` is now only updated when the query actually changes.
|
|
25
|
+
|
|
3
26
|
## 2.0.0
|
|
4
27
|
|
|
5
28
|
### Major Changes
|
|
@@ -9,14 +32,14 @@
|
|
|
9
32
|
**Before**
|
|
10
33
|
|
|
11
34
|
```ts
|
|
12
|
-
import { defaultSortingOptions } from
|
|
35
|
+
import { defaultSortingOptions } from '#storefront-product-listing'
|
|
13
36
|
const { sortLinks } = useProductListSort(useRoute(), {
|
|
14
37
|
sortingOptions: defaultSortingOptions,
|
|
15
|
-
})
|
|
38
|
+
})
|
|
16
39
|
```
|
|
17
40
|
|
|
18
41
|
```ts
|
|
19
|
-
const { sortLinks } = useProductListSort(useRoute())
|
|
42
|
+
const { sortLinks } = useProductListSort(useRoute())
|
|
20
43
|
```
|
|
21
44
|
|
|
22
45
|
(Both before approaches are equivalent.)
|
|
@@ -24,19 +47,19 @@
|
|
|
24
47
|
**After**
|
|
25
48
|
|
|
26
49
|
```ts
|
|
27
|
-
import { SORT_PRICE_ASC, SORT_PRICE_DESC } from
|
|
50
|
+
import { SORT_PRICE_ASC, SORT_PRICE_DESC } from '#storefront-product-listing'
|
|
28
51
|
const { sortLinks } = useProductListSort(useRoute(), {
|
|
29
52
|
sortingOptions: [
|
|
30
53
|
{
|
|
31
54
|
...SORT_PRICE_ASC,
|
|
32
|
-
label:
|
|
55
|
+
label: 'Price Ascending',
|
|
33
56
|
},
|
|
34
57
|
{
|
|
35
58
|
...SORT_PRICE_DESC,
|
|
36
|
-
label:
|
|
59
|
+
label: 'Price Descending',
|
|
37
60
|
},
|
|
38
61
|
],
|
|
39
|
-
})
|
|
62
|
+
})
|
|
40
63
|
```
|
|
41
64
|
|
|
42
65
|
- **BREAKING**: `useProductListingSeoData` now expects `isDefaultSortSelected` to be passed as the final parameter. This removes the internal dependency on `useProductListSort`. It is typed as `MaybeRefOrGetter<Boolean>` to support reactive usage.
|
|
@@ -44,12 +67,12 @@
|
|
|
44
67
|
**Before**
|
|
45
68
|
|
|
46
69
|
```ts
|
|
47
|
-
const route = useRoute()
|
|
70
|
+
const route = useRoute()
|
|
48
71
|
const { title, robots, canonicalLink, categoryBreadcrumbSchema } =
|
|
49
72
|
useProductListingSeoData(breadcrumbs, route, {
|
|
50
73
|
baseUrl: baseUrl,
|
|
51
74
|
fullPath: fullPath,
|
|
52
|
-
})
|
|
75
|
+
})
|
|
53
76
|
```
|
|
54
77
|
|
|
55
78
|
**After**
|
|
@@ -221,7 +244,7 @@
|
|
|
221
244
|
They can be used as follows:
|
|
222
245
|
|
|
223
246
|
```ts
|
|
224
|
-
import { filtersFactory } from
|
|
247
|
+
import { filtersFactory } from '@scayle/storefront-product-listing'
|
|
225
248
|
```
|
|
226
249
|
|
|
227
250
|
- Upgrade the `storefront-core` and `storefront-nuxt` packages to version 8 and update your implementation to reflect the changes in RPC composables:
|
|
@@ -252,7 +275,7 @@
|
|
|
252
275
|
### Patch Changes
|
|
253
276
|
|
|
254
277
|
- The `useProductsByCategory` composable now sets the trackSearchAnalyticsEvent parameter by default if the current page evaluates to `1` and the `appliedFilter.term` is not empty.
|
|
255
|
-
The default behavior can be
|
|
278
|
+
The default behavior can be overridden by passing `trackSearchAnalyticsEvent: false` as part of `ProductsByCategoryOptions.params`.
|
|
256
279
|
For more details, check the [SCAYLE Search Analytics section](https://scayle.dev/en/developer-guide/products/search#scayle-search-analytics) in the SCAYLE Resource Center.
|
|
257
280
|
|
|
258
281
|
## 0.4.1
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from '../dist/runtime/types/sort.js';
|
|
2
|
-
import { BreadcrumbItem } from '@scayle/storefront-nuxt';
|
|
2
|
+
import { BreadcrumbItem, FilterItemWithValues } from '@scayle/storefront-nuxt';
|
|
3
3
|
import { Factory } from 'fishery';
|
|
4
|
-
import { FilterItemWithValues } from '@scayle/storefront-api';
|
|
5
4
|
|
|
6
5
|
type RangeTuple = [start: number, end: number];
|
|
7
6
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from '../dist/runtime/types/sort.js';
|
|
2
2
|
import { Factory } from 'fishery';
|
|
3
|
-
import { FilterTypes } from '@scayle/storefront-
|
|
3
|
+
import { FilterTypes } from '@scayle/storefront-nuxt';
|
|
4
4
|
|
|
5
5
|
const breadcrumbsFactory = Factory.define(() => [
|
|
6
6
|
{ to: "/de/c/women/clothing/shirts-2045", value: "shirts" },
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addImportsDir } from '@nuxt/kit';
|
|
2
2
|
|
|
3
3
|
const PACKAGE_NAME = "@scayle/storefront-product-listing";
|
|
4
|
-
const PACKAGE_VERSION = "2.0.
|
|
4
|
+
const PACKAGE_VERSION = "2.0.2";
|
|
5
5
|
const module = defineNuxtModule({
|
|
6
6
|
meta: {
|
|
7
7
|
name: PACKAGE_NAME,
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { computed } from "vue";
|
|
1
|
+
import { computed, ref, watch } from "vue";
|
|
2
2
|
import { parseFilterDataFromRoute } from "../utils/filters.js";
|
|
3
3
|
export function useAppliedFilters(route, { filtersPrefix } = { filtersPrefix: "filters" }) {
|
|
4
|
-
const appliedFilter =
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const appliedFilter = ref({ attributes: [] });
|
|
5
|
+
const parsedFilterQuery = computed(
|
|
6
|
+
() => parseFilterDataFromRoute(route.query, filtersPrefix)
|
|
7
|
+
);
|
|
8
|
+
watch(() => JSON.stringify(parsedFilterQuery.value), () => {
|
|
9
|
+
appliedFilter.value = parsedFilterQuery.value;
|
|
10
|
+
}, { immediate: true });
|
|
7
11
|
const appliedFiltersCount = computed(() => {
|
|
8
12
|
let count = 0;
|
|
9
13
|
count += appliedFilter.value.attributes?.length ?? 0;
|
|
@@ -39,7 +43,7 @@ export function useAppliedFilters(route, { filtersPrefix } = { filtersPrefix: "f
|
|
|
39
43
|
return appliedFiltersCount.value > 0;
|
|
40
44
|
});
|
|
41
45
|
return {
|
|
42
|
-
appliedFilter,
|
|
46
|
+
appliedFilter: computed(() => appliedFilter.value),
|
|
43
47
|
appliedFiltersCount,
|
|
44
48
|
appliedAttributeValues,
|
|
45
49
|
appliedBooleanValues,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { FetchFiltersParams } from '@scayle/storefront-nuxt';
|
|
1
|
+
import type { FetchFiltersParams, FilterItemWithValues } from '@scayle/storefront-nuxt';
|
|
2
2
|
import { useFilters } from '@scayle/storefront-nuxt/composables';
|
|
3
3
|
import type { ComputedRef, Ref } from 'vue';
|
|
4
|
-
import type { FilterItemWithValues } from '@scayle/storefront-api';
|
|
5
4
|
export type FiltersForListingOptions = Partial<{
|
|
6
5
|
params: Ref<Omit<FetchFiltersParams, 'category'>>;
|
|
7
6
|
fetchingOptions: Partial<{
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { FetchProductsByCategoryParams, Product } from '@scayle/storefront-nuxt';
|
|
1
|
+
import type { FetchProductsByCategoryParams, Product, Pagination } from '@scayle/storefront-nuxt';
|
|
2
2
|
import type { Ref, ComputedRef } from 'vue';
|
|
3
3
|
import { useProducts } from '@scayle/storefront-nuxt/composables';
|
|
4
|
-
import type { Pagination } from '@scayle/storefront-api';
|
|
5
4
|
export type UseProductsForListingReturn = Pick<Awaited<ReturnType<typeof useProducts>>, 'error' | 'status'> & {
|
|
6
5
|
/** A computed array of products in the specified category. */
|
|
7
6
|
products: ComputedRef<Product[]>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ErrorResponse,
|
|
3
3
|
HttpStatusCode,
|
|
4
|
-
HttpStatusMessage
|
|
4
|
+
HttpStatusMessage,
|
|
5
|
+
defineRpcHandler
|
|
5
6
|
} from "@scayle/storefront-nuxt";
|
|
6
|
-
export const getAllShopCategoriesForId = async
|
|
7
|
+
export const getAllShopCategoriesForId = defineRpcHandler(async ({ id, properties }, context) => {
|
|
7
8
|
if (typeof id !== "number" || isNaN(id)) {
|
|
8
9
|
return new ErrorResponse(
|
|
9
10
|
HttpStatusCode.BAD_REQUEST,
|
|
@@ -43,4 +44,4 @@ export const getAllShopCategoriesForId = async function getAllShopCategoriesForI
|
|
|
43
44
|
// 12 hours
|
|
44
45
|
})();
|
|
45
46
|
return result;
|
|
46
|
-
};
|
|
47
|
+
});
|
|
@@ -2,14 +2,14 @@ import type { LocationQuery, RouteLocationNormalizedLoadedGeneric } from 'vue-ro
|
|
|
2
2
|
import type { CategoryFilter, ProductSearchQuery } from '@scayle/storefront-nuxt';
|
|
3
3
|
import type { RangeTuple } from '../..//index.js';
|
|
4
4
|
/**
|
|
5
|
-
* Parses filter data from a Vue Router
|
|
5
|
+
* Parses filter data from a Vue Router query object.
|
|
6
6
|
*
|
|
7
|
-
* @param
|
|
7
|
+
* @param query The query object.
|
|
8
8
|
* @param filtersPrefix The prefix used for filter query parameters.
|
|
9
9
|
*
|
|
10
10
|
* @returns An object representing the parsed product search query.
|
|
11
11
|
*/
|
|
12
|
-
export declare const parseFilterDataFromRoute: (
|
|
12
|
+
export declare const parseFilterDataFromRoute: (query: LocationQuery, filtersPrefix: string) => ProductSearchQuery;
|
|
13
13
|
/**
|
|
14
14
|
* Creates a new attribute filter query object.
|
|
15
15
|
*
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const getAttributeValues = (value) => {
|
|
2
2
|
return value.split(",").filter((v) => v !== "").map(Number).filter((v) => !isNaN(v));
|
|
3
3
|
};
|
|
4
|
-
export const parseFilterDataFromRoute = (
|
|
5
|
-
const queryKeys = Object.keys(
|
|
4
|
+
export const parseFilterDataFromRoute = (query, filtersPrefix) => {
|
|
5
|
+
const queryKeys = Object.keys(query);
|
|
6
6
|
const productSearchQuery = { attributes: [] };
|
|
7
7
|
queryKeys.forEach((queryKey) => {
|
|
8
|
-
const value =
|
|
8
|
+
const value = query[queryKey];
|
|
9
9
|
if (!queryKey.includes(filtersPrefix)) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-product-listing",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Collection of essential composables and utilities to work with product listing",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,9 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@nuxt/kit": ">=3.13.0",
|
|
36
|
-
"@scayle/storefront-core": "^8.0.0",
|
|
37
36
|
"@scayle/storefront-nuxt": "^8.0.0",
|
|
38
|
-
"@vue/test-utils": "^2.4.6",
|
|
39
37
|
"@vueuse/core": "^12.8.2 || ^13.0.0",
|
|
40
38
|
"fishery": "^2.2.3",
|
|
41
39
|
"vue-router": "^4.5.0",
|
|
@@ -43,31 +41,29 @@
|
|
|
43
41
|
},
|
|
44
42
|
"devDependencies": {
|
|
45
43
|
"@arethetypeswrong/cli": "0.18.2",
|
|
46
|
-
"@nuxt/kit": "3.
|
|
44
|
+
"@nuxt/kit": "3.17.7",
|
|
47
45
|
"@nuxt/module-builder": "1.0.1",
|
|
48
|
-
"@nuxt/schema": "3.
|
|
46
|
+
"@nuxt/schema": "3.17.7",
|
|
49
47
|
"@nuxt/test-utils": "3.19.2",
|
|
50
|
-
"@
|
|
51
|
-
"@scayle/storefront-api": "18.9.0",
|
|
52
|
-
"@scayle/storefront-nuxt": "8.32.1",
|
|
53
|
-
"@types/node": "22.15.34",
|
|
48
|
+
"@types/node": "22.16.5",
|
|
54
49
|
"@vitest/coverage-v8": "3.2.4",
|
|
55
|
-
"@
|
|
56
|
-
"@vueuse/core": "13.4.0",
|
|
50
|
+
"@vueuse/core": "13.5.0",
|
|
57
51
|
"dprint": "0.50.1",
|
|
58
52
|
"eslint-formatter-gitlab": "6.0.1",
|
|
59
|
-
"eslint": "9.
|
|
53
|
+
"eslint": "9.31.0",
|
|
60
54
|
"fishery": "2.3.1",
|
|
61
55
|
"happy-dom": "18.0.1",
|
|
62
|
-
"nuxt": "3.
|
|
56
|
+
"nuxt": "3.17.7",
|
|
63
57
|
"publint": "0.3.12",
|
|
64
58
|
"schema-dts": "1.1.5",
|
|
65
59
|
"typescript": "5.8.3",
|
|
66
60
|
"unbuild": "3.5.0",
|
|
67
61
|
"vitest": "3.2.4",
|
|
68
62
|
"vue-router": "4.5.1",
|
|
69
|
-
"vue-tsc": "
|
|
70
|
-
"vue": "3.5.17"
|
|
63
|
+
"vue-tsc": "3.0.3",
|
|
64
|
+
"vue": "3.5.17",
|
|
65
|
+
"@scayle/storefront-nuxt": "8.37.0",
|
|
66
|
+
"@scayle/eslint-config-storefront": "4.7.0"
|
|
71
67
|
},
|
|
72
68
|
"scripts": {
|
|
73
69
|
"build": "nuxt-module-build build",
|