diff --git a/packages/js/email-editor/src/hooks/use-preview-templates.ts b/packages/js/email-editor/src/hooks/use-preview-templates.ts index 3420e7b47f..062699dba5 100644 --- a/packages/js/email-editor/src/hooks/use-preview-templates.ts +++ b/packages/js/email-editor/src/hooks/use-preview-templates.ts @@ -5,7 +5,6 @@ import { useMemo } from '@wordpress/element'; import { parse } from '@wordpress/blocks'; import { BlockInstance } from '@wordpress/blocks/index'; import { useSelect } from '@wordpress/data'; -import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies @@ -17,6 +16,10 @@ import { EmailEditorPostType, } from '../store'; +// Shared reference to an empty array for cases where it is important to avoid +// returning a new array reference on every invocation +const EMPTY_ARRAY = []; + /** * We need to merge pattern blocks and template blocks for BlockPreview component. * @param templateBlocks - Parsed template blocks @@ -96,21 +99,12 @@ export function usePreviewTemplates( ): [ TemplatePreview[], TemplatePreview[], boolean ] { const { templates, patterns, emailPosts, hasEmailPosts } = useSelect( ( select ) => { - const contentBlockId = - // @ts-expect-error getBlocksByName is not defined in types - select( blockEditorStore ).getBlocksByName( - 'core/post-content' - )?.[ 0 ]; - const rawEmailPosts = select( storeName ).getSentEmailEditorPosts(); + return { templates: select( storeName ).getEmailTemplates(), patterns: - // @ts-expect-error getPatternsByBlockTypes is not defined in types - select( blockEditorStore ).getPatternsByBlockTypes( - [ 'core/post-content' ], - contentBlockId - ), + select( storeName ).getBlockPatternsForEmailTemplate(), emailPosts: rawEmailPosts, hasEmailPosts: !! ( rawEmailPosts && rawEmailPosts?.length ), }; @@ -128,15 +122,11 @@ export function usePreviewTemplates( if ( parsedCustomEmailContent ) { contentPatterns = [ { blocks: parsedCustomEmailContent } ]; } else { - contentPatterns = patterns.filter( - ( pattern ) => - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - pattern?.templateTypes?.includes( 'email-template' ) - ); + contentPatterns = patterns; } if ( ! contentPatterns || ! templates ) { - return []; + return EMPTY_ARRAY; } const templateToPreview = []; @@ -208,5 +198,9 @@ export function usePreviewTemplates( } ) as unknown as TemplatePreview[]; }, [ emailPosts, allTemplates ] ); - return [ allTemplates || [], allEmailPosts || [], hasEmailPosts ]; + return [ + allTemplates || EMPTY_ARRAY, + allEmailPosts || EMPTY_ARRAY, + hasEmailPosts, + ]; } diff --git a/packages/js/email-editor/src/store/selectors.ts b/packages/js/email-editor/src/store/selectors.ts index ca879bc08a..8abf73e7f0 100644 --- a/packages/js/email-editor/src/store/selectors.ts +++ b/packages/js/email-editor/src/store/selectors.ts @@ -1,12 +1,12 @@ /** * External dependencies */ -import { createRegistrySelector } from '@wordpress/data'; +import { createRegistrySelector, createSelector } from '@wordpress/data'; import { store as coreDataStore } from '@wordpress/core-data'; import { store as interfaceStore } from '@wordpress/interface'; import { store as editorStore } from '@wordpress/editor'; import { store as preferencesStore } from '@wordpress/preferences'; -import { serialize } from '@wordpress/blocks'; +import { serialize, parse } from '@wordpress/blocks'; import { BlockInstance } from '@wordpress/blocks/index'; import { Post } from '@wordpress/core-data/build-types/entity-types/post'; @@ -29,6 +29,21 @@ function getContentFromEntity( entity ): string { return ''; } +const patternsWithParsedBlocks = new WeakMap(); +function enhancePatternWithParsedBlocks( pattern ) { + let enhancedPattern = patternsWithParsedBlocks.get( pattern ); + if ( ! enhancedPattern ) { + enhancedPattern = { + ...pattern, + get blocks() { + return parse( pattern.content ); + }, + }; + patternsWithParsedBlocks.set( pattern, enhancedPattern ); + } + return enhancedPattern; +} + export const isFeatureActive = createRegistrySelector( ( select ) => ( _, feature: Feature ): boolean => @@ -164,6 +179,22 @@ export const getSentEmailEditorPosts = createRegistrySelector( ) || [] ); +export const getBlockPatternsForEmailTemplate = createRegistrySelector( + ( select ) => + createSelector( + () => + select( coreDataStore ) + .getBlockPatterns() + .filter( + ( { templateTypes } ) => + Array.isArray( templateTypes ) && + templateTypes.includes( 'email-template' ) + ) + .map( enhancePatternWithParsedBlocks ), + () => [ select( coreDataStore ).getBlockPatterns() ] + ) +); + /** * COPIED FROM https://github.com/WordPress/gutenberg/blob/9c6d4fe59763b188d27ad937c2f0daa39e4d9341/packages/edit-post/src/store/selectors.js * Retrieves the template of the currently edited post.