Data: add selector to get related products (#43489)
* add getRelatedProducts to get related products * changelog * add a resolver to pull the related products * minor jsdoc enhancement * query Product params should be optional * fix ES issue * minor TS enhancement * use createSelector() helper
This commit is contained in:
parent
ac43fb2426
commit
d0d056c60e
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: add
|
||||
|
||||
Data: add selector to get related products
|
|
@ -80,9 +80,11 @@ export const getItems = createSelector(
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( query && query._fields ) {
|
||||
if ( query && typeof query._fields !== 'undefined' ) {
|
||||
const fields = query._fields;
|
||||
|
||||
return ids.map( ( id: IdType ) => {
|
||||
return query._fields.reduce(
|
||||
return fields.reduce(
|
||||
( item: Partial< Item >, field: string ) => {
|
||||
return {
|
||||
...item,
|
||||
|
|
|
@ -20,9 +20,11 @@ export const getOrders = createSelector(
|
|||
if ( ! ids ) {
|
||||
return defaultValue;
|
||||
}
|
||||
if ( query._fields ) {
|
||||
if ( query && typeof query._fields !== 'undefined' ) {
|
||||
const fields = query._fields;
|
||||
|
||||
return ids.map( ( id ) => {
|
||||
return query._fields.reduce(
|
||||
return fields.reduce(
|
||||
( product: PartialOrder, field: keyof PartialOrder ) => {
|
||||
return {
|
||||
...product,
|
||||
|
|
|
@ -78,6 +78,36 @@ export function* getProduct( productId: number ) {
|
|||
}
|
||||
}
|
||||
|
||||
export function* getRelatedProducts( productId: number ) {
|
||||
try {
|
||||
// Get the product.
|
||||
const product: Product = yield resolveSelect(
|
||||
STORE_NAME,
|
||||
'getProduct',
|
||||
productId
|
||||
);
|
||||
|
||||
// Pick the related products IDs.
|
||||
const relatedProductsIds = product.related_ids;
|
||||
if ( ! relatedProductsIds?.length ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get the related products.
|
||||
const relatedProducts: Product[] = yield resolveSelect(
|
||||
STORE_NAME,
|
||||
'getProducts',
|
||||
{
|
||||
include: relatedProductsIds,
|
||||
}
|
||||
);
|
||||
|
||||
return relatedProducts;
|
||||
} catch ( error ) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function* getProductsTotalCount( query: Partial< ProductQuery > ) {
|
||||
try {
|
||||
const totalsQuery = {
|
||||
|
|
|
@ -33,9 +33,11 @@ export const getProducts = createSelector(
|
|||
if ( ! ids ) {
|
||||
return defaultValue;
|
||||
}
|
||||
if ( query._fields ) {
|
||||
if ( query && typeof query._fields !== 'undefined' ) {
|
||||
const fields = query._fields;
|
||||
|
||||
return ids.map( ( id ) => {
|
||||
return query._fields.reduce(
|
||||
return fields.reduce(
|
||||
(
|
||||
product: PartialProduct,
|
||||
field: keyof PartialProduct
|
||||
|
@ -145,6 +147,31 @@ export const getPermalinkParts = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns an array of related products for a given product ID.
|
||||
*
|
||||
* @param {ProductState} state - The current state.
|
||||
* @param {number} productId - The product ID.
|
||||
* @return {PartialProduct[]} The related products.
|
||||
*/
|
||||
export const getRelatedProducts = createSelector(
|
||||
( state: ProductState, productId: number ): PartialProduct[] => {
|
||||
const product = state.data[ productId ];
|
||||
if ( ! product?.related_ids ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const relatedProducts = getProducts( state, {
|
||||
include: product.related_ids,
|
||||
} );
|
||||
|
||||
return relatedProducts || [];
|
||||
},
|
||||
( state, productId ) => {
|
||||
return [ state.data[ productId ] ];
|
||||
}
|
||||
);
|
||||
|
||||
export type ProductsSelectors = {
|
||||
getCreateProductError: WPDataSelector< typeof getCreateProductError >;
|
||||
getProduct: WPDataSelector< typeof getProduct >;
|
||||
|
@ -153,4 +180,5 @@ export type ProductsSelectors = {
|
|||
getProductsError: WPDataSelector< typeof getProductsError >;
|
||||
isPending: WPDataSelector< typeof isPending >;
|
||||
getPermalinkParts: WPDataSelector< typeof getPermalinkParts >;
|
||||
getRelatedProducts: WPDataSelector< typeof getRelatedProducts >;
|
||||
} & WPDataSelectors;
|
||||
|
|
|
@ -170,7 +170,7 @@ export type ProductQuery<
|
|||
Status = ProductStatus,
|
||||
Type = ProductType
|
||||
> = BaseQueryParams< keyof Product > & {
|
||||
orderby:
|
||||
orderby?:
|
||||
| 'date'
|
||||
| 'id'
|
||||
| 'include'
|
||||
|
@ -179,19 +179,19 @@ export type ProductQuery<
|
|||
| 'price'
|
||||
| 'popularity'
|
||||
| 'rating';
|
||||
slug: string;
|
||||
status: Status;
|
||||
type: Type;
|
||||
sku: string;
|
||||
featured: boolean;
|
||||
category: string;
|
||||
tag: string;
|
||||
shipping_class: string;
|
||||
attribute: string;
|
||||
attribute_term: string;
|
||||
tax_class: 'standard' | 'reduced-rate' | 'zero-rate';
|
||||
on_sale: boolean;
|
||||
min_price: string;
|
||||
max_price: string;
|
||||
stock_status: 'instock' | 'outofstock' | 'onbackorder';
|
||||
slug?: string;
|
||||
status?: Status;
|
||||
type?: Type;
|
||||
sku?: string;
|
||||
featured?: boolean;
|
||||
category?: string;
|
||||
tag?: string;
|
||||
shipping_class?: string;
|
||||
attribute?: string;
|
||||
attribute_term?: string;
|
||||
tax_class?: 'standard' | 'reduced-rate' | 'zero-rate';
|
||||
on_sale?: boolean;
|
||||
min_price?: string;
|
||||
max_price?: string;
|
||||
stock_status?: 'instock' | 'outofstock' | 'onbackorder';
|
||||
};
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
export type BaseQueryParams< Fields = string > = {
|
||||
context: string;
|
||||
page: number;
|
||||
per_page: number;
|
||||
search: string;
|
||||
after: string;
|
||||
before: string;
|
||||
exclude: string;
|
||||
include: string;
|
||||
offset: number;
|
||||
order: 'asc' | 'desc';
|
||||
orderby: 'date' | 'id' | 'include' | 'title' | 'slug';
|
||||
parent: number[];
|
||||
parent_exclude: number[];
|
||||
_fields: Fields[];
|
||||
context?: string;
|
||||
page?: number;
|
||||
per_page?: number;
|
||||
search?: string;
|
||||
after?: string;
|
||||
before?: string;
|
||||
exclude?: string;
|
||||
include?: string | number[];
|
||||
offset?: number;
|
||||
order?: 'asc' | 'desc';
|
||||
orderby?: 'date' | 'id' | 'include' | 'title' | 'slug';
|
||||
parent?: number[];
|
||||
parent_exclude?: number[];
|
||||
_fields?: Fields[];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue