From 8bde58f77b7f69f15c27a8f97ded36f3b8cbdea5 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 23 May 2024 18:06:47 +0300 Subject: [PATCH 1/4] Consolidate and fix `delete` and `edit` post actions --- .../edit-post/src/components/layout/index.js | 2 +- .../src/components/dataviews-actions/index.js | 17 +- .../edit-site/src/components/editor/index.js | 2 +- .../src/components/post-actions/actions.js | 383 +++++------------- 4 files changed, 113 insertions(+), 291 deletions(-) diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index fde9319a348daf..780c706ca83014 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -277,7 +277,7 @@ function Layout( { initialPost } ) { const onActionPerformed = useCallback( ( actionId, items ) => { switch ( actionId ) { - case 'move-to-trash': + case 'delete-post': { document.location.href = addQueryArgs( 'edit.php', { trashed: 1, diff --git a/packages/edit-site/src/components/dataviews-actions/index.js b/packages/edit-site/src/components/dataviews-actions/index.js index ed6522995d3b7b..27597c22421b9d 100644 --- a/packages/edit-site/src/components/dataviews-actions/index.js +++ b/packages/edit-site/src/components/dataviews-actions/index.js @@ -9,6 +9,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ +import { PATTERN_TYPES } from '../../utils/constants'; import { unlock } from '../../lock-unlock'; const { useHistory } = unlock( routerPrivateApis ); @@ -21,8 +22,20 @@ export const useEditPostAction = () => { label: __( 'Edit' ), isPrimary: true, icon: edit, - isEligible( { status } ) { - return status !== 'trash'; + isEligible( post ) { + if ( post.status === 'trash' ) { + return false; + } + // It's eligible for all post types except patterns. + if ( + ! [ ...Object.values( PATTERN_TYPES ) ].includes( + post.type + ) + ) { + return true; + } + // We can only edit user patterns. + return post.type === PATTERN_TYPES.user; }, callback( items ) { const post = items[ 0 ]; diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index ba4d751de5ae08..5796e086598f2a 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -212,7 +212,7 @@ export default function Editor( { isLoading } ) { const onActionPerformed = useCallback( ( actionId, items ) => { switch ( actionId ) { - case 'move-to-trash': + case 'delete-post': { history.push( { postType: items[ 0 ].type, diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index a4937dc6a75d74..a4be37c405dbc4 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -37,6 +37,34 @@ import { exportPatternAsJSONAction } from './export-pattern-action'; // Patterns. const { PATTERN_TYPES } = unlock( patternsPrivateApis ); +/** + * Check if a template is removable. + * Copy from packages/edit-site/src/utils/is-template-removable.js. + * + * @param {Object} template The template entity to check. + * @return {boolean} Whether the template is revertable. + */ +function isTemplateRemovable( template ) { + if ( ! template ) { + return false; + } + // In patterns list page we map the templates parts to a different object + // than the one returned from the endpoint. This is why we need to check for + // two props whether is custom or has a theme file. + return ( + [ template.source, template.templatePart?.source ].includes( + TEMPLATE_ORIGINS.custom + ) && + ! template.has_theme_file && + ! template.templatePart?.has_theme_file + ); +} +const canDeleteOrReset = ( item ) => { + const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; + const isUserPattern = item.type === PATTERN_TYPES.user; + return isUserPattern || ( isTemplatePart && item.isCustom ); +}; + function getItemTitle( item ) { if ( typeof item.title === 'string' ) { return decodeEntities( item.title ); @@ -44,18 +72,36 @@ function getItemTitle( item ) { return decodeEntities( item.title?.rendered || '' ); } -const trashPostAction = { - id: 'move-to-trash', - label: __( 'Move to Trash' ), +const deletePostAction = { + id: 'delete-post', + label: __( 'Delete' ), isPrimary: true, icon: trash, - isEligible( item ) { - return ! [ 'auto-draft', 'trash' ].includes( item.status ); + isEligible( post ) { + if ( [ 'auto-draft', 'trash' ].includes( post.status ) ) { + return false; + } + // Templates, template parts and patterns have special checks for renaming. + const isTemplateOrTemplatePart = [ + TEMPLATE_POST_TYPE, + TEMPLATE_PART_POST_TYPE, + ].includes( post.type ); + const isPattern = [ ...Object.values( PATTERN_TYPES ) ].includes( + post.type + ); + if ( ! isTemplateOrTemplatePart && ! isPattern ) { + return true; + } + if ( isTemplateOrTemplatePart ) { + return isTemplateRemovable( post ); + } + // We can only remove user patterns. + return post.type === PATTERN_TYPES.user; }, supportsBulk: true, hideModalHeader: true, RenderModal: ( { - items: posts, + items, closeModal, onActionStart, onActionPerformed, @@ -64,23 +110,36 @@ const trashPostAction = { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); const { deleteEntityRecord } = useDispatch( coreStore ); + const { __experimentalDeleteReusableBlock } = + useDispatch( reusableBlocksStore ); + const isPattern = items[ 0 ].type === PATTERN_POST_TYPE; + const deleteItem = isPattern + ? ( item ) => __experimentalDeleteReusableBlock( item.id ) + : ( item ) => + deleteEntityRecord( + 'postType', + item.type, + item.id, + {}, + { throwOnError: true } + ); return ( - { posts.length === 1 + { items.length === 1 ? sprintf( - // translators: %s: The page's title. + // translators: %s: The item's title. __( 'Are you sure you want to delete "%s"?' ), - getItemTitle( posts[ 0 ] ) + getItemTitle( items[ 0 ] ) ) : sprintf( - // translators: %d: The number of pages (2 or more). + // translators: %d: The number of items (2 or more). _n( - 'Are you sure you want to delete %d page?', - 'Are you sure you want to delete %d pages?', - posts.length + 'Are you sure you want to delete %d item?', + 'Are you sure you want to delete %d items?', + items.length ), - posts.length + items.length ) } @@ -97,18 +156,10 @@ const trashPostAction = { onClick={ async () => { setIsBusy( true ); if ( onActionStart ) { - onActionStart( posts ); + onActionStart( items ); } const promiseResult = await Promise.allSettled( - posts.map( ( post ) => { - return deleteEntityRecord( - 'postType', - post.type, - post.id, - {}, - { throwOnError: true } - ); - } ) + items.map( deleteItem ) ); // If all the promises were fulfilled with success. if ( @@ -119,41 +170,41 @@ const trashPostAction = { let successMessage; if ( promiseResult.length === 1 ) { successMessage = sprintf( - /* translators: The posts's title. */ - __( '"%s" moved to the Trash.' ), - getItemTitle( posts[ 0 ] ) + /* translators: The item's title. */ + __( '"%s" deleted.' ), + getItemTitle( items[ 0 ] ) ); - } else if ( posts[ 0 ].type === 'page' ) { + } else if ( items[ 0 ].type === 'page' ) { successMessage = sprintf( - /* translators: The number of pages. */ - __( '%s pages moved to the Trash.' ), - posts.length + /* translators: The number of items. */ + __( '%s items deleted.' ), + items.length ); } else { successMessage = sprintf( /* translators: The number of posts. */ - __( '%s posts moved to the Trash.' ), - posts.length + __( '%s items deleted.' ), + items.length ); } createSuccessNotice( successMessage, { type: 'snackbar', - id: 'trash-post-action', + id: 'delete-post-action', } ); } else { - // If there was at lease one failure. + // If there was at least one failure. let errorMessage; - // If we were trying to move a single post to the trash. + // If we were trying to delete a single item. if ( promiseResult.length === 1 ) { if ( promiseResult[ 0 ].reason?.message ) { errorMessage = promiseResult[ 0 ].reason.message; } else { errorMessage = __( - 'An error occurred while moving the post to the trash.' + 'An error occurred while deleting the item.' ); } - // If we were trying to move multiple posts to the trash + // If we were trying to delete multiple items. } else { const errorMessages = new Set(); const failedPromises = promiseResult.filter( @@ -168,13 +219,13 @@ const trashPostAction = { } if ( errorMessages.size === 0 ) { errorMessage = __( - 'An error occurred while moving the posts to the trash.' + 'An error occurred while deleting the items.' ); } else if ( errorMessages.size === 1 ) { errorMessage = sprintf( /* translators: %s: an error message */ __( - 'An error occurred while moving the posts to the trash: %s' + 'An error occurred while deleting the item: %s' ), [ ...errorMessages ][ 0 ] ); @@ -182,7 +233,7 @@ const trashPostAction = { errorMessage = sprintf( /* translators: %s: a list of comma separated error messages */ __( - 'Some errors occurred while moving the pages to the trash: %s' + 'Some errors occurred while deleting the items: %s' ), [ ...errorMessages ].join( ',' ) ); @@ -193,7 +244,7 @@ const trashPostAction = { } ); } if ( onActionPerformed ) { - onActionPerformed( posts ); + onActionPerformed( items ); } setIsBusy( false ); closeModal(); @@ -511,7 +562,7 @@ const renamePostAction = { ) { return true; } - // In the case of templates, we can only remove custom templates. + // In the case of templates, we can only rename custom templates. if ( post.type === TEMPLATE_POST_TYPE ) { return isTemplateRemovable( post ) && post.is_custom; } @@ -850,245 +901,6 @@ const resetTemplateAction = { }, }; -/** - * Check if a template is removable. - * Copy from packages/edit-site/src/utils/is-template-removable.js. - * - * @param {Object} template The template entity to check. - * @return {boolean} Whether the template is revertable. - */ -function isTemplateRemovable( template ) { - if ( ! template ) { - return false; - } - - return ( - template.source === TEMPLATE_ORIGINS.custom && ! template.has_theme_file - ); -} - -const deleteTemplateAction = { - id: 'delete-template', - label: __( 'Delete' ), - isEligible: isTemplateRemovable, - icon: trash, - supportsBulk: true, - hideModalHeader: true, - RenderModal: ( { - items: templates, - closeModal, - onActionStart, - onActionPerformed, - } ) => { - const [ isBusy, setIsBusy ] = useState( false ); - const { removeTemplates } = unlock( useDispatch( editorStore ) ); - return ( - - - { templates.length > 1 - ? sprintf( - // translators: %d: number of items to delete. - _n( - 'Delete %d item?', - 'Delete %d items?', - templates.length - ), - templates.length - ) - : sprintf( - // translators: %s: The template or template part's titles - __( 'Delete "%s"?' ), - decodeEntities( - templates?.[ 0 ]?.title?.rendered - ) - ) } - - - - - - - ); - }, -}; - -const canDeleteOrReset = ( item ) => { - const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; - const isUserPattern = item.type === PATTERN_TYPES.user; - return isUserPattern || ( isTemplatePart && item.isCustom ); -}; - -export const deletePatternAction = { - id: 'delete-pattern', - label: __( 'Delete' ), - isEligible: ( item ) => { - if ( ! item ) { - return false; - } - const isTemplatePart = item.type === TEMPLATE_PART_POST_TYPE; - const hasThemeFile = - isTemplatePart && item.templatePart?.has_theme_file; - return canDeleteOrReset( item ) && ! hasThemeFile; - }, - hideModalHeader: true, - supportsBulk: true, - RenderModal: ( { items, closeModal, onActionPerformed } ) => { - const { __experimentalDeleteReusableBlock } = - useDispatch( reusableBlocksStore ); - const { createErrorNotice, createSuccessNotice } = - useDispatch( noticesStore ); - const { removeTemplates } = unlock( useDispatch( editorStore ) ); - - const deletePattern = async () => { - const promiseResult = await Promise.allSettled( - items.map( ( item ) => { - return __experimentalDeleteReusableBlock( item.id ); - } ) - ); - // If all the promises were fulfilled with success. - if ( - promiseResult.every( ( { status } ) => status === 'fulfilled' ) - ) { - let successMessage; - if ( promiseResult.length === 1 ) { - successMessage = sprintf( - /* translators: The posts's title. */ - __( '"%s" deleted.' ), - items[ 0 ].title - ); - } else { - successMessage = __( 'The patterns were deleted.' ); - } - createSuccessNotice( successMessage, { - type: 'snackbar', - id: 'edit-site-page-trashed', - } ); - } else { - // If there was at lease one failure. - let errorMessage; - // If we were trying to delete a single pattern. - if ( promiseResult.length === 1 ) { - if ( promiseResult[ 0 ].reason?.message ) { - errorMessage = promiseResult[ 0 ].reason.message; - } else { - errorMessage = __( - 'An error occurred while deleting the pattern.' - ); - } - // If we were trying to delete multiple patterns. - } else { - const errorMessages = new Set(); - const failedPromises = promiseResult.filter( - ( { status } ) => status === 'rejected' - ); - for ( const failedPromise of failedPromises ) { - if ( failedPromise.reason?.message ) { - errorMessages.add( failedPromise.reason.message ); - } - } - if ( errorMessages.size === 0 ) { - errorMessage = __( - 'An error occurred while deleting the patterns.' - ); - } else if ( errorMessages.size === 1 ) { - errorMessage = sprintf( - /* translators: %s: an error message */ - __( - 'An error occurred while deleting the patterns: %s' - ), - [ ...errorMessages ][ 0 ] - ); - } else { - errorMessage = sprintf( - /* translators: %s: a list of comma separated error messages */ - __( - 'Some errors occurred while deleting the patterns: %s' - ), - [ ...errorMessages ].join( ',' ) - ); - } - createErrorNotice( errorMessage, { - type: 'snackbar', - } ); - } - } - }; - const deleteItem = () => { - if ( items[ 0 ].type === TEMPLATE_PART_POST_TYPE ) { - removeTemplates( items ); - } else { - deletePattern(); - } - if ( onActionPerformed ) { - onActionPerformed(); - } - closeModal(); - }; - let questionMessage; - if ( items.length === 1 ) { - questionMessage = sprintf( - // translators: %s: The page's title. - __( 'Are you sure you want to delete "%s"?' ), - decodeEntities( items[ 0 ].title || items[ 0 ].name ) - ); - } else if ( - items.length > 1 && - items[ 0 ].type === TEMPLATE_PART_POST_TYPE - ) { - questionMessage = sprintf( - // translators: %d: The number of template parts (2 or more). - __( 'Are you sure you want to delete %d template parts?' ), - items.length - ); - } else { - questionMessage = sprintf( - // translators: %d: The number of patterns (2 or more). - __( 'Are you sure you want to delete %d patterns?' ), - items.length - ); - } - return ( - - { questionMessage } - - - - - - ); - }, -}; - export function usePostActions( postType, onActionPerformed ) { const { postTypeObject } = useSelect( ( select ) => { @@ -1124,11 +936,8 @@ export function usePostActions( postType, onActionPerformed ) { renamePostAction, isPattern && exportPatternAsJSONAction, isTemplateOrTemplatePart ? resetTemplateAction : restorePostAction, - isTemplateOrTemplatePart - ? deleteTemplateAction - : permanentlyDeletePostAction, - isPattern && deletePatternAction, - ! isTemplateOrTemplatePart && trashPostAction, + deletePostAction, + ! isTemplateOrTemplatePart && permanentlyDeletePostAction, ].filter( Boolean ); if ( onActionPerformed ) { From 440a6421f250f7574f4d2d00cfcb7e738c8c90e3 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 23 May 2024 19:11:33 +0300 Subject: [PATCH 2/4] feedback --- .../src/components/dataviews-actions/index.js | 12 ++-------- .../src/components/post-actions/actions.js | 24 +++++++------------ .../editor/various/change-detection.spec.js | 2 +- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/packages/edit-site/src/components/dataviews-actions/index.js b/packages/edit-site/src/components/dataviews-actions/index.js index 27597c22421b9d..09b7597c6cb341 100644 --- a/packages/edit-site/src/components/dataviews-actions/index.js +++ b/packages/edit-site/src/components/dataviews-actions/index.js @@ -26,16 +26,8 @@ export const useEditPostAction = () => { if ( post.status === 'trash' ) { return false; } - // It's eligible for all post types except patterns. - if ( - ! [ ...Object.values( PATTERN_TYPES ) ].includes( - post.type - ) - ) { - return true; - } - // We can only edit user patterns. - return post.type === PATTERN_TYPES.user; + // It's eligible for all post types except theme patterns. + return post.type !== PATTERN_TYPES.theme; }, callback( items ) { const post = items[ 0 ]; diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index a4be37c405dbc4..d04a31ed3c322f 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -9,7 +9,6 @@ import { store as coreStore } from '@wordpress/core-data'; import { __, _n, sprintf, _x } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import { useMemo, useState } from '@wordpress/element'; -import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; import { privateApis as patternsPrivateApis } from '@wordpress/patterns'; import { @@ -110,19 +109,6 @@ const deletePostAction = { const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); const { deleteEntityRecord } = useDispatch( coreStore ); - const { __experimentalDeleteReusableBlock } = - useDispatch( reusableBlocksStore ); - const isPattern = items[ 0 ].type === PATTERN_POST_TYPE; - const deleteItem = isPattern - ? ( item ) => __experimentalDeleteReusableBlock( item.id ) - : ( item ) => - deleteEntityRecord( - 'postType', - item.type, - item.id, - {}, - { throwOnError: true } - ); return ( @@ -159,7 +145,15 @@ const deletePostAction = { onActionStart( items ); } const promiseResult = await Promise.allSettled( - items.map( deleteItem ) + items.map( ( item ) => + deleteEntityRecord( + 'postType', + item.type, + item.id, + {}, + { throwOnError: true } + ) + ) ); // If all the promises were fulfilled with success. if ( diff --git a/test/e2e/specs/editor/various/change-detection.spec.js b/test/e2e/specs/editor/various/change-detection.spec.js index a737e4eb94a5fc..02bcc715359e72 100644 --- a/test/e2e/specs/editor/various/change-detection.spec.js +++ b/test/e2e/specs/editor/various/change-detection.spec.js @@ -416,7 +416,7 @@ test.describe( 'Change detection', () => { .click(); await page .getByRole( 'menu' ) - .getByRole( 'menuitem', { name: 'Move to Trash' } ) + .getByRole( 'menuitem', { name: 'Delete' } ) .click(); await page .getByRole( 'dialog' ) From afc5f61918f5c28600b84d29f00545393ed6654d Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Fri, 24 May 2024 15:52:51 +0300 Subject: [PATCH 3/4] update comment --- packages/editor/src/components/post-actions/actions.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index d04a31ed3c322f..e3f243225375ee 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -38,10 +38,9 @@ const { PATTERN_TYPES } = unlock( patternsPrivateApis ); /** * Check if a template is removable. - * Copy from packages/edit-site/src/utils/is-template-removable.js. * * @param {Object} template The template entity to check. - * @return {boolean} Whether the template is revertable. + * @return {boolean} Whether the template is removable. */ function isTemplateRemovable( template ) { if ( ! template ) { From ddc727c95c95846066a02e2c79dc7ea9af032666 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Mon, 27 May 2024 12:24:12 +0300 Subject: [PATCH 4/4] preserve move to trash action --- .../edit-post/src/components/layout/index.js | 2 +- .../edit-site/src/components/editor/index.js | 1 + .../src/components/post-actions/actions.js | 125 ++++++++++++++---- packages/editor/src/store/private-actions.js | 72 +++------- .../editor/various/change-detection.spec.js | 4 +- 5 files changed, 123 insertions(+), 81 deletions(-) diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 780c706ca83014..fde9319a348daf 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -277,7 +277,7 @@ function Layout( { initialPost } ) { const onActionPerformed = useCallback( ( actionId, items ) => { switch ( actionId ) { - case 'delete-post': + case 'move-to-trash': { document.location.href = addQueryArgs( 'edit.php', { trashed: 1, diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 5796e086598f2a..b7fc350c3eabb9 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -212,6 +212,7 @@ export default function Editor( { isLoading } ) { const onActionPerformed = useCallback( ( actionId, items ) => { switch ( actionId ) { + case 'move-to-trash': case 'delete-post': { history.push( { diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index e3f243225375ee..0706737a7c4e8a 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -70,27 +70,20 @@ function getItemTitle( item ) { return decodeEntities( item.title?.rendered || '' ); } +// This action is used for templates, patterns and template parts. +// Every other post type uses the similar `trashPostAction` which +// moves the post to trash. const deletePostAction = { id: 'delete-post', label: __( 'Delete' ), isPrimary: true, icon: trash, isEligible( post ) { - if ( [ 'auto-draft', 'trash' ].includes( post.status ) ) { - return false; - } - // Templates, template parts and patterns have special checks for renaming. - const isTemplateOrTemplatePart = [ - TEMPLATE_POST_TYPE, - TEMPLATE_PART_POST_TYPE, - ].includes( post.type ); - const isPattern = [ ...Object.values( PATTERN_TYPES ) ].includes( - post.type - ); - if ( ! isTemplateOrTemplatePart && ! isPattern ) { - return true; - } - if ( isTemplateOrTemplatePart ) { + if ( + [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes( + post.type + ) + ) { return isTemplateRemovable( post ); } // We can only remove user patterns. @@ -98,6 +91,78 @@ const deletePostAction = { }, supportsBulk: true, hideModalHeader: true, + RenderModal: ( { + items, + closeModal, + onActionStart, + onActionPerformed, + } ) => { + const [ isBusy, setIsBusy ] = useState( false ); + const { removeTemplates } = unlock( useDispatch( editorStore ) ); + return ( + + + { items.length > 1 + ? sprintf( + // translators: %d: number of items to delete. + _n( + 'Delete %d item?', + 'Delete %d items?', + items.length + ), + items.length + ) + : sprintf( + // translators: %s: The template or template part's titles + __( 'Delete "%s"?' ), + getItemTitle( items[ 0 ] ) + ) } + + + + + + + ); + }, +}; + +const trashPostAction = { + id: 'move-to-trash', + label: __( 'Move to Trash' ), + isPrimary: true, + icon: trash, + isEligible( item ) { + return ! [ 'auto-draft', 'trash' ].includes( item.status ); + }, + supportsBulk: true, + hideModalHeader: true, RenderModal: ( { items, closeModal, @@ -114,14 +179,16 @@ const deletePostAction = { { items.length === 1 ? sprintf( // translators: %s: The item's title. - __( 'Are you sure you want to delete "%s"?' ), + __( + 'Are you sure you want to move to trash "%s"?' + ), getItemTitle( items[ 0 ] ) ) : sprintf( // translators: %d: The number of items (2 or more). _n( - 'Are you sure you want to delete %d item?', - 'Are you sure you want to delete %d items?', + 'Are you sure you want to move to trash %d item?', + 'Are you sure you want to move to trash %d items?', items.length ), items.length @@ -164,25 +231,25 @@ const deletePostAction = { if ( promiseResult.length === 1 ) { successMessage = sprintf( /* translators: The item's title. */ - __( '"%s" deleted.' ), + __( '"%s" moved to trash.' ), getItemTitle( items[ 0 ] ) ); } else if ( items[ 0 ].type === 'page' ) { successMessage = sprintf( /* translators: The number of items. */ - __( '%s items deleted.' ), + __( '%s items moved to trash.' ), items.length ); } else { successMessage = sprintf( /* translators: The number of posts. */ - __( '%s items deleted.' ), + __( '%s items move to trash.' ), items.length ); } createSuccessNotice( successMessage, { type: 'snackbar', - id: 'delete-post-action', + id: 'move-to-trash-action', } ); } else { // If there was at least one failure. @@ -194,7 +261,7 @@ const deletePostAction = { promiseResult[ 0 ].reason.message; } else { errorMessage = __( - 'An error occurred while deleting the item.' + 'An error occurred while moving to trash the item.' ); } // If we were trying to delete multiple items. @@ -212,13 +279,13 @@ const deletePostAction = { } if ( errorMessages.size === 0 ) { errorMessage = __( - 'An error occurred while deleting the items.' + 'An error occurred while moving to trash the items.' ); } else if ( errorMessages.size === 1 ) { errorMessage = sprintf( /* translators: %s: an error message */ __( - 'An error occurred while deleting the item: %s' + 'An error occurred while moving to trash the item: %s' ), [ ...errorMessages ][ 0 ] ); @@ -226,7 +293,7 @@ const deletePostAction = { errorMessage = sprintf( /* translators: %s: a list of comma separated error messages */ __( - 'Some errors occurred while deleting the items: %s' + 'Some errors occurred while moving to trash the items: %s' ), [ ...errorMessages ].join( ',' ) ); @@ -246,7 +313,7 @@ const deletePostAction = { disabled={ isBusy } __experimentalIsFocusable > - { __( 'Delete' ) } + { __( 'Trash' ) } @@ -929,7 +996,9 @@ export function usePostActions( postType, onActionPerformed ) { renamePostAction, isPattern && exportPatternAsJSONAction, isTemplateOrTemplatePart ? resetTemplateAction : restorePostAction, - deletePostAction, + isTemplateOrTemplatePart || isPattern + ? deletePostAction + : trashPostAction, ! isTemplateOrTemplatePart && permanentlyDeletePostAction, ].filter( Boolean ); diff --git a/packages/editor/src/store/private-actions.js b/packages/editor/src/store/private-actions.js index c3fca0798e8b70..9304a2fe2c0579 100644 --- a/packages/editor/src/store/private-actions.js +++ b/packages/editor/src/store/private-actions.js @@ -15,7 +15,6 @@ import { decodeEntities } from '@wordpress/html-entities'; * Internal dependencies */ import isTemplateRevertable from './utils/is-template-revertable'; -import { TEMPLATE_POST_TYPE } from './constants'; /** * Returns an action object used to set which template is currently being used/edited. @@ -363,14 +362,13 @@ export const revertTemplate = }; /** - * Action that removes an array of templates. + * Action that removes an array of templates, template parts or patterns. * - * @param {Array} items An array of template or template part objects to remove. + * @param {Array} items An array of template,template part or pattern objects to remove. */ export const removeTemplates = ( items ) => async ( { registry } ) => { - const isTemplate = items[ 0 ].type === TEMPLATE_POST_TYPE; const promiseResult = await Promise.allSettled( items.map( ( item ) => { return registry @@ -402,16 +400,14 @@ export const removeTemplates = decodeEntities( title ) ); } else { - successMessage = isTemplate - ? __( 'Templates deleted.' ) - : __( 'Template parts deleted.' ); + successMessage = __( 'Items deleted.' ); } registry .dispatch( noticesStore ) .createSuccessNotice( successMessage, { type: 'snackbar', - id: 'site-editor-template-deleted-success', + id: 'editor-template-deleted-success', } ); } else { // If there was at lease one failure. @@ -421,11 +417,9 @@ export const removeTemplates = if ( promiseResult[ 0 ].reason?.message ) { errorMessage = promiseResult[ 0 ].reason.message; } else { - errorMessage = isTemplate - ? __( 'An error occurred while deleting the template.' ) - : __( - 'An error occurred while deleting the template part.' - ); + errorMessage = __( + 'An error occurred while deleting the item.' + ); } // If we were trying to delete a multiple templates } else { @@ -439,45 +433,23 @@ export const removeTemplates = } } if ( errorMessages.size === 0 ) { - errorMessage = isTemplate - ? __( - 'An error occurred while deleting the templates.' - ) - : __( - 'An error occurred while deleting the template parts.' - ); + errorMessage = __( + 'An error occurred while deleting the items.' + ); } else if ( errorMessages.size === 1 ) { - errorMessage = isTemplate - ? sprintf( - /* translators: %s: an error message */ - __( - 'An error occurred while deleting the templates: %s' - ), - [ ...errorMessages ][ 0 ] - ) - : sprintf( - /* translators: %s: an error message */ - __( - 'An error occurred while deleting the template parts: %s' - ), - [ ...errorMessages ][ 0 ] - ); + errorMessage = sprintf( + /* translators: %s: an error message */ + __( 'An error occurred while deleting the items: %s' ), + [ ...errorMessages ][ 0 ] + ); } else { - errorMessage = isTemplate - ? sprintf( - /* translators: %s: a list of comma separated error messages */ - __( - 'Some errors occurred while deleting the templates: %s' - ), - [ ...errorMessages ].join( ',' ) - ) - : sprintf( - /* translators: %s: a list of comma separated error messages */ - __( - 'Some errors occurred while deleting the template parts: %s' - ), - [ ...errorMessages ].join( ',' ) - ); + sprintf( + /* translators: %s: a list of comma separated error messages */ + __( + 'Some errors occurred while deleting the items: %s' + ), + [ ...errorMessages ].join( ',' ) + ); } } registry diff --git a/test/e2e/specs/editor/various/change-detection.spec.js b/test/e2e/specs/editor/various/change-detection.spec.js index 02bcc715359e72..4ac262f4c1348d 100644 --- a/test/e2e/specs/editor/various/change-detection.spec.js +++ b/test/e2e/specs/editor/various/change-detection.spec.js @@ -416,11 +416,11 @@ test.describe( 'Change detection', () => { .click(); await page .getByRole( 'menu' ) - .getByRole( 'menuitem', { name: 'Delete' } ) + .getByRole( 'menuitem', { name: 'Move to Trash' } ) .click(); await page .getByRole( 'dialog' ) - .getByRole( 'button', { name: 'Delete' } ) + .getByRole( 'button', { name: 'Trash' } ) .click(); await expect( page ).toHaveURL( '/wp-admin/edit.php?post_type=post' );