From a49b9780503b9b817ba82183cdd99141f28cbb9c Mon Sep 17 00:00:00 2001 From: Oluwaseun Olorunsola Date: Tue, 28 Jan 2025 22:51:40 +0100 Subject: [PATCH] Remove usage of hardcoded `mailpoet_email` string from the JS package MAILPOET-6430 --- .../src/components/header/campaign-name.tsx | 4 +-- .../src/components/header/more-menu.tsx | 4 +-- .../src/components/header/trash-modal.tsx | 5 ++-- .../rich-text-with-button.tsx | 4 +-- .../components/preview/preview-dropdown.tsx | 2 +- .../components/preview/send-preview-email.tsx | 3 ++- .../src/components/sidebar/details-panel.tsx | 5 ++-- .../template-select/select-modal.tsx | 3 ++- packages/js/email-editor/src/editor.tsx | 4 +-- packages/js/email-editor/src/global.d.ts | 1 + packages/js/email-editor/src/store/actions.ts | 14 +++++++---- .../js/email-editor/src/store/constants.ts | 3 +++ .../js/email-editor/src/store/selectors.ts | 22 ++++++++-------- packages/js/email-editor/src/store/types.ts | 2 +- .../src/Engine/class-email-editor.php | 25 +++++++++++++++++++ 15 files changed, 69 insertions(+), 32 deletions(-) diff --git a/packages/js/email-editor/src/components/header/campaign-name.tsx b/packages/js/email-editor/src/components/header/campaign-name.tsx index af63c59db6..84b0ec21d9 100644 --- a/packages/js/email-editor/src/components/header/campaign-name.tsx +++ b/packages/js/email-editor/src/components/header/campaign-name.tsx @@ -17,7 +17,7 @@ import { /** * Internal dependencies */ -import { storeName } from '../../store'; +import { storeName, editorCurrentPostType } from '../../store'; import { recordEvent, recordEventOnce } from '../../events'; // @see https://github.com/WordPress/gutenberg/blob/5e0ffdbc36cb2e967dfa6a6b812a10a2e56a598f/packages/edit-post/src/components/header/document-actions/index.js @@ -34,7 +34,7 @@ export function CampaignName() { const [ emailTitle = '', setTitle ] = useEntityProp( 'postType', - 'mailpoet_email', + editorCurrentPostType, 'title' ); diff --git a/packages/js/email-editor/src/components/header/more-menu.tsx b/packages/js/email-editor/src/components/header/more-menu.tsx index 4486b16568..5ae46fa073 100644 --- a/packages/js/email-editor/src/components/header/more-menu.tsx +++ b/packages/js/email-editor/src/components/header/more-menu.tsx @@ -13,7 +13,7 @@ import { useSelect, useDispatch } from '@wordpress/data'; /** * Internal dependencies */ -import { storeName } from '../../store'; +import { storeName, editorCurrentPostType } from '../../store'; import { TrashModal } from './trash-modal'; import { recordEvent } from '../../events'; @@ -32,7 +32,7 @@ export function MoreMenu(): JSX.Element { ); const [ status, setStatus ] = useEntityProp( 'postType', - 'mailpoet_email', + editorCurrentPostType, 'status' ); const { saveEditedEmail, updateEmailMailPoetProperty } = diff --git a/packages/js/email-editor/src/components/header/trash-modal.tsx b/packages/js/email-editor/src/components/header/trash-modal.tsx index e01d97599f..a32b676c85 100644 --- a/packages/js/email-editor/src/components/header/trash-modal.tsx +++ b/packages/js/email-editor/src/components/header/trash-modal.tsx @@ -10,6 +10,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ +import { editorCurrentPostType } from '../../store'; import { recordEvent } from '../../events'; export function TrashModal( { @@ -31,7 +32,7 @@ export function TrashModal( { recordEvent( 'trash_modal_move_to_trash_button_clicked' ); const success = await deleteEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId as unknown as string, {}, { throwOnError: false } @@ -41,7 +42,7 @@ export function TrashModal( { } else { const lastError = getLastEntityDeleteError( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); // Already deleted. diff --git a/packages/js/email-editor/src/components/personalization-tags/rich-text-with-button.tsx b/packages/js/email-editor/src/components/personalization-tags/rich-text-with-button.tsx index 154a85055f..d3cab8c967 100644 --- a/packages/js/email-editor/src/components/personalization-tags/rich-text-with-button.tsx +++ b/packages/js/email-editor/src/components/personalization-tags/rich-text-with-button.tsx @@ -17,7 +17,7 @@ import { getCursorPosition, replacePersonalizationTagsWithHTMLComments, } from './rich-text-utils'; -import { storeName } from '../../store'; +import { storeName, editorCurrentPostType } from '../../store'; import { PersonalizationTagsPopover } from './personalization-tags-popover'; import { recordEvent, recordEventOnce } from '../../events'; @@ -30,7 +30,7 @@ export function RichTextWithButton( { } ) { const [ mailpoetEmailData ] = useEntityProp( 'postType', - 'mailpoet_email', + editorCurrentPostType, 'mailpoet_data' ); diff --git a/packages/js/email-editor/src/components/preview/preview-dropdown.tsx b/packages/js/email-editor/src/components/preview/preview-dropdown.tsx index acd0ce1b5c..2e12ce7ed8 100644 --- a/packages/js/email-editor/src/components/preview/preview-dropdown.tsx +++ b/packages/js/email-editor/src/components/preview/preview-dropdown.tsx @@ -10,9 +10,9 @@ import { PostPreviewButton } from '@wordpress/editor'; /** * Internal dependencies */ -import { SendPreviewEmail } from './send-preview-email'; import { storeName } from '../../store'; import { recordEvent } from '../../events'; +import { SendPreviewEmail } from './send-preview-email'; export function PreviewDropdown() { const previewDeviceType = useSelect( diff --git a/packages/js/email-editor/src/components/preview/send-preview-email.tsx b/packages/js/email-editor/src/components/preview/send-preview-email.tsx index dfcb39f617..b08779ef57 100644 --- a/packages/js/email-editor/src/components/preview/send-preview-email.tsx +++ b/packages/js/email-editor/src/components/preview/send-preview-email.tsx @@ -22,6 +22,7 @@ import { MailPoetEmailData, SendingPreviewStatus, storeName, + editorCurrentPostType, } from '../../store'; import { recordEvent, recordEventOnce } from '../../events'; @@ -43,7 +44,7 @@ function RawSendPreviewEmail() { const [ mailpoetEmailData ] = useEntityProp( 'postType', - 'mailpoet_email', + editorCurrentPostType, 'mailpoet_data' ) as [ MailPoetEmailData, unknown, unknown ]; diff --git a/packages/js/email-editor/src/components/sidebar/details-panel.tsx b/packages/js/email-editor/src/components/sidebar/details-panel.tsx index 318b8bc6cd..54ab008aac 100644 --- a/packages/js/email-editor/src/components/sidebar/details-panel.tsx +++ b/packages/js/email-editor/src/components/sidebar/details-panel.tsx @@ -10,8 +10,9 @@ import classnames from 'classnames'; /** * Internal dependencies */ -import { RichTextWithButton } from '../personalization-tags/rich-text-with-button'; +import { editorCurrentPostType } from '../../store'; import { recordEvent } from '../../events'; +import { RichTextWithButton } from '../personalization-tags/rich-text-with-button'; const previewTextMaxLength = 150; const previewTextRecommendedLength = 80; @@ -19,7 +20,7 @@ const previewTextRecommendedLength = 80; export function DetailsPanel() { const [ mailpoetEmailData ] = useEntityProp( 'postType', - 'mailpoet_email', + editorCurrentPostType, 'mailpoet_data' ); diff --git a/packages/js/email-editor/src/components/template-select/select-modal.tsx b/packages/js/email-editor/src/components/template-select/select-modal.tsx index 0a484a010a..f3b51f5d45 100644 --- a/packages/js/email-editor/src/components/template-select/select-modal.tsx +++ b/packages/js/email-editor/src/components/template-select/select-modal.tsx @@ -16,6 +16,7 @@ import { storeName, TemplateCategory, TemplatePreview, + editorCurrentPostType, } from '../../store'; import { TemplateList } from './template-list'; import { TemplateCategoriesListSidebar } from './template-categories-list-sidebar'; @@ -94,7 +95,7 @@ export function SelectTemplateModal( { const hasTemplates = templates?.length > 0; const handleTemplateSelection = ( template: TemplatePreview ) => { - const templateIsPostContent = template.type === 'mailpoet_email'; + const templateIsPostContent = template.type === editorCurrentPostType; const postContent = template.template as unknown as EmailEditorPostType; diff --git a/packages/js/email-editor/src/editor.tsx b/packages/js/email-editor/src/editor.tsx index 3a50327e15..2ea6d155f4 100644 --- a/packages/js/email-editor/src/editor.tsx +++ b/packages/js/email-editor/src/editor.tsx @@ -12,7 +12,7 @@ import '@wordpress/format-library'; // Enables text formatting capabilities import { initBlocks } from './blocks'; import { initializeLayout } from './layouts/flex-email'; import { InnerEditor } from './components/block-editor'; -import { createStore, storeName } from './store'; +import { createStore, storeName, editorCurrentPostType } from './store'; import { initHooks } from './editor-hooks'; import { KeyboardShortcuts } from './components/keybord-shortcuts'; import { initEventCollector } from './events'; @@ -33,7 +33,7 @@ function Editor() { diff --git a/packages/js/email-editor/src/global.d.ts b/packages/js/email-editor/src/global.d.ts index 7570409c7a..d5b6544b93 100644 --- a/packages/js/email-editor/src/global.d.ts +++ b/packages/js/email-editor/src/global.d.ts @@ -15,4 +15,5 @@ interface Window { editor_layout: unknown; // Can't import type in global.d.ts. Typed in getEmailLayout() in store/settings.ts editor_theme: unknown; // Can't import type in global.d.ts. Typed in getEditorTheme() in store/settings.ts }; + mailpoet_email_editor_current_post_type: string; } diff --git a/packages/js/email-editor/src/store/actions.ts b/packages/js/email-editor/src/store/actions.ts index 7f5e5a8cc1..56c4d46010 100644 --- a/packages/js/email-editor/src/store/actions.ts +++ b/packages/js/email-editor/src/store/actions.ts @@ -24,7 +24,11 @@ import { /** * Internal dependencies */ -import { storeName, mainSidebarDocumentTab } from './constants'; +import { + storeName, + mainSidebarDocumentTab, + editorCurrentPostType, +} from './constants'; import { SendingPreviewStatus, State, @@ -99,7 +103,7 @@ export function* saveEditedEmail() { const result = yield dispatch( coreDataStore ).saveEditedEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId, { throwOnError: true } ); @@ -135,14 +139,14 @@ export function* updateEmailMailPoetProperty( name: string, value: string ) { // There can be a better way how to get the edited post data const editedPost = select( coreDataStore ).getEditedEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); // @ts-expect-error Property 'mailpoet_data' does not exist on type 'Updatable>'. const mailpoetData = editedPost?.mailpoet_data || {}; yield dispatch( coreDataStore ).editEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId, { mailpoet_data: { @@ -159,7 +163,7 @@ export const setTemplateToPost = const postId = registry.select( storeName ).getEmailPostId(); registry .dispatch( coreDataStore ) - .editEntityRecord( 'postType', 'mailpoet_email', postId, { + .editEntityRecord( 'postType', editorCurrentPostType, postId, { template: templateSlug, } ); }; diff --git a/packages/js/email-editor/src/store/constants.ts b/packages/js/email-editor/src/store/constants.ts index eb6160a37f..e43f7da77f 100644 --- a/packages/js/email-editor/src/store/constants.ts +++ b/packages/js/email-editor/src/store/constants.ts @@ -4,3 +4,6 @@ export const mainSidebarId = 'email-editor/editor/main'; export const mainSidebarDocumentTab = 'document'; export const mainSidebarBlockTab = 'block'; export const stylesSidebarId = 'email-editor/editor/styles'; + +export const editorCurrentPostType = + window.mailpoet_email_editor_current_post_type; diff --git a/packages/js/email-editor/src/store/selectors.ts b/packages/js/email-editor/src/store/selectors.ts index 8abf73e7f0..61c4626e8b 100644 --- a/packages/js/email-editor/src/store/selectors.ts +++ b/packages/js/email-editor/src/store/selectors.ts @@ -13,7 +13,7 @@ import { Post } from '@wordpress/core-data/build-types/entity-types/post'; /** * Internal dependencies */ -import { storeName } from './constants'; +import { storeName, editorCurrentPostType } from './constants'; import { State, Feature, EmailTemplate, EmailEditorPostType } from './types'; function getContentFromEntity( entity ): string { @@ -59,7 +59,7 @@ export const hasEdits = createRegistrySelector( ( select ) => (): boolean => { const postId = select( storeName ).getEmailPostId(); return !! select( coreDataStore ).hasEditsForEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); } ); @@ -69,7 +69,7 @@ export const isEmailLoaded = createRegistrySelector( const postId = select( storeName ).getEmailPostId(); return !! select( coreDataStore ).getEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); } @@ -79,7 +79,7 @@ export const isSaving = createRegistrySelector( ( select ) => (): boolean => { const postId = select( storeName ).getEmailPostId(); return !! select( coreDataStore ).isSavingEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); } ); @@ -89,7 +89,7 @@ export const isEmpty = createRegistrySelector( ( select ) => (): boolean => { const post: EmailEditorPostType = select( coreDataStore ).getEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); if ( ! post ) { @@ -111,7 +111,7 @@ export const hasEmptyContent = createRegistrySelector( const post = select( coreDataStore ).getEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); if ( ! post ) { @@ -130,7 +130,7 @@ export const isEmailSent = createRegistrySelector( const post = select( coreDataStore ).getEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ); if ( ! post ) { @@ -154,7 +154,7 @@ export const getEditedEmailContent = createRegistrySelector( const postId = select( storeName ).getEmailPostId(); const record = select( coreDataStore ).getEditedEntityRecord( 'postType', - 'mailpoet_email', + editorCurrentPostType, postId ) as unknown as | { content: string | unknown; blocks: BlockInstance[] } @@ -170,7 +170,7 @@ export const getEditedEmailContent = createRegistrySelector( export const getSentEmailEditorPosts = createRegistrySelector( ( select ) => () => select( coreDataStore ) - .getEntityRecords( 'postType', 'mailpoet_email', { + .getEntityRecords( 'postType', editorCurrentPostType, { per_page: 30, // show a maximum of 30 for now status: 'publish,sent', // show only sent emails } ) @@ -290,13 +290,13 @@ export const getEmailTemplates = createRegistrySelector( select( coreDataStore ) .getEntityRecords( 'postType', 'wp_template', { per_page: -1, - post_type: 'mailpoet_email', + post_type: editorCurrentPostType, } ) // We still need to filter the templates because, in some cases, the API also returns custom templates // ignoring the post_type filter in the query ?.filter( ( template ) => // @ts-expect-error Missing property in type - template.post_types.includes( 'mailpoet_email' ) + template.post_types.includes( editorCurrentPostType ) ) ); diff --git a/packages/js/email-editor/src/store/types.ts b/packages/js/email-editor/src/store/types.ts index a4ca3fb1aa..db07a5ec02 100644 --- a/packages/js/email-editor/src/store/types.ts +++ b/packages/js/email-editor/src/store/types.ts @@ -268,6 +268,6 @@ export type MailPoetEmailPostContentExtended = { }; export type EmailEditorPostType = Omit< Post, 'type' > & { - type: 'mailpoet_email'; + type: string; mailpoet_data?: MailPoetEmailPostContentExtended; }; diff --git a/packages/php/email-editor/src/Engine/class-email-editor.php b/packages/php/email-editor/src/Engine/class-email-editor.php index e7e00f54ba..6b838a2890 100644 --- a/packages/php/email-editor/src/Engine/class-email-editor.php +++ b/packages/php/email-editor/src/Engine/class-email-editor.php @@ -105,6 +105,7 @@ class Email_Editor { if ( $is_editor_page ) { $this->extend_email_post_api(); $this->settings_controller->init(); + add_filter( 'admin_footer', array( $this, 'load_js_vars' ), 24 ); // @phpstan-ignore-line -- Filter callback return statement is missing. } add_action( 'rest_api_init', array( $this, 'register_email_editor_api_routes' ) ); add_filter( 'mailpoet_email_editor_send_preview_email', array( $this->send_preview_email, 'send_preview_email' ), 11, 1 ); // allow for other filter methods to take precedent. @@ -296,4 +297,28 @@ class Email_Editor { return __DIR__ . '/Templates/single-email-post-template.php'; } + + /** + * Load JS vars + * + * @return void + * @throws \InvalidArgumentException If the post-type is invalid. + */ + public function load_js_vars() { + global $post; + + $email_editor_post_type_names = array_column( $this->get_post_types(), 'name' ); + $email_editor_current_post_type = $post->post_type; + $current_post_is_email_editor_type = in_array( $email_editor_current_post_type, $email_editor_post_type_names, true ); + + if ( ! $current_post_is_email_editor_type ) { + throw new \InvalidArgumentException( esc_html__( 'Invalid email post type', 'mailpoet' ) ); + } + + ?> + +