/** * External dependencies */ import { BlockInstance, createBlock, getBlockType, registerBlockType, unregisterBlockType, } from '@wordpress/blocks'; import type { BlockEditProps } from '@wordpress/blocks'; import { isExperimentalBuild, WC_BLOCKS_IMAGE_URL, } from '@woocommerce/block-settings'; import { useBlockProps, BlockPreview, store as blockEditorStore, } from '@wordpress/block-editor'; import { Button, Placeholder, Popover } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { box, Icon } from '@wordpress/icons'; import { useDispatch, subscribe, useSelect, select } from '@wordpress/data'; import { useEffect, useMemo, useState } from '@wordpress/element'; import { store as noticesStore } from '@wordpress/notices'; import { useEntityRecord } from '@wordpress/core-data'; /** * Internal dependencies */ import './editor.scss'; import './style.scss'; import { BLOCK_SLUG, TEMPLATES, TYPES } from './constants'; import { isClassicTemplateBlockRegisteredWithAnotherTitle, hasTemplateSupportForClassicTemplateBlock, getTemplateDetailsBySlug, } from './utils'; import { blockifiedProductCatalogConfig, blockifiedProductTaxonomyConfig, } from './archive-product'; import * as blockifiedSingleProduct from './single-product'; import * as blockifiedProductSearchResults from './product-search-results'; import type { BlockifiedTemplateConfig } from './types'; type Attributes = { template: string; align: string; }; const blockifiedFallbackConfig = { isConversionPossible: () => false, getBlockifiedTemplate: () => [], getDescription: () => '', getButtonLabel: () => '', onClickCallback: () => void 0, }; const conversionConfig: { [ key: string ]: BlockifiedTemplateConfig } = { [ TYPES.productCatalog ]: blockifiedProductCatalogConfig, [ TYPES.productTaxonomy ]: blockifiedProductTaxonomyConfig, [ TYPES.singleProduct ]: blockifiedSingleProduct, [ TYPES.productSearchResults ]: blockifiedProductSearchResults, fallback: blockifiedFallbackConfig, }; const pickBlockClientIds = ( blocks: Array< BlockInstance > ) => blocks.reduce< Array< string > >( ( acc, block ) => { if ( block.name === 'core/template-part' ) { return acc; } return [ ...acc, block.clientId ]; }, [] ); const Edit = ( { clientId, attributes, setAttributes, }: BlockEditProps< Attributes > ) => { const { replaceBlock, selectBlock, replaceBlocks } = useDispatch( blockEditorStore ); const { getBlocks, editedPostId } = useSelect( ( sel ) => { return { getBlocks: sel( blockEditorStore ).getBlocks, editedPostId: sel( 'core/edit-site' ).getEditedPostId(), }; }, [] ); const template = useEntityRecord< { slug: string; title: { rendered?: string; row: string; }; } >( 'postType', 'wp_template', editedPostId ); const { createInfoNotice } = useDispatch( noticesStore ); const blocks = getBlocks(); const clientIds = useMemo( () => { pickBlockClientIds( blocks ); }, [ blocks ] ); const blockProps = useBlockProps(); const templateDetails = getTemplateDetailsBySlug( attributes.template, TEMPLATES ); const templateTitle = template.record?.title.rendered?.toLowerCase() ?? attributes.template; const templatePlaceholder = templateDetails?.placeholder ?? 'fallback'; const templateType = templateDetails?.type ?? 'fallback'; useEffect( () => setAttributes( { template: attributes.template, align: attributes.align ?? 'wide', } ), [ attributes.align, attributes.template, setAttributes ] ); const { isConversionPossible, getDescription, getButtonLabel, onClickCallback, getBlockifiedTemplate, } = conversionConfig[ templateType ]; const canConvert = isConversionPossible(); const placeholderDescription = getDescription( templateTitle, canConvert ); const [ isPopoverOpen, setIsPopoverOpen ] = useState( false ); return (
{ placeholderDescription }
{ canConvert && (