Product Form Template: populate the template selector control with the PFTs (#48327)

* switch setting templates order

* pull product_form from the entity store

* fix typo

* set post excerpt with template description

* update the description for the Simple template

* rename type for product form post

* introduce isProductFormTemplateEnabled() helper

* render the PFTs into the templates selector

* changelog

* tscripting

* remopve dropdown

* re-write changelog files

* change and rename isProductFormTemplateSystemEnabled

* remove unused component

* try change the template version name
This commit is contained in:
Damián Suárez 2024-06-13 13:55:07 +01:00 committed by GitHub
parent 7352c7270a
commit 6328ffdfb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 62 additions and 46 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
Product Block Editor: populate the template selector with the product form templates

View File

@ -39,10 +39,12 @@ import {
} from '../../../utils/get-product-error-message'; } from '../../../utils/get-product-error-message';
import type { import type {
ProductEditorBlockEditProps, ProductEditorBlockEditProps,
ProductFormPostProps,
ProductTemplate, ProductTemplate,
} from '../../../types'; } from '../../../types';
import { ProductDetailsSectionDescriptionBlockAttributes } from './types'; import { ProductDetailsSectionDescriptionBlockAttributes } from './types';
import * as wooIcons from '../../../icons'; import * as wooIcons from '../../../icons';
import isProductFormTemplateSystemEnabled from '../../../utils/is-product-form-template-system-enabled';
export function ProductDetailsSectionDescriptionBlockEdit( { export function ProductDetailsSectionDescriptionBlockEdit( {
attributes, attributes,
@ -93,6 +95,20 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
const [ unsupportedProductTemplate, setUnsupportedProductTemplate ] = const [ unsupportedProductTemplate, setUnsupportedProductTemplate ] =
useState< ProductTemplate >(); useState< ProductTemplate >();
// Pull the product templates from the store.
const productFormPosts = useSelect( ( sel ) => {
// Do not fetch product form posts if the feature is not enabled.
if ( ! isProductFormTemplateSystemEnabled() ) {
return [];
}
return (
sel( 'core' ).getEntityRecords( 'postType', 'product_form', {
per_page: -1,
} ) || []
);
}, [] ) as ProductFormPostProps[];
const { isSaving } = useSelect( const { isSaving } = useSelect(
( select ) => { ( select ) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@ -189,6 +205,12 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
return <Icon icon={ icon } size={ 24 } />; return <Icon icon={ icon } size={ 24 } />;
} }
/**
* Returns a function that renders a MenuItem component.
*
* @param {Function} onClose - Function to close the dropdown.
* @return {Function} Function that renders a MenuItem component.
*/
function getMenuItem( onClose: () => void ) { function getMenuItem( onClose: () => void ) {
return function renderMenuItem( productTemplate: ProductTemplate ) { return function renderMenuItem( productTemplate: ProductTemplate ) {
const isSelected = const isSelected =
@ -278,7 +300,7 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
} }
} }
function toogleButtonClickHandler( isOpen: boolean, onToggle: () => void ) { function toggleButtonClickHandler( isOpen: boolean, onToggle: () => void ) {
return function onClick() { return function onClick() {
onToggle(); onToggle();
@ -326,7 +348,7 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
<Button <Button
aria-expanded={ isOpen } aria-expanded={ isOpen }
variant="link" variant="link"
onClick={ toogleButtonClickHandler( onClick={ toggleButtonClickHandler(
isOpen, isOpen,
onToggle onToggle
) } ) }
@ -344,6 +366,22 @@ export function ProductDetailsSectionDescriptionBlockEdit( {
) } ) }
</MenuGroup> </MenuGroup>
{ isProductFormTemplateSystemEnabled() && (
<MenuGroup>
{ productFormPosts.map( ( formPost ) => (
<MenuItem
key={ formPost.id }
icon={ resolveIcon( 'external' ) }
info={ formPost.excerpt.raw }
iconPosition="left"
onClick={ onClose } // close the dropdown for now
>
{ formPost.title.rendered }
</MenuItem>
) ) }
</MenuGroup>
) }
{ unsupportedProductTemplates.length > 0 && ( { unsupportedProductTemplates.length > 0 && (
<MenuGroup> <MenuGroup>
<Dropdown <Dropdown

View File

@ -17,7 +17,6 @@ import { __ } from '@wordpress/i18n';
import { useLayoutTemplate } from '@woocommerce/block-templates'; import { useLayoutTemplate } from '@woocommerce/block-templates';
import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts';
import { Product } from '@woocommerce/data'; import { Product } from '@woocommerce/data';
import { SelectControl } from '@wordpress/components';
import { import {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore No types for this exist yet. // @ts-ignore No types for this exist yet.
@ -51,7 +50,8 @@ import { store as productEditorUiStore } from '../../store/product-editor-ui';
import { ProductEditorSettings } from '../editor'; import { ProductEditorSettings } from '../editor';
import { BlockEditorProps } from './types'; import { BlockEditorProps } from './types';
import { LoadingState } from './loading-state'; import { LoadingState } from './loading-state';
import type { ProductFormTemplateProps, ProductTemplate } from '../../types'; import type { ProductFormPostProps, ProductTemplate } from '../../types';
import isProductFormTemplateSystemEnabled from '../../utils/is-product-form-template-system-enabled';
const PluginArea = lazy( () => const PluginArea = lazy( () =>
import( '@wordpress/plugins' ).then( ( module ) => ( { import( '@wordpress/plugins' ).then( ( module ) => ( {
@ -87,9 +87,6 @@ export function BlockEditor( {
productId, productId,
setIsEditorLoading, setIsEditorLoading,
}: BlockEditorProps ) { }: BlockEditorProps ) {
const isProductEditorTemplateSystemEnabled =
!! window.wcAdminFeatures?.[ 'product-editor-template-system' ];
const [ selectedProductFormId, setSelectedProductFormId ] = useState< const [ selectedProductFormId, setSelectedProductFormId ] = useState<
number | null number | null
>( null ); >( null );
@ -224,7 +221,7 @@ export function BlockEditor( {
per_page: -1, per_page: -1,
} ) || [] } ) || []
); );
}, [] ) as ProductFormTemplateProps[]; }, [] ) as ProductFormPostProps[];
// Set the default product form template ID. // Set the default product form template ID.
useEffect( () => { useEffect( () => {
@ -246,7 +243,7 @@ export function BlockEditor( {
const productFormTemplate = useMemo( const productFormTemplate = useMemo(
function pickAndParseTheProductFormTemplate() { function pickAndParseTheProductFormTemplate() {
if ( if (
! isProductEditorTemplateSystemEnabled || ! isProductFormTemplateSystemEnabled() ||
! selectedProductFormId ! selectedProductFormId
) { ) {
return undefined; return undefined;
@ -262,11 +259,7 @@ export function BlockEditor( {
return undefined; return undefined;
}, },
[ [ productForms, selectedProductFormId ]
isProductEditorTemplateSystemEnabled,
productForms,
selectedProductFormId,
]
); );
useLayoutEffect( useLayoutEffect(
@ -284,7 +277,7 @@ export function BlockEditor( {
* If the product form template is not available, use the block instances. * If the product form template is not available, use the block instances.
* ToDo: Remove this fallback once the product form template is stable/available. * ToDo: Remove this fallback once the product form template is stable/available.
*/ */
const editorTemplate = productFormTemplate ?? blockInstances; const editorTemplate = blockInstances ?? productFormTemplate;
onChange( editorTemplate, {} ); onChange( editorTemplate, {} );
@ -336,34 +329,8 @@ export function BlockEditor( {
); );
} }
const formTemplateSelectValues = productForms?.map( ( form ) => ( {
label: form.title.raw,
value: String( form.id ),
} ) );
return ( return (
<div className="woocommerce-product-block-editor"> <div className="woocommerce-product-block-editor">
{ isProductEditorTemplateSystemEnabled && (
<div style={ { margin: '32px', width: '250px' } }>
<SelectControl
label={ __(
'Choose form template type',
'woocommerce'
) }
options={ formTemplateSelectValues }
onChange={ ( value: string ) =>
setSelectedProductFormId( parseInt( value, 10 ) )
}
disabled={ ! productForms }
className="woocommerce-product-block-editor__product-type-selector"
help={ __(
'This is a temporary setting.',
'woocommerce'
) }
/>
</div>
) }
<BlockContextProvider value={ context }> <BlockContextProvider value={ context }>
<BlockEditorProvider <BlockEditorProvider
value={ blocks } value={ blocks }

View File

@ -50,7 +50,7 @@ export interface TaxonomyMetadata {
hierarchical: boolean; hierarchical: boolean;
} }
export type ProductFormTemplateProps = { export type ProductFormPostProps = {
id: number; id: number;
date: string; date: string;
date_gmt: string; date_gmt: string;

View File

@ -0,0 +1,3 @@
export default function isProductFormTemplateSystemEnabled() {
return !! window.wcAdminFeatures?.[ 'product-editor-template-system' ];
}

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
WooCommerce: store the template description in the `product_form` excerpt property.

View File

@ -109,7 +109,7 @@ class ProductFormsController {
'ID' => $post->ID, 'ID' => $post->ID,
'post_title' => $file_data['title'], 'post_title' => $file_data['title'],
'post_content' => BlockTemplateUtils::get_template_content( $file_path ), 'post_content' => BlockTemplateUtils::get_template_content( $file_path ),
'post_excerpt' => __( 'Template updated by the (PFT) Product Form Template system', 'woocommerce' ), 'post_excerpt' => $file_data['description'],
) )
); );
} }
@ -129,7 +129,7 @@ class ProductFormsController {
'post_status' => 'publish', 'post_status' => 'publish',
'post_type' => 'product_form', 'post_type' => 'product_form',
'post_content' => BlockTemplateUtils::get_template_content( $file_path ), 'post_content' => BlockTemplateUtils::get_template_content( $file_path ),
'post_excerpt' => __( 'Template created by the (PFT) Product Form Template system', 'woocommerce' ), 'post_excerpt' => $file_data['description'],
) )
); );
} }

View File

@ -4,11 +4,11 @@
* *
* Title: Simple * Title: Simple
* Slug: simple * Slug: simple
* Description: This is the template description. * Description: A single physical or virtual product, e.g. a t-shirt or an eBook
* Product Types: simple, variable * Product Types: simple, variable
* *
* @package WooCommerce\Templates * @package WooCommerce\Templates
* @version 9.1.0 * @version 9.1.0-beta.1
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {