Commit ccd4a90cda5 for woocommerce

commit ccd4a90cda51edb7aed0d30dc7bcb854e754f655
Author: Pavel Dohnal <pavel.dohnal@automattic.com>
Date:   Mon Apr 6 16:01:49 2026 +0200

    Fix template-select modal not showing on WP 7.0 (#64026)

diff --git a/packages/js/email-editor/changelog/fix-template-selection-hasedits-wp7 b/packages/js/email-editor/changelog/fix-template-selection-hasedits-wp7
new file mode 100644
index 00000000000..23cee276a1c
--- /dev/null
+++ b/packages/js/email-editor/changelog/fix-template-selection-hasedits-wp7
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix template-select modal not appearing on WordPress 7.0 due to hasEdits() returning true on fresh posts
diff --git a/packages/js/email-editor/src/components/template-select/template-selection.tsx b/packages/js/email-editor/src/components/template-select/template-selection.tsx
index 54a04f25fcf..57a5d3dfd9d 100644
--- a/packages/js/email-editor/src/components/template-select/template-selection.tsx
+++ b/packages/js/email-editor/src/components/template-select/template-selection.tsx
@@ -1,8 +1,7 @@
 /**
  * External dependencies
  */
-import { useSelect } from '@wordpress/data';
-import { useState } from '@wordpress/element';
+import { useDispatch, useSelect } from '@wordpress/data';

 /**
  * Internal dependencies
@@ -11,22 +10,26 @@ import { storeName } from '../../store';
 import { SelectTemplateModal } from './select-modal';

 export function TemplateSelection() {
-	const [ templateSelected, setTemplateSelected ] = useState( false );
-	const { emailContentIsEmpty, emailHasEdits, postType } = useSelect(
+	const { emailContentIsEmpty, templateSelected, postType } = useSelect(
 		( select ) => ( {
 			emailContentIsEmpty: select( storeName ).hasEmptyContent(),
-			emailHasEdits: select( storeName ).hasEdits(),
+			templateSelected: select( storeName ).isTemplateSelected(),
 			postType: select( storeName ).getEmailPostType(),
 		} ),
 		[]
 	);
-	if ( ! emailContentIsEmpty || emailHasEdits || templateSelected ) {
+	const { setTemplateSelected } = useDispatch( storeName );
+
+	// Show the template modal whenever content is empty, regardless of WP's dirty state.
+	// WP 7.0 auto-inserts an empty paragraph block on fresh posts, causing hasEdits()
+	// to return true before the user does anything.
+	if ( ! emailContentIsEmpty || templateSelected ) {
 		return null;
 	}

 	return (
 		<SelectTemplateModal
-			onSelectCallback={ () => setTemplateSelected( true ) }
+			onSelectCallback={ () => void setTemplateSelected() }
 			postType={ postType }
 		/>
 	);
diff --git a/packages/js/email-editor/src/store/actions.ts b/packages/js/email-editor/src/store/actions.ts
index a83c530d1c6..79b4169b12a 100644
--- a/packages/js/email-editor/src/store/actions.ts
+++ b/packages/js/email-editor/src/store/actions.ts
@@ -100,6 +100,12 @@ export const setTemplateToPost =
 			} );
 	};

+export function setTemplateSelected() {
+	return {
+		type: 'SET_TEMPLATE_SELECTED',
+	} as const;
+}
+
 export function* requestSendingNewsletterPreview( email: string ) {
 	// If preview is already sending do nothing
 	const previewState = select( storeName ).getPreviewState();
diff --git a/packages/js/email-editor/src/store/initial-state.ts b/packages/js/email-editor/src/store/initial-state.ts
index 5f4e87c9b9c..95149108c3f 100644
--- a/packages/js/email-editor/src/store/initial-state.ts
+++ b/packages/js/email-editor/src/store/initial-state.ts
@@ -21,5 +21,6 @@ export function getInitialState(): State {
 			sendingPreviewStatus: null,
 		},
 		contentValidation: undefined,
+		templateSelected: false,
 	};
 }
diff --git a/packages/js/email-editor/src/store/reducer.ts b/packages/js/email-editor/src/store/reducer.ts
index 1a1ecd49d69..55801d03f1f 100644
--- a/packages/js/email-editor/src/store/reducer.ts
+++ b/packages/js/email-editor/src/store/reducer.ts
@@ -20,6 +20,11 @@ export function reducer( state: State, action ): State {
 				...state,
 				contentValidation: action.validation,
 			};
+		case 'SET_TEMPLATE_SELECTED':
+			return {
+				...state,
+				templateSelected: true,
+			};
 		case 'SET_EDITOR_SETTINGS':
 			return {
 				...state,
diff --git a/packages/js/email-editor/src/store/selectors.ts b/packages/js/email-editor/src/store/selectors.ts
index 2948f72aae5..13ace7ae64b 100644
--- a/packages/js/email-editor/src/store/selectors.ts
+++ b/packages/js/email-editor/src/store/selectors.ts
@@ -475,3 +475,7 @@ export function getContentValidation(
 ): State[ 'contentValidation' ] {
 	return state.contentValidation;
 }
+
+export function isTemplateSelected( state: State ): boolean {
+	return state.templateSelected;
+}
diff --git a/packages/js/email-editor/src/store/types.ts b/packages/js/email-editor/src/store/types.ts
index 14f53960d3d..0f33a36c136 100644
--- a/packages/js/email-editor/src/store/types.ts
+++ b/packages/js/email-editor/src/store/types.ts
@@ -140,6 +140,7 @@ export type State = {
 		errorMessage?: string;
 	};
 	contentValidation?: ContentValidation;
+	templateSelected: boolean;
 };

 export type EmailTemplatePreview = Omit<