diff --git a/packages/js/data/changelog/add-39125 b/packages/js/data/changelog/add-39125 new file mode 100644 index 00000000000..7da3d857f7b --- /dev/null +++ b/packages/js/data/changelog/add-39125 @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Add catalog_visibility property to the Product type diff --git a/packages/js/data/src/products/types.ts b/packages/js/data/src/products/types.ts index 42ca8bbc6dd..ad30ac27c70 100644 --- a/packages/js/data/src/products/types.ts +++ b/packages/js/data/src/products/types.ts @@ -42,6 +42,12 @@ export type ProductDimensions = { length: string; }; +export type ProductCatalogVisibility = + | 'visible' + | 'catalog' + | 'search' + | 'hidden'; + export type Product< Status = ProductStatus, Type = ProductType > = Omit< Schema.Post, 'status' | 'categories' @@ -53,6 +59,7 @@ export type Product< Status = ProductStatus, Type = ProductType > = Omit< backorders_allowed: boolean; button_text: string; categories: Pick< ProductCategory, 'id' | 'name' | 'slug' >[]; + catalog_visibility: ProductCatalogVisibility; date_created: string; date_created_gmt: string; date_modified: string; diff --git a/packages/js/product-editor/changelog/add-39125 b/packages/js/product-editor/changelog/add-39125 new file mode 100644 index 00000000000..c9974074015 --- /dev/null +++ b/packages/js/product-editor/changelog/add-39125 @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Create product search and catalog visibility blocks diff --git a/packages/js/product-editor/src/blocks/catalog-visibility/block.json b/packages/js/product-editor/src/blocks/catalog-visibility/block.json new file mode 100644 index 00000000000..987aeb070b6 --- /dev/null +++ b/packages/js/product-editor/src/blocks/catalog-visibility/block.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "woocommerce/product-catalog-visibility-field", + "description": "A checkbox to manage the catalog visibility of the product.", + "title": "Product catalog visibility", + "category": "widgets", + "keywords": [ "products", "catalog" ], + "textdomain": "default", + "attributes": { + "label": { + "type": "string", + "__experimentalRole": "content" + }, + "visibilty": { + "type": "string", + "enum": [ "visible", "catalog", "search", "hidden" ], + "default": "visible" + } + }, + "supports": { + "align": false, + "html": false, + "multiple": false, + "reusable": false, + "inserter": false, + "lock": false, + "__experimentalToolbar": false + }, + "editorStyle": "file:./editor.css" +} diff --git a/packages/js/product-editor/src/blocks/catalog-visibility/edit.tsx b/packages/js/product-editor/src/blocks/catalog-visibility/edit.tsx new file mode 100644 index 00000000000..c9181d83cc0 --- /dev/null +++ b/packages/js/product-editor/src/blocks/catalog-visibility/edit.tsx @@ -0,0 +1,63 @@ +/** + * External dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; +import { CheckboxControl } from '@wordpress/components'; +import { useEntityProp } from '@wordpress/core-data'; +import { createElement } from '@wordpress/element'; +import { Product } from '@woocommerce/data'; + +/** + * Internal dependencies + */ +import { CatalogVisibilityBlockAttributes } from './types'; + +export function Edit( { + attributes, +}: { + attributes: CatalogVisibilityBlockAttributes; +} ) { + const { label, visibilty } = attributes; + + const blockProps = useBlockProps(); + + const [ catalogVisibility, setCatalogVisibility ] = useEntityProp< + Product[ 'catalog_visibility' ] + >( 'postType', 'product', 'catalog_visibility' ); + + const checked = + catalogVisibility === visibilty || catalogVisibility === 'hidden'; + + function handleChange( selected: boolean ) { + if ( selected ) { + if ( catalogVisibility === 'visible' ) { + setCatalogVisibility( visibilty ); + return; + } + setCatalogVisibility( 'hidden' ); + } else { + if ( catalogVisibility === 'hidden' ) { + if ( visibilty === 'catalog' ) { + setCatalogVisibility( 'search' ); + return; + } + if ( visibilty === 'search' ) { + setCatalogVisibility( 'catalog' ); + return; + } + return; + } + setCatalogVisibility( 'visible' ); + } + } + + return ( +
+ +
+ ); +} diff --git a/packages/js/product-editor/src/blocks/catalog-visibility/index.ts b/packages/js/product-editor/src/blocks/catalog-visibility/index.ts new file mode 100644 index 00000000000..276ba069731 --- /dev/null +++ b/packages/js/product-editor/src/blocks/catalog-visibility/index.ts @@ -0,0 +1,28 @@ +/** + * External dependencies + */ +import { BlockConfiguration } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { initBlock } from '../../utils/init-blocks'; +import blockConfiguration from './block.json'; +import { Edit } from './edit'; +import { CatalogVisibilityBlockAttributes } from './types'; + +const { name, ...metadata } = + blockConfiguration as BlockConfiguration< CatalogVisibilityBlockAttributes >; + +export { metadata, name }; + +export const settings: Partial< + BlockConfiguration< CatalogVisibilityBlockAttributes > +> = { + example: {}, + edit: Edit, +}; + +export function init() { + return initBlock( { name, metadata, settings } ); +} diff --git a/packages/js/product-editor/src/blocks/catalog-visibility/types.ts b/packages/js/product-editor/src/blocks/catalog-visibility/types.ts new file mode 100644 index 00000000000..26b3f55e82b --- /dev/null +++ b/packages/js/product-editor/src/blocks/catalog-visibility/types.ts @@ -0,0 +1,10 @@ +/** + * External dependencies + */ +import { Product } from '@woocommerce/data'; +import { BlockAttributes } from '@wordpress/blocks'; + +export interface CatalogVisibilityBlockAttributes extends BlockAttributes { + label: string; + visibilty: Product[ 'catalog_visibility' ]; +} diff --git a/packages/js/product-editor/src/blocks/index.ts b/packages/js/product-editor/src/blocks/index.ts index 65e4a9d940b..72691311569 100644 --- a/packages/js/product-editor/src/blocks/index.ts +++ b/packages/js/product-editor/src/blocks/index.ts @@ -1,3 +1,4 @@ +export { init as initCatalogVisibility } from './catalog-visibility'; export { init as initCategory } from './category'; export { init as initCheckbox } from './checkbox'; export { init as initCollapsible } from './collapsible'; diff --git a/plugins/woocommerce/changelog/add-39125 b/plugins/woocommerce/changelog/add-39125 new file mode 100644 index 00000000000..91bba4e1a49 --- /dev/null +++ b/plugins/woocommerce/changelog/add-39125 @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Register product catalog and search visibility blocks diff --git a/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/BlockRegistry.php b/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/BlockRegistry.php index c3e5a3d3d56..246969f4bbc 100644 --- a/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/BlockRegistry.php +++ b/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/BlockRegistry.php @@ -21,6 +21,7 @@ class BlockRegistry { */ const PRODUCT_BLOCKS = [ 'woocommerce/conditional', + 'woocommerce/product-catalog-visibility-field', 'woocommerce/product-category-field', 'woocommerce/product-checkbox-field', 'woocommerce/product-collapsible', diff --git a/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/Init.php b/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/Init.php index 30e4619cd93..8afee4a76ce 100644 --- a/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/Init.php +++ b/plugins/woocommerce/src/Admin/Features/ProductBlockEditor/Init.php @@ -370,6 +370,20 @@ class Init { 'name' => 'categories', ), ), + array( + 'woocommerce/product-catalog-visibility-field', + array( + 'label' => __( 'Hide in product catalog', 'woocommerce' ), + 'visibilty' => 'search', + ), + ), + array( + 'woocommerce/product-catalog-visibility-field', + array( + 'label' => __( 'Hide from search results', 'woocommerce' ), + 'visibilty' => 'catalog', + ), + ), array( 'woocommerce/product-checkbox-field', array(