From 57ec70f1d02d9293fc25dbb177fb5a4540e800d2 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 12:18:39 +0000 Subject: [PATCH 01/16] Move getItemTitle to its own file --- packages/editor/README.md | 12 +++++++++ .../post-actions/set-as-homepage.js | 17 +++---------- packages/editor/src/utils/get-item-title.js | 25 +++++++++++++++++++ packages/editor/src/utils/index.js | 1 + 4 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 packages/editor/src/utils/get-item-title.js diff --git a/packages/editor/README.md b/packages/editor/README.md index 3211e6664256d0..0be8cfd57cccde 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -439,6 +439,18 @@ getDerivedStateFromError is used to render a fallback UI after an error has been > **Deprecated** since 5.3, use `wp.blockEditor.getFontSizeClass` instead. +### getItemTitle + +Helper function to get the title of a post item. This is duplicated from the `@wordpress/fields` package. `packages/fields/src/actions/utils.ts` + +_Parameters_ + +- _item_ `Object`: The post item. + +_Returns_ + +- `string`: The title of the item, or an empty string if the title is not found. + ### getTemplatePartIcon Helper function to retrieve the corresponding icon by name. diff --git a/packages/editor/src/components/post-actions/set-as-homepage.js b/packages/editor/src/components/post-actions/set-as-homepage.js index 70bdeeeefe70fb..2773f03f6957dc 100644 --- a/packages/editor/src/components/post-actions/set-as-homepage.js +++ b/packages/editor/src/components/post-actions/set-as-homepage.js @@ -12,20 +12,11 @@ import { import { useDispatch, useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; import { store as noticesStore } from '@wordpress/notices'; -import { decodeEntities } from '@wordpress/html-entities'; -const getItemTitle = ( item ) => { - if ( typeof item.title === 'string' ) { - return decodeEntities( item.title ); - } - if ( item.title && 'rendered' in item.title ) { - return decodeEntities( item.title.rendered ); - } - if ( item.title && 'raw' in item.title ) { - return decodeEntities( item.title.raw ); - } - return ''; -}; +/** + * Internal dependencies + */ +import { getItemTitle } from '../../utils'; const SetAsHomepageModal = ( { items, closeModal } ) => { const [ item ] = items; diff --git a/packages/editor/src/utils/get-item-title.js b/packages/editor/src/utils/get-item-title.js new file mode 100644 index 00000000000000..86929c27408a81 --- /dev/null +++ b/packages/editor/src/utils/get-item-title.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { decodeEntities } from '@wordpress/html-entities'; + +/** + * Helper function to get the title of a post item. + * This is duplicated from the `@wordpress/fields` package. + * `packages/fields/src/actions/utils.ts` + * + * @param {Object} item The post item. + * @return {string} The title of the item, or an empty string if the title is not found. + */ +export function getItemTitle( item ) { + if ( typeof item.title === 'string' ) { + return decodeEntities( item.title ); + } + if ( item.title && 'rendered' in item.title ) { + return decodeEntities( item.title.rendered ); + } + if ( item.title && 'raw' in item.title ) { + return decodeEntities( item.title.raw ); + } + return ''; +} diff --git a/packages/editor/src/utils/index.js b/packages/editor/src/utils/index.js index d85892a57bd0a8..07a8d1676b4ff1 100644 --- a/packages/editor/src/utils/index.js +++ b/packages/editor/src/utils/index.js @@ -6,3 +6,4 @@ import mediaUpload from './media-upload'; export { mediaUpload }; export { cleanForSlug } from './url.js'; export { getTemplatePartIcon } from './get-template-part-icon'; +export { getItemTitle } from './get-item-title'; From fbc91d717d05711d11edee25945adf3281454de6 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 12:32:41 +0000 Subject: [PATCH 02/16] Add unset homepage action --- .../src/components/post-actions/actions.js | 10 +- .../post-actions/unset-as-homepage.js | 156 ++++++++++++++++++ 2 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 packages/editor/src/components/post-actions/unset-as-homepage.js diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 808134ea969a11..91ecea20a9d98c 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -11,6 +11,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useSetAsHomepageAction } from './set-as-homepage'; +import { useUnsetAsHomepageAction } from './unset-as-homepage'; export function usePostActions( { postType, onActionPerformed, context } ) { const { defaultActions } = useSelect( @@ -43,7 +44,8 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); const setAsHomepageAction = useSetAsHomepageAction(); - const shouldShowSetAsHomepageAction = + const unsetAsHomepageAction = useUnsetAsHomepageAction(); + const shouldShowHomepageActions = canManageOptions && ! hasFrontPageTemplate; const { registerPostTypeSchema } = unlock( useDispatch( editorStore ) ); @@ -53,8 +55,9 @@ export function usePostActions( { postType, onActionPerformed, context } ) { return useMemo( () => { let actions = [ ...defaultActions ]; - if ( shouldShowSetAsHomepageAction ) { + if ( shouldShowHomepageActions ) { actions.push( setAsHomepageAction ); + actions.push( unsetAsHomepageAction ); } // Filter actions based on provided context. If not provided @@ -123,6 +126,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { defaultActions, onActionPerformed, setAsHomepageAction, - shouldShowSetAsHomepageAction, + shouldShowHomepageActions, + unsetAsHomepageAction, ] ); } diff --git a/packages/editor/src/components/post-actions/unset-as-homepage.js b/packages/editor/src/components/post-actions/unset-as-homepage.js new file mode 100644 index 00000000000000..81fe6adf8ce766 --- /dev/null +++ b/packages/editor/src/components/post-actions/unset-as-homepage.js @@ -0,0 +1,156 @@ +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { useMemo } from '@wordpress/element'; +import { + Button, + __experimentalText as Text, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { getItemTitle } from '../../utils'; + +const UnsetAsHomepageModal = ( { items, closeModal } ) => { + const [ item ] = items; + const pageTitle = getItemTitle( item ); + const { isPageForPostsSet, currentHomePage, isSaving } = useSelect( + ( select ) => { + const { getEntityRecord, isSavingEntityRecord } = + select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + const currentHomePageItem = getEntityRecord( + 'postType', + 'page', + siteSettings?.page_on_front + ); + return { + isPageForPostsSet: siteSettings?.page_for_posts !== 0, + currentHomePage: currentHomePageItem, + isSaving: isSavingEntityRecord( 'root', 'site' ), + }; + } + ); + const currentHomePageTitle = currentHomePage + ? getItemTitle( currentHomePage ) + : ''; + + const { saveEditedEntityRecord, saveEntityRecord } = + useDispatch( coreStore ); + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + async function onUnsetPageAsHomepage( event ) { + event.preventDefault(); + + try { + // Save new home page settings. + await saveEditedEntityRecord( 'root', 'site', undefined, { + page_on_front: 0, + show_on_front: isPageForPostsSet ? 'page' : 'posts', + } ); + + // This second call to a save function is a workaround for a bug in + // `saveEditedEntityRecord`. This forces the root site settings to be updated. + // See https://github.com/WordPress/gutenberg/issues/67161. + await saveEntityRecord( 'root', 'site', { + page_on_front: 0, + show_on_front: isPageForPostsSet ? 'page' : 'posts', + } ); + + createSuccessNotice( __( 'Homepage unset' ), { + type: 'snackbar', + } ); + } catch ( error ) { + const typedError = error; + const errorMessage = + typedError.message && typedError.code !== 'unknown_error' + ? typedError.message + : __( 'An error occurred while unsetting the homepage' ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } finally { + closeModal?.(); + } + } + + const modalWarning = ! isPageForPostsSet + ? __( 'This will set the homepage to display latest posts.' ) + : sprintf( + // translators: %s: title of the current home page. + __( 'This will replace the current homepage: "%s"' ), + currentHomePageTitle + ); + + const modalText = sprintf( + // translators: %1$s: title of the page to be unset as the homepage, %2$s: homepage replacement warning message. + __( 'Unset "%1$s" as the site homepage? %2$s' ), + pageTitle, + modalWarning + ); + + // translators: Button label to confirm unsetting the specified page as the homepage. + const modalButtonLabel = __( 'Unset as homepage' ); + + return ( +
+ + { modalText } + + + + + +
+ ); +}; + +export const useUnsetAsHomepageAction = () => { + const { pageOnFront } = useSelect( ( select ) => { + const { getEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + return { + pageOnFront: siteSettings?.page_on_front, + }; + } ); + + return useMemo( + () => ( { + id: 'unset-as-homepage', + label: __( 'Unset as homepage' ), + isEligible( post ) { + if ( pageOnFront !== post.id ) { + return false; + } + + return true; + }, + RenderModal: UnsetAsHomepageModal, + } ), + [ pageOnFront ] + ); +}; From d42e0c1a272a4e595ac81c0744428620e4341276 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 13:23:12 +0000 Subject: [PATCH 03/16] Add unset as posts page action --- .../src/components/post-actions/actions.js | 10 +- .../post-actions/unset-as-posts-page.js | 140 ++++++++++++++++++ 2 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 packages/editor/src/components/post-actions/unset-as-posts-page.js diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 91ecea20a9d98c..827b51c4e2e33d 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -12,6 +12,7 @@ import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useSetAsHomepageAction } from './set-as-homepage'; import { useUnsetAsHomepageAction } from './unset-as-homepage'; +import { useUnsetAsPostsPageAction } from './unset-as-posts-page'; export function usePostActions( { postType, onActionPerformed, context } ) { const { defaultActions } = useSelect( @@ -45,6 +46,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { const setAsHomepageAction = useSetAsHomepageAction(); const unsetAsHomepageAction = useUnsetAsHomepageAction(); + const unsetAsPostsPageAction = useUnsetAsPostsPageAction(); const shouldShowHomepageActions = canManageOptions && ! hasFrontPageTemplate; @@ -56,8 +58,11 @@ export function usePostActions( { postType, onActionPerformed, context } ) { return useMemo( () => { let actions = [ ...defaultActions ]; if ( shouldShowHomepageActions ) { - actions.push( setAsHomepageAction ); - actions.push( unsetAsHomepageAction ); + actions.push( + setAsHomepageAction, + unsetAsHomepageAction, + unsetAsPostsPageAction + ); } // Filter actions based on provided context. If not provided @@ -128,5 +133,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) { setAsHomepageAction, shouldShowHomepageActions, unsetAsHomepageAction, + unsetAsPostsPageAction, ] ); } diff --git a/packages/editor/src/components/post-actions/unset-as-posts-page.js b/packages/editor/src/components/post-actions/unset-as-posts-page.js new file mode 100644 index 00000000000000..7d74521236ba21 --- /dev/null +++ b/packages/editor/src/components/post-actions/unset-as-posts-page.js @@ -0,0 +1,140 @@ +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { useMemo } from '@wordpress/element'; +import { + Button, + __experimentalText as Text, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { getItemTitle } from '../../utils'; + +const UnsetAsPostsPageModal = ( { items, closeModal } ) => { + const [ item ] = items; + const pageTitle = getItemTitle( item ); + const { isPageOnFrontSet, isSaving } = useSelect( ( select ) => { + const { getEntityRecord, isSavingEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + return { + isPageOnFrontSet: siteSettings?.page_on_front !== 0, + isSaving: isSavingEntityRecord( 'root', 'site' ), + }; + } ); + + const { saveEditedEntityRecord, saveEntityRecord } = + useDispatch( coreStore ); + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + async function onUnsetPageAsPostsPage( event ) { + event.preventDefault(); + + try { + // Save new posts page settings. + await saveEditedEntityRecord( 'root', 'site', undefined, { + page_for_posts: 0, + show_on_front: isPageOnFrontSet ? 'page' : 'posts', + } ); + + // This second call to a save function is a workaround for a bug in + // `saveEditedEntityRecord`. This forces the root site settings to be updated. + // See https://github.com/WordPress/gutenberg/issues/67161. + await saveEntityRecord( 'root', 'site', { + page_for_posts: 0, + show_on_front: isPageOnFrontSet ? 'page' : 'posts', + } ); + + createSuccessNotice( __( 'Posts page unset' ), { + type: 'snackbar', + } ); + } catch ( error ) { + const typedError = error; + const errorMessage = + typedError.message && typedError.code !== 'unknown_error' + ? typedError.message + : __( 'An error occurred while unsetting the posts page' ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } finally { + closeModal?.(); + } + } + + const modalWarning = ! isPageOnFrontSet + ? __( 'This will set the homepage to display latest posts.' ) + : ''; + + const modalText = sprintf( + // translators: %1$s: title of the page to be unset as the posts page, %2$s: post pages warning message. + __( 'Unset "%1$s" as the posts page? %2$s' ), + pageTitle, + modalWarning + ); + + // translators: Button label to confirm unsetting the specified page as the posts page. + const modalButtonLabel = __( 'Unset as posts page' ); + + return ( +
+ + { modalText } + + + + + +
+ ); +}; + +export const useUnsetAsPostsPageAction = () => { + const { pageForPosts } = useSelect( ( select ) => { + const { getEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + return { + pageForPosts: siteSettings?.page_for_posts, + }; + } ); + + return useMemo( + () => ( { + id: 'unset-as-posts-page', + label: __( 'Unset as posts page' ), + isEligible( post ) { + if ( pageForPosts !== post.id ) { + return false; + } + + return true; + }, + RenderModal: UnsetAsPostsPageModal, + } ), + [ pageForPosts ] + ); +}; From 4a90867954292e9ead73d968c48848db18a4f662 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 14:57:50 +0000 Subject: [PATCH 04/16] Add set as posts page action --- .../src/components/post-actions/actions.js | 4 + .../post-actions/set-as-posts-page.js | 171 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 packages/editor/src/components/post-actions/set-as-posts-page.js diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 827b51c4e2e33d..fab6e8d7062085 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -12,6 +12,7 @@ import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useSetAsHomepageAction } from './set-as-homepage'; import { useUnsetAsHomepageAction } from './unset-as-homepage'; +import { useSetAsPostsPageAction } from './set-as-posts-page'; import { useUnsetAsPostsPageAction } from './unset-as-posts-page'; export function usePostActions( { postType, onActionPerformed, context } ) { @@ -46,6 +47,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { const setAsHomepageAction = useSetAsHomepageAction(); const unsetAsHomepageAction = useUnsetAsHomepageAction(); + const setAsPostsPageAction = useSetAsPostsPageAction(); const unsetAsPostsPageAction = useUnsetAsPostsPageAction(); const shouldShowHomepageActions = canManageOptions && ! hasFrontPageTemplate; @@ -61,6 +63,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { actions.push( setAsHomepageAction, unsetAsHomepageAction, + setAsPostsPageAction, unsetAsPostsPageAction ); } @@ -131,6 +134,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { defaultActions, onActionPerformed, setAsHomepageAction, + setAsPostsPageAction, shouldShowHomepageActions, unsetAsHomepageAction, unsetAsPostsPageAction, diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js new file mode 100644 index 00000000000000..a714e174c418be --- /dev/null +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -0,0 +1,171 @@ +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { useMemo } from '@wordpress/element'; +import { + Button, + __experimentalText as Text, + __experimentalHStack as HStack, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { getItemTitle } from '../../utils'; + +const SetAsPostsPageModal = ( { items, closeModal } ) => { + const [ item ] = items; + const pageTitle = getItemTitle( item ); + const { currentPostsPage, isPageForPostsSet, isSaving } = useSelect( + ( select ) => { + const { getEntityRecord, isSavingEntityRecord } = + select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + const currentPostsPageItem = getEntityRecord( + 'postType', + 'page', + siteSettings?.page_for_posts + ); + return { + currentPostsPage: currentPostsPageItem, + isPageForPostsSet: siteSettings?.page_for_posts !== 0, + isSaving: isSavingEntityRecord( 'root', 'site' ), + }; + } + ); + const currentPostsPageTitle = currentPostsPage + ? getItemTitle( currentPostsPage ) + : ''; + + const { saveEditedEntityRecord, saveEntityRecord } = + useDispatch( coreStore ); + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + async function onSetPageAsPostsPage( event ) { + event.preventDefault(); + + try { + // Save new posts page settings. + await saveEditedEntityRecord( 'root', 'site', undefined, { + page_for_posts: item.id, + show_on_front: 'page', + } ); + + // This second call to a save function is a workaround for a bug in + // `saveEditedEntityRecord`. This forces the root site settings to be updated. + // See https://github.com/WordPress/gutenberg/issues/67161. + await saveEntityRecord( 'root', 'site', { + page_for_posts: item.id, + show_on_front: 'page', + } ); + + createSuccessNotice( __( 'Post page updated' ), { + type: 'snackbar', + } ); + } catch ( error ) { + const typedError = error; + const errorMessage = + typedError.message && typedError.code !== 'unknown_error' + ? typedError.message + : __( 'An error occurred while setting the posts page' ); + createErrorNotice( errorMessage, { type: 'snackbar' } ); + } finally { + closeModal?.(); + } + } + + const modalWarning = isPageForPostsSet + ? sprintf( + // translators: %s: title of the current home page. + __( 'This will replace the current posts page: "%s"' ), + currentPostsPageTitle + ) + : __( 'This page will show the latest posts.' ); + + const modalText = sprintf( + // translators: %1$s: title of the page to be set as the posts page, %2$s: posts page replacement warning message. + __( 'Set "%1$s" as the posts page? %2$s' ), + pageTitle, + modalWarning + ); + + // translators: Button label to confirm setting the specified page as the posts page. + const modalButtonLabel = __( 'Set posts page' ); + + return ( +
+ + { modalText } + + + + + +
+ ); +}; + +export const useSetAsPostsPageAction = () => { + const { pageOnFront, pageForPosts } = useSelect( ( select ) => { + const { getEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + return { + pageOnFront: siteSettings?.page_on_front, + pageForPosts: siteSettings?.page_for_posts, + }; + } ); + + return useMemo( + () => ( { + id: 'set-as-posts-page', + label: __( 'Set as posts page' ), + isEligible( post ) { + if ( post.status !== 'publish' ) { + return false; + } + + if ( post.type !== 'page' ) { + return false; + } + + // Don't show the action if the page is already set as the homepage. + if ( pageOnFront === post.id ) { + return false; + } + + // Don't show the action if the page is already set as the page for posts. + if ( pageForPosts === post.id ) { + return false; + } + + return true; + }, + RenderModal: SetAsPostsPageModal, + } ), + [ pageForPosts, pageOnFront ] + ); +}; From 4b29bcb6b0fddc85c951463c20b73e5491b267b5 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 15:34:46 +0000 Subject: [PATCH 05/16] Update homepage action tests --- .../site-editor/homepage-settings.spec.js | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/test/e2e/specs/site-editor/homepage-settings.spec.js b/test/e2e/specs/site-editor/homepage-settings.spec.js index d53130af23ac8b..4998a6068da5a2 100644 --- a/test/e2e/specs/site-editor/homepage-settings.spec.js +++ b/test/e2e/specs/site-editor/homepage-settings.spec.js @@ -10,6 +10,14 @@ test.describe( 'Homepage Settings via Editor', () => { title: 'Homepage', status: 'publish', } ); + await requestUtils.createPage( { + title: 'Sample page', + status: 'publish', + } ); + await requestUtils.createPage( { + title: 'Draft page', + status: 'draft', + } ); } ); test.beforeEach( async ( { admin, page } ) => { @@ -28,27 +36,30 @@ test.describe( 'Homepage Settings via Editor', () => { ] ); } ); - test( 'should show "Set as homepage" action on pages with `publish` status', async ( { + test( 'should not show "Set as homepage" and "Set as posts page" action on pages with `draft` status', async ( { page, } ) => { - const samplePage = page + const draftPage = page .getByRole( 'gridcell' ) - .getByLabel( 'Homepage' ); - const samplePageRow = page + .getByLabel( 'Draft page' ); + const draftPageRow = page .getByRole( 'row' ) - .filter( { has: samplePage } ); - await samplePageRow.hover(); - await samplePageRow + .filter( { has: draftPage } ); + await draftPageRow.hover(); + await draftPageRow .getByRole( 'button', { name: 'Actions', } ) .click(); await expect( page.getByRole( 'menuitem', { name: 'Set as homepage' } ) - ).toBeVisible(); + ).toBeHidden(); + await expect( + page.getByRole( 'menuitem', { name: 'Set as posts page' } ) + ).toBeHidden(); } ); - test( 'should not show "Set as homepage" action on current homepage', async ( { + test( 'should show correct homepage actions based on current homepage or posts page', async ( { page, } ) => { const samplePage = page @@ -68,5 +79,38 @@ test.describe( 'Homepage Settings via Editor', () => { await expect( page.getByRole( 'menuitem', { name: 'Set as homepage' } ) ).toBeHidden(); + await expect( + page.getByRole( 'menuitem', { name: 'Set as posts page' } ) + ).toBeHidden(); + await expect( + page.getByRole( 'menuitem', { name: 'Unset as homepage' } ) + ).toBeVisible(); + + const samplePageTwo = page + .getByRole( 'gridcell' ) + .getByLabel( 'Sample page' ); + const samplePageTwoRow = page + .getByRole( 'row' ) + .filter( { has: samplePageTwo } ); + // eslint-disable-next-line playwright/no-force-option + await samplePageTwoRow.click( { force: true } ); + await samplePageTwoRow + .getByRole( 'button', { + name: 'Actions', + } ) + .click(); + await page + .getByRole( 'menuitem', { name: 'Set as posts page' } ) + .click(); + await page.getByRole( 'button', { name: 'Set posts page' } ).click(); + await expect( + page.getByRole( 'menuitem', { name: 'Set as homepage' } ) + ).toBeHidden(); + await expect( + page.getByRole( 'menuitem', { name: 'Set as posts page' } ) + ).toBeHidden(); + await expect( + page.getByRole( 'menuitem', { name: 'Unset as posts page' } ) + ).toBeVisible(); } ); } ); From d892300b51b0b4cecdbe9a1ab8e510ede76f15e3 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 16:40:47 +0000 Subject: [PATCH 06/16] Rename unset options to reset --- .../src/components/post-actions/actions.js | 16 ++--- ...unset-as-homepage.js => reset-homepage.js} | 61 ++++++++----------- ...t-as-posts-page.js => reset-posts-page.js} | 26 ++++---- .../site-editor/homepage-settings.spec.js | 4 +- 4 files changed, 48 insertions(+), 59 deletions(-) rename packages/editor/src/components/post-actions/{unset-as-homepage.js => reset-homepage.js} (67%) rename packages/editor/src/components/post-actions/{unset-as-posts-page.js => reset-posts-page.js} (83%) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index fab6e8d7062085..d8da5cb51cf1d8 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -11,9 +11,9 @@ import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useSetAsHomepageAction } from './set-as-homepage'; -import { useUnsetAsHomepageAction } from './unset-as-homepage'; +import { useResetHomepageAction } from './reset-homepage'; import { useSetAsPostsPageAction } from './set-as-posts-page'; -import { useUnsetAsPostsPageAction } from './unset-as-posts-page'; +import { useResetPostsPageAction } from './reset-posts-page'; export function usePostActions( { postType, onActionPerformed, context } ) { const { defaultActions } = useSelect( @@ -46,9 +46,9 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); const setAsHomepageAction = useSetAsHomepageAction(); - const unsetAsHomepageAction = useUnsetAsHomepageAction(); + const resetHomepageAction = useResetHomepageAction(); const setAsPostsPageAction = useSetAsPostsPageAction(); - const unsetAsPostsPageAction = useUnsetAsPostsPageAction(); + const resetPostsPageAction = useResetPostsPageAction(); const shouldShowHomepageActions = canManageOptions && ! hasFrontPageTemplate; @@ -62,9 +62,9 @@ export function usePostActions( { postType, onActionPerformed, context } ) { if ( shouldShowHomepageActions ) { actions.push( setAsHomepageAction, - unsetAsHomepageAction, + resetHomepageAction, setAsPostsPageAction, - unsetAsPostsPageAction + resetPostsPageAction ); } @@ -133,10 +133,10 @@ export function usePostActions( { postType, onActionPerformed, context } ) { context, defaultActions, onActionPerformed, + resetHomepageAction, + resetPostsPageAction, setAsHomepageAction, setAsPostsPageAction, shouldShowHomepageActions, - unsetAsHomepageAction, - unsetAsPostsPageAction, ] ); } diff --git a/packages/editor/src/components/post-actions/unset-as-homepage.js b/packages/editor/src/components/post-actions/reset-homepage.js similarity index 67% rename from packages/editor/src/components/post-actions/unset-as-homepage.js rename to packages/editor/src/components/post-actions/reset-homepage.js index 81fe6adf8ce766..0a64d3faba059e 100644 --- a/packages/editor/src/components/post-actions/unset-as-homepage.js +++ b/packages/editor/src/components/post-actions/reset-homepage.js @@ -18,36 +18,25 @@ import { store as noticesStore } from '@wordpress/notices'; */ import { getItemTitle } from '../../utils'; -const UnsetAsHomepageModal = ( { items, closeModal } ) => { +const ResetHomepageModal = ( { items, closeModal } ) => { const [ item ] = items; const pageTitle = getItemTitle( item ); - const { isPageForPostsSet, currentHomePage, isSaving } = useSelect( - ( select ) => { - const { getEntityRecord, isSavingEntityRecord } = - select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - const currentHomePageItem = getEntityRecord( - 'postType', - 'page', - siteSettings?.page_on_front - ); - return { - isPageForPostsSet: siteSettings?.page_for_posts !== 0, - currentHomePage: currentHomePageItem, - isSaving: isSavingEntityRecord( 'root', 'site' ), - }; - } - ); - const currentHomePageTitle = currentHomePage - ? getItemTitle( currentHomePage ) - : ''; + const { isPageForPostsSet, isSaving } = useSelect( ( select ) => { + const { getEntityRecord, isSavingEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + + return { + isPageForPostsSet: siteSettings?.page_for_posts !== 0, + isSaving: isSavingEntityRecord( 'root', 'site' ), + }; + } ); const { saveEditedEntityRecord, saveEntityRecord } = useDispatch( coreStore ); const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); - async function onUnsetPageAsHomepage( event ) { + async function onResetHomepage( event ) { event.preventDefault(); try { @@ -65,7 +54,7 @@ const UnsetAsHomepageModal = ( { items, closeModal } ) => { show_on_front: isPageForPostsSet ? 'page' : 'posts', } ); - createSuccessNotice( __( 'Homepage unset' ), { + createSuccessNotice( __( 'Homepage reset' ), { type: 'snackbar', } ); } catch ( error ) { @@ -73,7 +62,7 @@ const UnsetAsHomepageModal = ( { items, closeModal } ) => { const errorMessage = typedError.message && typedError.code !== 'unknown_error' ? typedError.message - : __( 'An error occurred while unsetting the homepage' ); + : __( 'An error occurred while resetting the homepage' ); createErrorNotice( errorMessage, { type: 'snackbar' } ); } finally { closeModal?.(); @@ -82,24 +71,22 @@ const UnsetAsHomepageModal = ( { items, closeModal } ) => { const modalWarning = ! isPageForPostsSet ? __( 'This will set the homepage to display latest posts.' ) - : sprintf( - // translators: %s: title of the current home page. - __( 'This will replace the current homepage: "%s"' ), - currentHomePageTitle - ); + : ''; const modalText = sprintf( // translators: %1$s: title of the page to be unset as the homepage, %2$s: homepage replacement warning message. - __( 'Unset "%1$s" as the site homepage? %2$s' ), + __( + 'Reset the site homepage? "%1$s" will no longer be set as the homepage. %2$s' + ), pageTitle, modalWarning ); - // translators: Button label to confirm unsetting the specified page as the homepage. - const modalButtonLabel = __( 'Unset as homepage' ); + // translators: Button label to confirm resetting the homepage. + const modalButtonLabel = __( 'Reset homepage' ); return ( -
+ { modalText } @@ -129,7 +116,7 @@ const UnsetAsHomepageModal = ( { items, closeModal } ) => { ); }; -export const useUnsetAsHomepageAction = () => { +export const useResetHomepageAction = () => { const { pageOnFront } = useSelect( ( select ) => { const { getEntityRecord } = select( coreStore ); const siteSettings = getEntityRecord( 'root', 'site' ); @@ -140,8 +127,8 @@ export const useUnsetAsHomepageAction = () => { return useMemo( () => ( { - id: 'unset-as-homepage', - label: __( 'Unset as homepage' ), + id: 'reset-homepage', + label: __( 'Reset homepage' ), isEligible( post ) { if ( pageOnFront !== post.id ) { return false; @@ -149,7 +136,7 @@ export const useUnsetAsHomepageAction = () => { return true; }, - RenderModal: UnsetAsHomepageModal, + RenderModal: ResetHomepageModal, } ), [ pageOnFront ] ); diff --git a/packages/editor/src/components/post-actions/unset-as-posts-page.js b/packages/editor/src/components/post-actions/reset-posts-page.js similarity index 83% rename from packages/editor/src/components/post-actions/unset-as-posts-page.js rename to packages/editor/src/components/post-actions/reset-posts-page.js index 7d74521236ba21..c276fda422f757 100644 --- a/packages/editor/src/components/post-actions/unset-as-posts-page.js +++ b/packages/editor/src/components/post-actions/reset-posts-page.js @@ -18,7 +18,7 @@ import { store as noticesStore } from '@wordpress/notices'; */ import { getItemTitle } from '../../utils'; -const UnsetAsPostsPageModal = ( { items, closeModal } ) => { +const ResetPostsPageModal = ( { items, closeModal } ) => { const [ item ] = items; const pageTitle = getItemTitle( item ); const { isPageOnFrontSet, isSaving } = useSelect( ( select ) => { @@ -35,7 +35,7 @@ const UnsetAsPostsPageModal = ( { items, closeModal } ) => { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); - async function onUnsetPageAsPostsPage( event ) { + async function onResetPostsPage( event ) { event.preventDefault(); try { @@ -53,7 +53,7 @@ const UnsetAsPostsPageModal = ( { items, closeModal } ) => { show_on_front: isPageOnFrontSet ? 'page' : 'posts', } ); - createSuccessNotice( __( 'Posts page unset' ), { + createSuccessNotice( __( 'Posts page reset' ), { type: 'snackbar', } ); } catch ( error ) { @@ -61,7 +61,7 @@ const UnsetAsPostsPageModal = ( { items, closeModal } ) => { const errorMessage = typedError.message && typedError.code !== 'unknown_error' ? typedError.message - : __( 'An error occurred while unsetting the posts page' ); + : __( 'An error occurred while resetting the posts page' ); createErrorNotice( errorMessage, { type: 'snackbar' } ); } finally { closeModal?.(); @@ -74,16 +74,18 @@ const UnsetAsPostsPageModal = ( { items, closeModal } ) => { const modalText = sprintf( // translators: %1$s: title of the page to be unset as the posts page, %2$s: post pages warning message. - __( 'Unset "%1$s" as the posts page? %2$s' ), + __( + 'Reset the posts page? "%1$s" will no longer be the posts page. %2$s' + ), pageTitle, modalWarning ); - // translators: Button label to confirm unsetting the specified page as the posts page. - const modalButtonLabel = __( 'Unset as posts page' ); + // translators: Button label to confirm resetting the posts page. + const modalButtonLabel = __( 'Reset posts page' ); return ( - + { modalText } @@ -113,7 +115,7 @@ const UnsetAsPostsPageModal = ( { items, closeModal } ) => { ); }; -export const useUnsetAsPostsPageAction = () => { +export const useResetPostsPageAction = () => { const { pageForPosts } = useSelect( ( select ) => { const { getEntityRecord } = select( coreStore ); const siteSettings = getEntityRecord( 'root', 'site' ); @@ -124,8 +126,8 @@ export const useUnsetAsPostsPageAction = () => { return useMemo( () => ( { - id: 'unset-as-posts-page', - label: __( 'Unset as posts page' ), + id: 'reset-posts-page', + label: __( 'Reset posts page' ), isEligible( post ) { if ( pageForPosts !== post.id ) { return false; @@ -133,7 +135,7 @@ export const useUnsetAsPostsPageAction = () => { return true; }, - RenderModal: UnsetAsPostsPageModal, + RenderModal: ResetPostsPageModal, } ), [ pageForPosts ] ); diff --git a/test/e2e/specs/site-editor/homepage-settings.spec.js b/test/e2e/specs/site-editor/homepage-settings.spec.js index 4998a6068da5a2..615a2892e48f21 100644 --- a/test/e2e/specs/site-editor/homepage-settings.spec.js +++ b/test/e2e/specs/site-editor/homepage-settings.spec.js @@ -83,7 +83,7 @@ test.describe( 'Homepage Settings via Editor', () => { page.getByRole( 'menuitem', { name: 'Set as posts page' } ) ).toBeHidden(); await expect( - page.getByRole( 'menuitem', { name: 'Unset as homepage' } ) + page.getByRole( 'menuitem', { name: 'Reset homepage' } ) ).toBeVisible(); const samplePageTwo = page @@ -110,7 +110,7 @@ test.describe( 'Homepage Settings via Editor', () => { page.getByRole( 'menuitem', { name: 'Set as posts page' } ) ).toBeHidden(); await expect( - page.getByRole( 'menuitem', { name: 'Unset as posts page' } ) + page.getByRole( 'menuitem', { name: 'Reset posts page' } ) ).toBeVisible(); } ); } ); From f68a1898f75b7496209a11759acf8ce0d31f16e4 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 5 Dec 2024 16:46:40 +0000 Subject: [PATCH 07/16] Reword posts page reset notice --- packages/editor/src/components/post-actions/reset-posts-page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/post-actions/reset-posts-page.js b/packages/editor/src/components/post-actions/reset-posts-page.js index c276fda422f757..fa0dea87f820e3 100644 --- a/packages/editor/src/components/post-actions/reset-posts-page.js +++ b/packages/editor/src/components/post-actions/reset-posts-page.js @@ -75,7 +75,7 @@ const ResetPostsPageModal = ( { items, closeModal } ) => { const modalText = sprintf( // translators: %1$s: title of the page to be unset as the posts page, %2$s: post pages warning message. __( - 'Reset the posts page? "%1$s" will no longer be the posts page. %2$s' + 'Reset the posts page? "%1$s" will no longer show the latest posts. %2$s' ), pageTitle, modalWarning From 2cc8058630b74eff7ea8554d15d00dabf9520e12 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Fri, 6 Dec 2024 15:59:55 +0000 Subject: [PATCH 08/16] Ensure Move to trash is always at end of list --- packages/editor/src/components/post-actions/actions.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index d8da5cb51cf1d8..e26bbd28222b62 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -68,6 +68,14 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); } + // Ensure "Move to trash" is always the last action. + actions = actions.sort( ( a, b ) => { + if ( b.id === 'move-to-trash' ) { + return -1; + } + return 0; + } ); + // Filter actions based on provided context. If not provided // all actions are returned. We'll have a single entry for getting the actions // and the consumer should provide the context to filter the actions, if needed. From 61c7d4802cc3aa1ecc6a8e628aef6f88d5bc4a66 Mon Sep 17 00:00:00 2001 From: Sarah Norris <1645628+mikachan@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:04:11 +0000 Subject: [PATCH 09/16] Update packages/editor/src/components/post-actions/actions.js Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com> --- packages/editor/src/components/post-actions/actions.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index e26bbd28222b62..b356c769e4b544 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -69,12 +69,9 @@ export function usePostActions( { postType, onActionPerformed, context } ) { } // Ensure "Move to trash" is always the last action. - actions = actions.sort( ( a, b ) => { - if ( b.id === 'move-to-trash' ) { - return -1; - } - return 0; - } ); + actions = actions.sort( ( a, b ) => + b.id === 'move-to-trash' ? -1 : 0 + ); // Filter actions based on provided context. If not provided // all actions are returned. We'll have a single entry for getting the actions From 711f65cb4069bb17abca9e63cd6af87c4b050b12 Mon Sep 17 00:00:00 2001 From: Sarah Norris <1645628+mikachan@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:05:20 +0000 Subject: [PATCH 10/16] Update packages/editor/src/components/post-actions/reset-homepage.js Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com> --- .../editor/src/components/post-actions/reset-homepage.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/editor/src/components/post-actions/reset-homepage.js b/packages/editor/src/components/post-actions/reset-homepage.js index 0a64d3faba059e..ff165cef9caddb 100644 --- a/packages/editor/src/components/post-actions/reset-homepage.js +++ b/packages/editor/src/components/post-actions/reset-homepage.js @@ -130,11 +130,7 @@ export const useResetHomepageAction = () => { id: 'reset-homepage', label: __( 'Reset homepage' ), isEligible( post ) { - if ( pageOnFront !== post.id ) { - return false; - } - - return true; + return pageOnFront === post.id; }, RenderModal: ResetHomepageModal, } ), From 30a7f2acb1cd2c784655f3436ce2b081dcaafd41 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Tue, 10 Dec 2024 12:04:23 +0000 Subject: [PATCH 11/16] Remove getItemTitle from utils index.js --- packages/editor/README.md | 12 ------------ .../src/components/post-actions/reset-homepage.js | 2 +- .../src/components/post-actions/reset-posts-page.js | 2 +- .../src/components/post-actions/set-as-homepage.js | 2 +- .../src/components/post-actions/set-as-posts-page.js | 2 +- packages/editor/src/utils/index.js | 1 - 6 files changed, 4 insertions(+), 17 deletions(-) diff --git a/packages/editor/README.md b/packages/editor/README.md index 0be8cfd57cccde..3211e6664256d0 100644 --- a/packages/editor/README.md +++ b/packages/editor/README.md @@ -439,18 +439,6 @@ getDerivedStateFromError is used to render a fallback UI after an error has been > **Deprecated** since 5.3, use `wp.blockEditor.getFontSizeClass` instead. -### getItemTitle - -Helper function to get the title of a post item. This is duplicated from the `@wordpress/fields` package. `packages/fields/src/actions/utils.ts` - -_Parameters_ - -- _item_ `Object`: The post item. - -_Returns_ - -- `string`: The title of the item, or an empty string if the title is not found. - ### getTemplatePartIcon Helper function to retrieve the corresponding icon by name. diff --git a/packages/editor/src/components/post-actions/reset-homepage.js b/packages/editor/src/components/post-actions/reset-homepage.js index ff165cef9caddb..b7d8184b9702c4 100644 --- a/packages/editor/src/components/post-actions/reset-homepage.js +++ b/packages/editor/src/components/post-actions/reset-homepage.js @@ -16,7 +16,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ -import { getItemTitle } from '../../utils'; +import { getItemTitle } from '../../utils/get-item-title'; const ResetHomepageModal = ( { items, closeModal } ) => { const [ item ] = items; diff --git a/packages/editor/src/components/post-actions/reset-posts-page.js b/packages/editor/src/components/post-actions/reset-posts-page.js index fa0dea87f820e3..8042680e3a8cb0 100644 --- a/packages/editor/src/components/post-actions/reset-posts-page.js +++ b/packages/editor/src/components/post-actions/reset-posts-page.js @@ -16,7 +16,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ -import { getItemTitle } from '../../utils'; +import { getItemTitle } from '../../utils/get-item-title'; const ResetPostsPageModal = ( { items, closeModal } ) => { const [ item ] = items; diff --git a/packages/editor/src/components/post-actions/set-as-homepage.js b/packages/editor/src/components/post-actions/set-as-homepage.js index 2773f03f6957dc..d2e61a09dbaba0 100644 --- a/packages/editor/src/components/post-actions/set-as-homepage.js +++ b/packages/editor/src/components/post-actions/set-as-homepage.js @@ -16,7 +16,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ -import { getItemTitle } from '../../utils'; +import { getItemTitle } from '../../utils/get-item-title'; const SetAsHomepageModal = ( { items, closeModal } ) => { const [ item ] = items; diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js index a714e174c418be..a67f49007bcd5a 100644 --- a/packages/editor/src/components/post-actions/set-as-posts-page.js +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -16,7 +16,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ -import { getItemTitle } from '../../utils'; +import { getItemTitle } from '../../utils/get-item-title'; const SetAsPostsPageModal = ( { items, closeModal } ) => { const [ item ] = items; diff --git a/packages/editor/src/utils/index.js b/packages/editor/src/utils/index.js index 07a8d1676b4ff1..d85892a57bd0a8 100644 --- a/packages/editor/src/utils/index.js +++ b/packages/editor/src/utils/index.js @@ -6,4 +6,3 @@ import mediaUpload from './media-upload'; export { mediaUpload }; export { cleanForSlug } from './url.js'; export { getTemplatePartIcon } from './get-template-part-icon'; -export { getItemTitle } from './get-item-title'; From 8ef850cf1bcaa43a556019ca5b41e9cc3092ade0 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Wed, 11 Dec 2024 14:44:28 +0000 Subject: [PATCH 12/16] Remove reset actions --- .../src/components/post-actions/actions.js | 13 +- .../components/post-actions/reset-homepage.js | 139 ----------------- .../post-actions/reset-posts-page.js | 142 ------------------ .../site-editor/homepage-settings.spec.js | 6 - 4 files changed, 1 insertion(+), 299 deletions(-) delete mode 100644 packages/editor/src/components/post-actions/reset-homepage.js delete mode 100644 packages/editor/src/components/post-actions/reset-posts-page.js diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index b356c769e4b544..023b93d31bb511 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -11,9 +11,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useSetAsHomepageAction } from './set-as-homepage'; -import { useResetHomepageAction } from './reset-homepage'; import { useSetAsPostsPageAction } from './set-as-posts-page'; -import { useResetPostsPageAction } from './reset-posts-page'; export function usePostActions( { postType, onActionPerformed, context } ) { const { defaultActions } = useSelect( @@ -46,9 +44,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); const setAsHomepageAction = useSetAsHomepageAction(); - const resetHomepageAction = useResetHomepageAction(); const setAsPostsPageAction = useSetAsPostsPageAction(); - const resetPostsPageAction = useResetPostsPageAction(); const shouldShowHomepageActions = canManageOptions && ! hasFrontPageTemplate; @@ -60,12 +56,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { return useMemo( () => { let actions = [ ...defaultActions ]; if ( shouldShowHomepageActions ) { - actions.push( - setAsHomepageAction, - resetHomepageAction, - setAsPostsPageAction, - resetPostsPageAction - ); + actions.push( setAsHomepageAction, setAsPostsPageAction ); } // Ensure "Move to trash" is always the last action. @@ -138,8 +129,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) { context, defaultActions, onActionPerformed, - resetHomepageAction, - resetPostsPageAction, setAsHomepageAction, setAsPostsPageAction, shouldShowHomepageActions, diff --git a/packages/editor/src/components/post-actions/reset-homepage.js b/packages/editor/src/components/post-actions/reset-homepage.js deleted file mode 100644 index b7d8184b9702c4..00000000000000 --- a/packages/editor/src/components/post-actions/reset-homepage.js +++ /dev/null @@ -1,139 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { useMemo } from '@wordpress/element'; -import { - Button, - __experimentalText as Text, - __experimentalHStack as HStack, - __experimentalVStack as VStack, -} from '@wordpress/components'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; -import { store as noticesStore } from '@wordpress/notices'; - -/** - * Internal dependencies - */ -import { getItemTitle } from '../../utils/get-item-title'; - -const ResetHomepageModal = ( { items, closeModal } ) => { - const [ item ] = items; - const pageTitle = getItemTitle( item ); - const { isPageForPostsSet, isSaving } = useSelect( ( select ) => { - const { getEntityRecord, isSavingEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - - return { - isPageForPostsSet: siteSettings?.page_for_posts !== 0, - isSaving: isSavingEntityRecord( 'root', 'site' ), - }; - } ); - - const { saveEditedEntityRecord, saveEntityRecord } = - useDispatch( coreStore ); - const { createSuccessNotice, createErrorNotice } = - useDispatch( noticesStore ); - - async function onResetHomepage( event ) { - event.preventDefault(); - - try { - // Save new home page settings. - await saveEditedEntityRecord( 'root', 'site', undefined, { - page_on_front: 0, - show_on_front: isPageForPostsSet ? 'page' : 'posts', - } ); - - // This second call to a save function is a workaround for a bug in - // `saveEditedEntityRecord`. This forces the root site settings to be updated. - // See https://github.com/WordPress/gutenberg/issues/67161. - await saveEntityRecord( 'root', 'site', { - page_on_front: 0, - show_on_front: isPageForPostsSet ? 'page' : 'posts', - } ); - - createSuccessNotice( __( 'Homepage reset' ), { - type: 'snackbar', - } ); - } catch ( error ) { - const typedError = error; - const errorMessage = - typedError.message && typedError.code !== 'unknown_error' - ? typedError.message - : __( 'An error occurred while resetting the homepage' ); - createErrorNotice( errorMessage, { type: 'snackbar' } ); - } finally { - closeModal?.(); - } - } - - const modalWarning = ! isPageForPostsSet - ? __( 'This will set the homepage to display latest posts.' ) - : ''; - - const modalText = sprintf( - // translators: %1$s: title of the page to be unset as the homepage, %2$s: homepage replacement warning message. - __( - 'Reset the site homepage? "%1$s" will no longer be set as the homepage. %2$s' - ), - pageTitle, - modalWarning - ); - - // translators: Button label to confirm resetting the homepage. - const modalButtonLabel = __( 'Reset homepage' ); - - return ( - - - { modalText } - - - - - - - ); -}; - -export const useResetHomepageAction = () => { - const { pageOnFront } = useSelect( ( select ) => { - const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - return { - pageOnFront: siteSettings?.page_on_front, - }; - } ); - - return useMemo( - () => ( { - id: 'reset-homepage', - label: __( 'Reset homepage' ), - isEligible( post ) { - return pageOnFront === post.id; - }, - RenderModal: ResetHomepageModal, - } ), - [ pageOnFront ] - ); -}; diff --git a/packages/editor/src/components/post-actions/reset-posts-page.js b/packages/editor/src/components/post-actions/reset-posts-page.js deleted file mode 100644 index 8042680e3a8cb0..00000000000000 --- a/packages/editor/src/components/post-actions/reset-posts-page.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; -import { useMemo } from '@wordpress/element'; -import { - Button, - __experimentalText as Text, - __experimentalHStack as HStack, - __experimentalVStack as VStack, -} from '@wordpress/components'; -import { useDispatch, useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; -import { store as noticesStore } from '@wordpress/notices'; - -/** - * Internal dependencies - */ -import { getItemTitle } from '../../utils/get-item-title'; - -const ResetPostsPageModal = ( { items, closeModal } ) => { - const [ item ] = items; - const pageTitle = getItemTitle( item ); - const { isPageOnFrontSet, isSaving } = useSelect( ( select ) => { - const { getEntityRecord, isSavingEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - return { - isPageOnFrontSet: siteSettings?.page_on_front !== 0, - isSaving: isSavingEntityRecord( 'root', 'site' ), - }; - } ); - - const { saveEditedEntityRecord, saveEntityRecord } = - useDispatch( coreStore ); - const { createSuccessNotice, createErrorNotice } = - useDispatch( noticesStore ); - - async function onResetPostsPage( event ) { - event.preventDefault(); - - try { - // Save new posts page settings. - await saveEditedEntityRecord( 'root', 'site', undefined, { - page_for_posts: 0, - show_on_front: isPageOnFrontSet ? 'page' : 'posts', - } ); - - // This second call to a save function is a workaround for a bug in - // `saveEditedEntityRecord`. This forces the root site settings to be updated. - // See https://github.com/WordPress/gutenberg/issues/67161. - await saveEntityRecord( 'root', 'site', { - page_for_posts: 0, - show_on_front: isPageOnFrontSet ? 'page' : 'posts', - } ); - - createSuccessNotice( __( 'Posts page reset' ), { - type: 'snackbar', - } ); - } catch ( error ) { - const typedError = error; - const errorMessage = - typedError.message && typedError.code !== 'unknown_error' - ? typedError.message - : __( 'An error occurred while resetting the posts page' ); - createErrorNotice( errorMessage, { type: 'snackbar' } ); - } finally { - closeModal?.(); - } - } - - const modalWarning = ! isPageOnFrontSet - ? __( 'This will set the homepage to display latest posts.' ) - : ''; - - const modalText = sprintf( - // translators: %1$s: title of the page to be unset as the posts page, %2$s: post pages warning message. - __( - 'Reset the posts page? "%1$s" will no longer show the latest posts. %2$s' - ), - pageTitle, - modalWarning - ); - - // translators: Button label to confirm resetting the posts page. - const modalButtonLabel = __( 'Reset posts page' ); - - return ( -
- - { modalText } - - - - - -
- ); -}; - -export const useResetPostsPageAction = () => { - const { pageForPosts } = useSelect( ( select ) => { - const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); - return { - pageForPosts: siteSettings?.page_for_posts, - }; - } ); - - return useMemo( - () => ( { - id: 'reset-posts-page', - label: __( 'Reset posts page' ), - isEligible( post ) { - if ( pageForPosts !== post.id ) { - return false; - } - - return true; - }, - RenderModal: ResetPostsPageModal, - } ), - [ pageForPosts ] - ); -}; diff --git a/test/e2e/specs/site-editor/homepage-settings.spec.js b/test/e2e/specs/site-editor/homepage-settings.spec.js index 615a2892e48f21..e80e14830364ce 100644 --- a/test/e2e/specs/site-editor/homepage-settings.spec.js +++ b/test/e2e/specs/site-editor/homepage-settings.spec.js @@ -82,9 +82,6 @@ test.describe( 'Homepage Settings via Editor', () => { await expect( page.getByRole( 'menuitem', { name: 'Set as posts page' } ) ).toBeHidden(); - await expect( - page.getByRole( 'menuitem', { name: 'Reset homepage' } ) - ).toBeVisible(); const samplePageTwo = page .getByRole( 'gridcell' ) @@ -109,8 +106,5 @@ test.describe( 'Homepage Settings via Editor', () => { await expect( page.getByRole( 'menuitem', { name: 'Set as posts page' } ) ).toBeHidden(); - await expect( - page.getByRole( 'menuitem', { name: 'Reset posts page' } ) - ).toBeVisible(); } ); } ); From bc1b21829bee24f33fc69470df0449a527994acf Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Wed, 11 Dec 2024 14:49:20 +0000 Subject: [PATCH 13/16] Slight refactor to modal warning in set as posts page action --- .../editor/src/components/post-actions/set-as-posts-page.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js index a67f49007bcd5a..91d1fdd7fbcccf 100644 --- a/packages/editor/src/components/post-actions/set-as-posts-page.js +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -38,9 +38,6 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { }; } ); - const currentPostsPageTitle = currentPostsPage - ? getItemTitle( currentPostsPage ) - : ''; const { saveEditedEntityRecord, saveEntityRecord } = useDispatch( coreStore ); @@ -84,7 +81,7 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { ? sprintf( // translators: %s: title of the current home page. __( 'This will replace the current posts page: "%s"' ), - currentPostsPageTitle + getItemTitle( currentPostsPage ) ) : __( 'This page will show the latest posts.' ); From 2cfd8172456f9e5679c408519db73efb696f532c Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Wed, 11 Dec 2024 15:44:48 +0000 Subject: [PATCH 14/16] Remove use of saveEditedEntityRecord --- .../post-actions/set-as-homepage.js | 19 ++++--------------- .../post-actions/set-as-posts-page.js | 19 ++++--------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/packages/editor/src/components/post-actions/set-as-homepage.js b/packages/editor/src/components/post-actions/set-as-homepage.js index 9b905755709772..d250b68b459a83 100644 --- a/packages/editor/src/components/post-actions/set-as-homepage.js +++ b/packages/editor/src/components/post-actions/set-as-homepage.js @@ -39,8 +39,7 @@ const SetAsHomepageModal = ( { items, closeModal } ) => { } ); - const { saveEditedEntityRecord, saveEntityRecord } = - useDispatch( coreStore ); + const { saveEntityRecord } = useDispatch( coreStore ); const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); @@ -48,15 +47,6 @@ const SetAsHomepageModal = ( { items, closeModal } ) => { event.preventDefault(); try { - // Save new home page settings. - await saveEditedEntityRecord( 'root', 'site', undefined, { - page_on_front: item.id, - show_on_front: 'page', - } ); - - // This second call to a save function is a workaround for a bug in - // `saveEditedEntityRecord`. This forces the root site settings to be updated. - // See https://github.com/WordPress/gutenberg/issues/67161. await saveEntityRecord( 'root', 'site', { page_on_front: item.id, show_on_front: 'page', @@ -66,11 +56,10 @@ const SetAsHomepageModal = ( { items, closeModal } ) => { type: 'snackbar', } ); } catch ( error ) { - const typedError = error; const errorMessage = - typedError.message && typedError.code !== 'unknown_error' - ? typedError.message - : __( 'An error occurred while setting the homepage' ); + error.message && error.code !== 'unknown_error' + ? error.message + : __( 'An error occurred while setting the homepage.' ); createErrorNotice( errorMessage, { type: 'snackbar' } ); } finally { closeModal?.(); diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js index 91d1fdd7fbcccf..12edd47c68d889 100644 --- a/packages/editor/src/components/post-actions/set-as-posts-page.js +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -39,8 +39,7 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { } ); - const { saveEditedEntityRecord, saveEntityRecord } = - useDispatch( coreStore ); + const { saveEntityRecord } = useDispatch( coreStore ); const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); @@ -48,15 +47,6 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { event.preventDefault(); try { - // Save new posts page settings. - await saveEditedEntityRecord( 'root', 'site', undefined, { - page_for_posts: item.id, - show_on_front: 'page', - } ); - - // This second call to a save function is a workaround for a bug in - // `saveEditedEntityRecord`. This forces the root site settings to be updated. - // See https://github.com/WordPress/gutenberg/issues/67161. await saveEntityRecord( 'root', 'site', { page_for_posts: item.id, show_on_front: 'page', @@ -66,11 +56,10 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { type: 'snackbar', } ); } catch ( error ) { - const typedError = error; const errorMessage = - typedError.message && typedError.code !== 'unknown_error' - ? typedError.message - : __( 'An error occurred while setting the posts page' ); + error.message && error.code !== 'unknown_error' + ? error.message + : __( 'An error occurred while setting the posts page.' ); createErrorNotice( errorMessage, { type: 'snackbar' } ); } finally { closeModal?.(); From f60fa362f9c97b8b465ee740ecbf9feb1f3dc4e1 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 12 Dec 2024 10:21:40 +0000 Subject: [PATCH 15/16] Check for currentPostsPage before setting modalwarning --- .../components/post-actions/set-as-posts-page.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js index 12edd47c68d889..1d35d3a1fe2efa 100644 --- a/packages/editor/src/components/post-actions/set-as-posts-page.js +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -66,13 +66,14 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { } } - const modalWarning = isPageForPostsSet - ? sprintf( - // translators: %s: title of the current home page. - __( 'This will replace the current posts page: "%s"' ), - getItemTitle( currentPostsPage ) - ) - : __( 'This page will show the latest posts.' ); + const modalWarning = + isPageForPostsSet && currentPostsPage + ? sprintf( + // translators: %s: title of the current posts page. + __( 'This will replace the current posts page: "%s"' ), + getItemTitle( currentPostsPage ) + ) + : __( 'This page will show the latest posts.' ); const modalText = sprintf( // translators: %1$s: title of the page to be set as the posts page, %2$s: posts page replacement warning message. From 35cea15fecb652b2ba67cd6ecd110a0d7b22ea60 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Thu, 12 Dec 2024 10:53:23 +0000 Subject: [PATCH 16/16] Add full stop to action success notices --- packages/editor/src/components/post-actions/set-as-homepage.js | 2 +- .../editor/src/components/post-actions/set-as-posts-page.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/post-actions/set-as-homepage.js b/packages/editor/src/components/post-actions/set-as-homepage.js index d250b68b459a83..671906575b4123 100644 --- a/packages/editor/src/components/post-actions/set-as-homepage.js +++ b/packages/editor/src/components/post-actions/set-as-homepage.js @@ -52,7 +52,7 @@ const SetAsHomepageModal = ( { items, closeModal } ) => { show_on_front: 'page', } ); - createSuccessNotice( __( 'Homepage updated' ), { + createSuccessNotice( __( 'Homepage updated.' ), { type: 'snackbar', } ); } catch ( error ) { diff --git a/packages/editor/src/components/post-actions/set-as-posts-page.js b/packages/editor/src/components/post-actions/set-as-posts-page.js index 1d35d3a1fe2efa..67c42a7991fe45 100644 --- a/packages/editor/src/components/post-actions/set-as-posts-page.js +++ b/packages/editor/src/components/post-actions/set-as-posts-page.js @@ -52,7 +52,7 @@ const SetAsPostsPageModal = ( { items, closeModal } ) => { show_on_front: 'page', } ); - createSuccessNotice( __( 'Post page updated' ), { + createSuccessNotice( __( 'Posts page updated.' ), { type: 'snackbar', } ); } catch ( error ) {