From b6b51dc9239275d47fb39fafe7547cc59ffe3cbb Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Wed, 12 Oct 2022 07:11:59 +0200 Subject: [PATCH 1/6] Add Stock Status to Product Query block filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creates a new Tools Panel called “Product filters” where we can neatly organize our product specific settings. Eventually, this panel could be merged with the core “Filters” panel; however, at the time of this commit, this is impossible (see WordPress/gutenberg#43684 for a PoC). Also moved the “On Sale” setting under this newly created panel. --- assets/js/blocks/product-query/constants.ts | 17 ++- .../product-query/inspector-controls.tsx | 121 +++++++++++++++--- assets/js/blocks/product-query/types.ts | 27 ++-- assets/js/blocks/product-query/utils.tsx | 9 ++ 4 files changed, 136 insertions(+), 38 deletions(-) diff --git a/assets/js/blocks/product-query/constants.ts b/assets/js/blocks/product-query/constants.ts index 0ae12ff267d..691e7ee1782 100644 --- a/assets/js/blocks/product-query/constants.ts +++ b/assets/js/blocks/product-query/constants.ts @@ -1,22 +1,34 @@ /** * External dependencies */ +import { getSetting } from '@woocommerce/settings'; import type { InnerBlockTemplate } from '@wordpress/blocks'; /** * Internal dependencies */ import { QueryBlockAttributes } from './types'; +import { objectOmit } from './utils'; export const DEFAULT_CORE_ALLOWED_CONTROLS = [ 'order', 'taxQuery', 'search' ]; -export const ALL_PRODUCT_QUERY_CONTROLS = [ 'onSale' ]; +export const ALL_PRODUCT_QUERY_CONTROLS = [ 'onSale', 'stockStatus' ]; export const DEFAULT_ALLOWED_CONTROLS = [ ...DEFAULT_CORE_ALLOWED_CONTROLS, ...ALL_PRODUCT_QUERY_CONTROLS, ]; +export const STOCK_STATUS_OPTIONS = getSetting< Record< string, string > >( + 'stockStatusOptions', + [] +); + +const GLOBAL_HIDE_OUT_OF_STOCK = getSetting< boolean >( + 'hideOutOfStockItems', + false +); + export const QUERY_DEFAULT_ATTRIBUTES: QueryBlockAttributes = { allowControls: DEFAULT_ALLOWED_CONTROLS, displayLayout: { @@ -35,6 +47,9 @@ export const QUERY_DEFAULT_ATTRIBUTES: QueryBlockAttributes = { exclude: [], sticky: '', inherit: false, + __woocommerceStockStatus: GLOBAL_HIDE_OUT_OF_STOCK + ? Object.keys( objectOmit( STOCK_STATUS_OPTIONS, 'outofstock' ) ) + : Object.keys( STOCK_STATUS_OPTIONS ), }, }; diff --git a/assets/js/blocks/product-query/inspector-controls.tsx b/assets/js/blocks/product-query/inspector-controls.tsx index 56cfc24100a..89fd4eaf6c0 100644 --- a/assets/js/blocks/product-query/inspector-controls.tsx +++ b/assets/js/blocks/product-query/inspector-controls.tsx @@ -1,12 +1,19 @@ /** * External dependencies */ +import { ElementType } from 'react'; import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; -import { ToggleControl } from '@wordpress/components'; import { addFilter } from '@wordpress/hooks'; import { EditorBlock } from '@woocommerce/types'; -import { ElementType } from 'react'; +import { + FormTokenField, + ToggleControl, + // eslint-disable-next-line @wordpress/no-unsafe-wp-apis + __experimentalToolsPanel as ToolsPanel, + // eslint-disable-next-line @wordpress/no-unsafe-wp-apis + __experimentalToolsPanelItem as ToolsPanelItem, +} from '@wordpress/components'; /** * Internal dependencies @@ -17,36 +24,110 @@ import { setCustomQueryAttribute, useAllowedControls, } from './utils'; +import { STOCK_STATUS_OPTIONS } from './constants'; + +/** + * Gets the id of a specific stock status from its text label + * + * In theory, we could use a `saveTransform` function on the + * `FormFieldToken` component to do the conversion. However, plugins + * can add custom stock statii which don't conform to our naming + * conventions. + */ +function getStockStatusIdByLabel( statusLabel: FormTokenField.Value ) { + const label = + typeof statusLabel === 'string' ? statusLabel : statusLabel.value; + + return Object.entries( STOCK_STATUS_OPTIONS ).find( + ( [ , value ] ) => value === label + )?.[ 0 ]; +} export const INSPECTOR_CONTROLS = { - onSale: ( props: ProductQueryBlock ) => ( - { - setCustomQueryAttribute( props, { __woocommerceOnSale } ); - } } - /> - ), + onSale: ( props: ProductQueryBlock ) => { + const { query } = props.attributes; + + return ( + query.__woocommerceOnSale } + > + { + setCustomQueryAttribute( props, { + __woocommerceOnSale, + } ); + } } + /> + + ); + }, + stockStatus: ( props: ProductQueryBlock ) => { + const { query } = props.attributes; + + return ( + query.__woocommerceStockStatus } + > + { + const __woocommerceStockStatus = statusLabels + .map( getStockStatusIdByLabel ) + .filter( Boolean ) as string[]; + + setCustomQueryAttribute( props, { + __woocommerceStockStatus, + } ); + } } + suggestions={ Object.values( STOCK_STATUS_OPTIONS ) } + validateInput={ ( value: string ) => + Object.values( STOCK_STATUS_OPTIONS ).includes( value ) + } + value={ + query?.__woocommerceStockStatus?.map( + ( key ) => STOCK_STATUS_OPTIONS[ key ] + ) || [] + } + __experimentalExpandOnFocus={ true } + /> + + ); + }, }; export const withProductQueryControls = < T extends EditorBlock< T > >( BlockEdit: ElementType ) => ( props: ProductQueryBlock ) => { const allowedControls = useAllowedControls( props.attributes ); + return isWooQueryBlockVariation( props ) ? ( <> - { Object.entries( INSPECTOR_CONTROLS ).map( - ( [ key, Control ] ) => - allowedControls?.includes( key ) ? ( - - ) : null - ) } + + { Object.entries( INSPECTOR_CONTROLS ).map( + ( [ key, Control ] ) => + allowedControls?.includes( key ) ? ( + + ) : null + ) } + ) : ( diff --git a/assets/js/blocks/product-query/types.ts b/assets/js/blocks/product-query/types.ts index f311a3afdda..6ce0c7e3e58 100644 --- a/assets/js/blocks/product-query/types.ts +++ b/assets/js/blocks/product-query/types.ts @@ -3,6 +3,11 @@ */ import type { EditorBlock } from '@woocommerce/types'; +// The interface below disables the forbidden underscores +// naming convention because we are namespacing our +// custom attributes inside a core block. Prefixing with underscores +// will help signify our intentions. +/* eslint-disable @typescript-eslint/naming-convention */ export interface ProductQueryArguments { /** * Display only products on sale. @@ -27,27 +32,15 @@ export interface ProductQueryArguments { * ) * ``` */ - // Disabling naming convention because we are namespacing our - // custom attributes inside a core block. Prefixing with underscores - // will help signify our intentions. - // eslint-disable-next-line @typescript-eslint/naming-convention __woocommerceOnSale?: boolean; -} - -export type ProductQueryBlock = EditorBlock< QueryBlockAttributes >; - -export interface ProductQueryAttributes { /** - * An array of controls to disable in the inspector. - * - * @example `[ 'stockStatus' ]` will not render the dropdown for stock status. + * Filter products by their stock status. */ - disabledInspectorControls?: string[]; - /** - * Query attributes that define which products will be fetched. - */ - query?: ProductQueryArguments; + __woocommerceStockStatus?: string[]; } +/* eslint-enable */ + +export type ProductQueryBlock = EditorBlock< QueryBlockAttributes >; export interface QueryBlockAttributes { allowControls?: string[]; diff --git a/assets/js/blocks/product-query/utils.tsx b/assets/js/blocks/product-query/utils.tsx index 3fbade0fa47..9a764187dec 100644 --- a/assets/js/blocks/product-query/utils.tsx +++ b/assets/js/blocks/product-query/utils.tsx @@ -36,6 +36,15 @@ export function isWooQueryBlockVariation( block: ProductQueryBlock ) { ); } +/** + * Returns an object without a key. + */ +export function objectOmit< T, K extends keyof T >( obj: T, key: K ) { + const { [ key ]: omit, ...rest } = obj; + + return rest; +} + /** * Sets the new query arguments of a Product Query block * From a36029b2e7578e10a6fdae00788f0f6a6b4d1bfb Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Wed, 12 Oct 2022 08:56:20 +0200 Subject: [PATCH 2/6] Add `resetAll` callback for the new Tools Panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tools Panels come with a “Reset All” functionality, that's supposed to return all the settings to their original state. In our case, things are a bit more complicated, as the original state is dependant on the current variation, so it can't be hard-coded like it is on the core block. --- assets/js/blocks/product-query/constants.ts | 12 ++++- assets/js/blocks/product-query/index.tsx | 3 +- .../product-query/inspector-controls.tsx | 54 +++++++++++++++++-- assets/js/blocks/product-query/types.ts | 4 +- assets/js/blocks/product-query/utils.tsx | 14 ++--- .../variations/product-query.tsx | 3 +- .../variations/products-on-sale.tsx | 9 ++-- 7 files changed, 77 insertions(+), 22 deletions(-) diff --git a/assets/js/blocks/product-query/constants.ts b/assets/js/blocks/product-query/constants.ts index 691e7ee1782..a4d97fb13fd 100644 --- a/assets/js/blocks/product-query/constants.ts +++ b/assets/js/blocks/product-query/constants.ts @@ -8,7 +8,17 @@ import type { InnerBlockTemplate } from '@wordpress/blocks'; * Internal dependencies */ import { QueryBlockAttributes } from './types'; -import { objectOmit } from './utils'; + +/** + * Returns an object without a key. + */ +function objectOmit< T, K extends keyof T >( obj: T, key: K ) { + const { [ key ]: omit, ...rest } = obj; + + return rest; +} + +export const QUERY_LOOP_ID = 'core/query'; export const DEFAULT_CORE_ALLOWED_CONTROLS = [ 'order', 'taxQuery', 'search' ]; diff --git a/assets/js/blocks/product-query/index.tsx b/assets/js/blocks/product-query/index.tsx index dbdb98e2907..5a9da69d634 100644 --- a/assets/js/blocks/product-query/index.tsx +++ b/assets/js/blocks/product-query/index.tsx @@ -7,6 +7,7 @@ import { addFilter } from '@wordpress/hooks'; /** * Internal dependencies */ +import { QUERY_LOOP_ID } from './constants'; import './inspector-controls'; import './variations/product-query'; import './variations/products-on-sale'; @@ -15,7 +16,7 @@ function registerProductQueryVariationAttributes( props: Block, blockName: string ) { - if ( blockName === 'core/query' ) { + if ( blockName === QUERY_LOOP_ID ) { // Gracefully handle if settings.attributes is undefined. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -- We need this because `attributes` is marked as `readonly` diff --git a/assets/js/blocks/product-query/inspector-controls.tsx b/assets/js/blocks/product-query/inspector-controls.tsx index 89fd4eaf6c0..72a4b173c44 100644 --- a/assets/js/blocks/product-query/inspector-controls.tsx +++ b/assets/js/blocks/product-query/inspector-controls.tsx @@ -4,6 +4,7 @@ import { ElementType } from 'react'; import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; +import { useSelect } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { EditorBlock } from '@woocommerce/types'; import { @@ -18,13 +19,51 @@ import { /** * Internal dependencies */ -import { ProductQueryBlock } from './types'; +import { + ProductQueryArguments, + ProductQueryBlock, + QueryBlockAttributes, +} from './types'; import { isWooQueryBlockVariation, setCustomQueryAttribute, useAllowedControls, } from './utils'; -import { STOCK_STATUS_OPTIONS } from './constants'; +import { + ALL_PRODUCT_QUERY_CONTROLS, + QUERY_LOOP_ID, + STOCK_STATUS_OPTIONS, +} from './constants'; + +const NAMESPACED_CONTROLS = ALL_PRODUCT_QUERY_CONTROLS.map( + ( id ) => + `__woocommerce${ id[ 0 ].toUpperCase() }${ id.slice( + 1 + ) }` as keyof ProductQueryArguments +); + +function useDefaultWooQueryParamsForVariation( + variationName: string | undefined +): Partial< ProductQueryArguments > { + const variationAttributes: QueryBlockAttributes = useSelect( + ( select ) => + select( 'core/blocks' ) + .getBlockVariations( QUERY_LOOP_ID ) + .find( + ( variation: ProductQueryBlock ) => + variation.name === variationName + )?.attributes + ); + + return variationAttributes + ? Object.assign( + {}, + ...NAMESPACED_CONTROLS.map( ( key ) => ( { + [ key ]: variationAttributes.query[ key ], + } ) ) + ) + : {}; +} /** * Gets the id of a specific stock status from its text label @@ -109,6 +148,9 @@ export const withProductQueryControls = < T extends EditorBlock< T > >( BlockEdit: ElementType ) => ( props: ProductQueryBlock ) => { const allowedControls = useAllowedControls( props.attributes ); + const defaultWooQueryParams = useDefaultWooQueryParamsForVariation( + props.attributes.namespace + ); return isWooQueryBlockVariation( props ) ? ( <> @@ -120,6 +162,12 @@ export const withProductQueryControls = 'Product filters', 'woo-gutenberg-products-block' ) } + resetAll={ () => { + setCustomQueryAttribute( + props, + defaultWooQueryParams + ); + } } > { Object.entries( INSPECTOR_CONTROLS ).map( ( [ key, Control ] ) => @@ -135,4 +183,4 @@ export const withProductQueryControls = ); }; -addFilter( 'editor.BlockEdit', 'core/query', withProductQueryControls ); +addFilter( 'editor.BlockEdit', QUERY_LOOP_ID, withProductQueryControls ); diff --git a/assets/js/blocks/product-query/types.ts b/assets/js/blocks/product-query/types.ts index 6ce0c7e3e58..2aa3ef74f3e 100644 --- a/assets/js/blocks/product-query/types.ts +++ b/assets/js/blocks/product-query/types.ts @@ -42,6 +42,8 @@ export interface ProductQueryArguments { export type ProductQueryBlock = EditorBlock< QueryBlockAttributes >; +export type ProductQueryBlockQuery = QueryBlockQuery & ProductQueryArguments; + export interface QueryBlockAttributes { allowControls?: string[]; displayLayout?: { @@ -49,7 +51,7 @@ export interface QueryBlockAttributes { columns?: number; }; namespace?: string; - query: QueryBlockQuery & ProductQueryArguments; + query: ProductQueryBlockQuery; } export interface QueryBlockQuery { diff --git a/assets/js/blocks/product-query/utils.tsx b/assets/js/blocks/product-query/utils.tsx index 9a764187dec..343eb269bde 100644 --- a/assets/js/blocks/product-query/utils.tsx +++ b/assets/js/blocks/product-query/utils.tsx @@ -7,6 +7,7 @@ import { store as WP_BLOCKS_STORE } from '@wordpress/blocks'; /** * Internal dependencies */ +import { QUERY_LOOP_ID } from './constants'; import { ProductQueryArguments, ProductQueryBlock, @@ -29,22 +30,13 @@ export function ArrayXOR< T extends Array< unknown > >( a: T, b: T ) { */ export function isWooQueryBlockVariation( block: ProductQueryBlock ) { return ( - block.name === 'core/query' && + block.name === QUERY_LOOP_ID && Object.values( QueryVariation ).includes( block.attributes.namespace as QueryVariation ) ); } -/** - * Returns an object without a key. - */ -export function objectOmit< T, K extends keyof T >( obj: T, key: K ) { - const { [ key ]: omit, ...rest } = obj; - - return rest; -} - /** * Sets the new query arguments of a Product Query block * @@ -80,7 +72,7 @@ export function useAllowedControls( return useSelect( ( select ) => select( WP_BLOCKS_STORE ).getActiveBlockVariation( - 'core/query', + QUERY_LOOP_ID, attributes )?.allowControls, diff --git a/assets/js/blocks/product-query/variations/product-query.tsx b/assets/js/blocks/product-query/variations/product-query.tsx index 83c46240ef6..5018a3e5ef3 100644 --- a/assets/js/blocks/product-query/variations/product-query.tsx +++ b/assets/js/blocks/product-query/variations/product-query.tsx @@ -14,12 +14,13 @@ import { DEFAULT_ALLOWED_CONTROLS, INNER_BLOCKS_TEMPLATE, QUERY_DEFAULT_ATTRIBUTES, + QUERY_LOOP_ID, } from '../constants'; const VARIATION_NAME = 'woocommerce/product-query'; if ( isExperimentalBuild() ) { - registerBlockVariation( 'core/query', { + registerBlockVariation( QUERY_LOOP_ID, { name: VARIATION_NAME, title: __( 'Product Query', 'woo-gutenberg-products-block' ), isActive: ( blockAttributes ) => diff --git a/assets/js/blocks/product-query/variations/products-on-sale.tsx b/assets/js/blocks/product-query/variations/products-on-sale.tsx index 382cc31db8f..5c7ea294197 100644 --- a/assets/js/blocks/product-query/variations/products-on-sale.tsx +++ b/assets/js/blocks/product-query/variations/products-on-sale.tsx @@ -10,9 +10,10 @@ import { Icon, percent } from '@wordpress/icons'; * Internal dependencies */ import { - DEFAULT_CORE_ALLOWED_CONTROLS, + DEFAULT_ALLOWED_CONTROLS, INNER_BLOCKS_TEMPLATE, QUERY_DEFAULT_ATTRIBUTES, + QUERY_LOOP_ID, } from '../constants'; import { ArrayXOR } from '../utils'; @@ -20,7 +21,7 @@ const VARIATION_NAME = 'woocommerce/query-products-on-sale'; const DISABLED_INSPECTOR_CONTROLS = [ 'onSale' ]; if ( isExperimentalBuild() ) { - registerBlockVariation( 'core/query', { + registerBlockVariation( QUERY_LOOP_ID, { name: VARIATION_NAME, title: __( 'Products on Sale', 'woo-gutenberg-products-block' ), isActive: ( blockAttributes ) => @@ -46,8 +47,8 @@ if ( isExperimentalBuild() ) { // https://github.com/WordPress/gutenberg/pull/43632 // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - allowControls: ArrayXOR( - DEFAULT_CORE_ALLOWED_CONTROLS, + allowedControls: ArrayXOR( + DEFAULT_ALLOWED_CONTROLS, DISABLED_INSPECTOR_CONTROLS ), innerBlocks: INNER_BLOCKS_TEMPLATE, From f2014e08baa6a9bae4ea0a6292b0807cec162d01 Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Wed, 12 Oct 2022 09:25:09 +0200 Subject: [PATCH 3/6] Implement front-end of the stock status setting --- src/BlockTypes/ProductQuery.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/BlockTypes/ProductQuery.php b/src/BlockTypes/ProductQuery.php index 3f5dbc0e6a9..d16ec8213c0 100644 --- a/src/BlockTypes/ProductQuery.php +++ b/src/BlockTypes/ProductQuery.php @@ -134,6 +134,23 @@ private function get_on_sale_products_query() { ); } + /** + * Return a query for products depending on their stock status. + * + * @param array $stock_statii An array of acceptable stock statii. + * @return array + */ + private function get_stock_status_query( $stock_statii ) { + return array( + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'meta_query' => array( + 'key' => '_stock_status', + 'value' => array_merge( [ '' ], $stock_statii ), + 'compare' => 'IN', + ), + ); + } + /** * Set the query vars that are used by filter blocks. * @@ -161,9 +178,12 @@ private function get_queries_by_applied_filters() { * @return array */ private function get_queries_by_attributes( $parsed_block ) { - $on_sale_enabled = isset( $parsed_block['attrs']['query']['__woocommerceOnSale'] ) && true === $parsed_block['attrs']['query']['__woocommerceOnSale']; + $query = $parsed_block['attrs']['query']; + $on_sale_enabled = isset( $query['__woocommerceOnSale'] ) && true === $query['__woocommerceOnSale']; + return array( - 'on_sale' => ( $on_sale_enabled ? $this->get_on_sale_products_query() : array() ), + 'on_sale' => ( $on_sale_enabled ? $this->get_on_sale_products_query() : array() ), + 'stock_status' => $this->get_stock_status_query( $query['__woocommerceStockStatus'] ), ); } From b2b81c905a45f0591e34282477733420b0748a2f Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Thu, 13 Oct 2022 17:48:59 +0200 Subject: [PATCH 4/6] Fix in case query is not set --- src/BlockTypes/ProductQuery.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/BlockTypes/ProductQuery.php b/src/BlockTypes/ProductQuery.php index d16ec8213c0..6c341cdd9cb 100644 --- a/src/BlockTypes/ProductQuery.php +++ b/src/BlockTypes/ProductQuery.php @@ -119,7 +119,6 @@ function( $acc, $query ) { }, $common_query_values ); - } @@ -145,7 +144,7 @@ private function get_stock_status_query( $stock_statii ) { // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 'meta_query' => array( 'key' => '_stock_status', - 'value' => array_merge( [ '' ], $stock_statii ), + 'value' => (array) $stock_statii, 'compare' => 'IN', ), ); @@ -183,7 +182,7 @@ private function get_queries_by_attributes( $parsed_block ) { return array( 'on_sale' => ( $on_sale_enabled ? $this->get_on_sale_products_query() : array() ), - 'stock_status' => $this->get_stock_status_query( $query['__woocommerceStockStatus'] ), + 'stock_status' => isset( $query['__woocommerceStockStatus'] ) ? $this->get_stock_status_query( $query['__woocommerceStockStatus'] ) : array(), ); } From 7f7390be4bc5455c5604feb6b798c7d211840eed Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Thu, 13 Oct 2022 17:49:09 +0200 Subject: [PATCH 5/6] Update `allowedControl` API --- assets/js/blocks/product-query/utils.tsx | 2 +- assets/js/blocks/product-query/variations/product-query.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/product-query/utils.tsx b/assets/js/blocks/product-query/utils.tsx index 343eb269bde..f9c0a45bac0 100644 --- a/assets/js/blocks/product-query/utils.tsx +++ b/assets/js/blocks/product-query/utils.tsx @@ -74,7 +74,7 @@ export function useAllowedControls( select( WP_BLOCKS_STORE ).getActiveBlockVariation( QUERY_LOOP_ID, attributes - )?.allowControls, + )?.allowedControls, [ attributes ] ); diff --git a/assets/js/blocks/product-query/variations/product-query.tsx b/assets/js/blocks/product-query/variations/product-query.tsx index 5018a3e5ef3..a5b0f5a1a5e 100644 --- a/assets/js/blocks/product-query/variations/product-query.tsx +++ b/assets/js/blocks/product-query/variations/product-query.tsx @@ -41,7 +41,7 @@ if ( isExperimentalBuild() ) { // https://github.com/WordPress/gutenberg/pull/43632 // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - allowControls: DEFAULT_ALLOWED_CONTROLS, + allowedControls: DEFAULT_ALLOWED_CONTROLS, innerBlocks: INNER_BLOCKS_TEMPLATE, scope: [ 'block', 'inserter' ], } ); From 125575b5b7aed0aab5cce6c1e73e8ebfb7d9522d Mon Sep 17 00:00:00 2001 From: Lucio Giannotta Date: Thu, 13 Oct 2022 18:01:22 +0200 Subject: [PATCH 6/6] Update type docs --- assets/js/blocks/product-query/types.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/assets/js/blocks/product-query/types.ts b/assets/js/blocks/product-query/types.ts index 2aa3ef74f3e..e8f98eb38a0 100644 --- a/assets/js/blocks/product-query/types.ts +++ b/assets/js/blocks/product-query/types.ts @@ -35,6 +35,16 @@ export interface ProductQueryArguments { __woocommerceOnSale?: boolean; /** * Filter products by their stock status. + * + * Will generate the following `meta_query`: + * + * ``` + * array( + * 'key' => '_stock_status', + * 'value' => (array) $stock_statii, + * 'compare' => 'IN', + * ), + * ``` */ __woocommerceStockStatus?: string[]; }