2021-10-29 07:31:50 +00:00
/ * *
* External dependencies
* /
2022-06-29 07:42:02 +00:00
import {
getBlockType ,
registerBlockType ,
unregisterBlockType ,
} from '@wordpress/blocks' ;
2022-11-02 16:46:14 +00:00
import type { BlockEditProps } from '@wordpress/blocks' ;
2022-06-06 14:49:19 +00:00
import {
isExperimentalBuild ,
WC_BLOCKS_IMAGE_URL ,
} from '@woocommerce/block-settings' ;
2021-10-29 07:31:50 +00:00
import { useBlockProps } from '@wordpress/block-editor' ;
2022-06-06 14:49:19 +00:00
import { Button , Placeholder } from '@wordpress/components' ;
2023-02-27 14:34:18 +00:00
import { __ } from '@wordpress/i18n' ;
2021-12-10 10:07:10 +00:00
import { box , Icon } from '@wordpress/icons' ;
2022-06-29 07:42:02 +00:00
import { select , useDispatch , subscribe } from '@wordpress/data' ;
import { useEffect } from '@wordpress/element' ;
2021-11-02 14:42:07 +00:00
/ * *
* Internal dependencies
* /
import './editor.scss' ;
2022-05-04 11:02:42 +00:00
import './style.scss' ;
2023-02-27 14:34:18 +00:00
import { BLOCK_SLUG , TEMPLATES , TYPES } from './constants' ;
2022-09-06 09:52:33 +00:00
import {
isClassicTemplateBlockRegisteredWithAnotherTitle ,
hasTemplateSupportForClassicTemplateBlock ,
getTemplateDetailsBySlug ,
} from './utils' ;
2023-02-27 14:34:18 +00:00
import {
blockifiedProductCatalogConfig ,
blockifiedProductTaxonomyConfig ,
} from './archive-product' ;
import * as blockifiedSingleProduct from './single-product' ;
import * as blockifiedProductSearchResults from './product-search-results' ;
import type { BlockifiedTemplateConfig } from './types' ;
2022-06-29 07:42:02 +00:00
type Attributes = {
template : string ;
align : string ;
} ;
2021-10-29 07:31:50 +00:00
2023-02-27 14:34:18 +00:00
const blockifiedFallbackConfig = {
isConversionPossible : ( ) = > false ,
getBlockifiedTemplate : ( ) = > [ ] ,
getDescription : ( ) = > '' ,
getButtonLabel : ( ) = > '' ,
} ;
const conversionConfig : { [ key : string ] : BlockifiedTemplateConfig } = {
[ TYPES . productCatalog ] : blockifiedProductCatalogConfig ,
[ TYPES . productTaxonomy ] : blockifiedProductTaxonomyConfig ,
[ TYPES . singleProduct ] : blockifiedSingleProduct ,
[ TYPES . productSearchResults ] : blockifiedProductSearchResults ,
fallback : blockifiedFallbackConfig ,
} ;
2022-06-29 07:42:02 +00:00
const Edit = ( {
clientId ,
attributes ,
setAttributes ,
} : BlockEditProps < Attributes > ) = > {
2022-06-06 14:49:19 +00:00
const { replaceBlock } = useDispatch ( 'core/block-editor' ) ;
2021-10-29 07:31:50 +00:00
const blockProps = useBlockProps ( ) ;
2022-09-06 09:52:33 +00:00
const templateDetails = getTemplateDetailsBySlug (
attributes . template ,
TEMPLATES
) ;
const templateTitle = templateDetails ? . title ? ? attributes . template ;
const templatePlaceholder = templateDetails ? . placeholder ? ? 'fallback' ;
2023-02-27 14:34:18 +00:00
const templateType = templateDetails ? . type ? ? 'fallback' ;
2022-06-29 07:42:02 +00:00
useEffect (
( ) = >
setAttributes ( {
template : attributes.template ,
align : attributes.align ? ? 'wide' ,
} ) ,
[ attributes . align , attributes . template , setAttributes ]
) ;
2023-02-27 14:34:18 +00:00
const {
getBlockifiedTemplate ,
isConversionPossible ,
getDescription ,
getButtonLabel ,
} = conversionConfig [ templateType ] ;
2023-03-30 12:47:02 +00:00
const canConvert = isConversionPossible ( ) ;
2023-02-27 14:34:18 +00:00
const placeholderDescription = getDescription ( templateTitle , canConvert ) ;
2021-10-29 07:31:50 +00:00
return (
< div { ...blockProps } >
< Placeholder
2021-12-10 10:07:10 +00:00
icon = { box }
2022-01-27 09:45:00 +00:00
label = { templateTitle }
2022-03-22 22:34:43 +00:00
className = "wp-block-woocommerce-classic-template__placeholder"
2021-11-02 14:42:07 +00:00
>
2022-03-22 22:34:43 +00:00
< div className = "wp-block-woocommerce-classic-template__placeholder-copy" >
2023-02-27 14:34:18 +00:00
< p > { placeholderDescription } < / p >
2021-11-02 14:42:07 +00:00
< / div >
2022-03-22 22:34:43 +00:00
< div className = "wp-block-woocommerce-classic-template__placeholder-wireframe" >
2023-02-27 14:34:18 +00:00
{ canConvert && (
2022-06-06 14:49:19 +00:00
< div className = "wp-block-woocommerce-classic-template__placeholder-migration-button-container" >
< Button
isPrimary
onClick = { ( ) = > {
replaceBlock (
clientId ,
2023-02-27 14:34:18 +00:00
getBlockifiedTemplate ( attributes )
2022-06-06 14:49:19 +00:00
) ;
} }
2023-02-27 14:34:18 +00:00
text = { getButtonLabel ( ) }
2022-06-06 14:49:19 +00:00
/ >
< / div >
) }
2021-11-02 14:42:07 +00:00
< img
2022-03-22 22:34:43 +00:00
className = "wp-block-woocommerce-classic-template__placeholder-image"
2022-01-27 09:45:00 +00:00
src = { ` ${ WC_BLOCKS_IMAGE_URL } template-placeholders/ ${ templatePlaceholder } .svg ` }
alt = { templateTitle }
2021-11-02 14:42:07 +00:00
/ >
< / div >
< / Placeholder >
2021-10-29 07:31:50 +00:00
< / div >
) ;
} ;
2022-06-29 07:42:02 +00:00
const registerClassicTemplateBlock = ( {
template ,
inserter ,
} : {
template? : string ;
inserter : boolean ;
} ) = > {
/ * *
* The 'WooCommerce Legacy Template' block was renamed to 'WooCommerce Classic Template' , however , the internal block
* name 'woocommerce/legacy-template' needs to remain the same . Otherwise , it would result in a corrupt block when
* loaded for users who have customized templates using the legacy - template ( since the internal block name is
* stored in the database ) .
*
* See https : //github.com/woocommerce/woocommerce-gutenberg-products-block/issues/5861 for more context
* /
registerBlockType ( BLOCK_SLUG , {
2022-09-06 09:52:33 +00:00
title :
template && TEMPLATES [ template ]
? TEMPLATES [ template ] . title
: __ (
'WooCommerce Classic Template' ,
'woo-gutenberg-products-block'
) ,
2022-06-29 07:42:02 +00:00
icon : (
< Icon
icon = { box }
className = "wc-block-editor-components-block-icon"
/ >
) ,
category : 'woocommerce' ,
apiVersion : 2 ,
keywords : [ __ ( 'WooCommerce' , 'woo-gutenberg-products-block' ) ] ,
description : __ (
'Renders classic WooCommerce PHP templates.' ,
'woo-gutenberg-products-block'
) ,
supports : {
align : [ 'wide' , 'full' ] ,
html : false ,
multiple : false ,
reusable : false ,
inserter ,
} ,
attributes : {
/ * *
* Template attribute is used to determine which core PHP template gets rendered .
* /
template : {
type : 'string' ,
default : 'any' ,
} ,
align : {
type : 'string' ,
default : 'wide' ,
} ,
2022-01-27 09:45:00 +00:00
} ,
2022-06-29 07:42:02 +00:00
edit : ( {
attributes ,
clientId ,
setAttributes ,
} : BlockEditProps < Attributes > ) = > {
const newTemplate = template ? ? attributes . template ;
return (
< Edit
attributes = { {
. . . attributes ,
template : newTemplate ,
} }
setAttributes = { setAttributes }
clientId = { clientId }
/ >
) ;
2022-05-04 11:02:42 +00:00
} ,
2022-06-29 07:42:02 +00:00
save : ( ) = > null ,
} ) ;
} ;
// @todo Refactor when there will be possible to show a block according on a template/post with a Gutenberg API. https://github.com/WordPress/gutenberg/pull/41718
let currentTemplateId : string | undefined ;
if ( isExperimentalBuild ( ) ) {
subscribe ( ( ) = > {
const previousTemplateId = currentTemplateId ;
const store = select ( 'core/edit-site' ) ;
currentTemplateId = store ? . getEditedPostId ( ) as string | undefined ;
if ( previousTemplateId === currentTemplateId ) {
return ;
}
const parsedTemplate = currentTemplateId ? . split ( '//' ) [ 1 ] ;
if ( parsedTemplate === null || parsedTemplate === undefined ) {
return ;
}
const block = getBlockType ( BLOCK_SLUG ) ;
if (
block !== undefined &&
2022-09-06 09:52:33 +00:00
( ! hasTemplateSupportForClassicTemplateBlock (
parsedTemplate ,
TEMPLATES
) ||
2022-06-29 07:42:02 +00:00
isClassicTemplateBlockRegisteredWithAnotherTitle (
block ,
parsedTemplate
) )
) {
unregisterBlockType ( BLOCK_SLUG ) ;
currentTemplateId = undefined ;
return ;
}
if (
block === undefined &&
2022-09-06 09:52:33 +00:00
hasTemplateSupportForClassicTemplateBlock (
parsedTemplate ,
TEMPLATES
)
2022-06-29 07:42:02 +00:00
) {
registerClassicTemplateBlock ( {
template : parsedTemplate ,
inserter : true ,
} ) ;
}
} ) ;
} else {
registerClassicTemplateBlock ( {
inserter : false ,
} ) ;
}