From 9d3b8e039a81ddabfa3676e76dbb967cbe17a3ce Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 14 Jun 2024 16:10:08 +0100 Subject: [PATCH 1/3] Fix: User capacities are not taken into account in the trash post action. --- .../src/components/post-actions/actions.js | 352 ++++++++++-------- 1 file changed, 199 insertions(+), 153 deletions(-) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 5cb208e23e7867..3b795ac2a04a44 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -3,7 +3,7 @@ */ import { external, trash, backup } from '@wordpress/icons'; import { addQueryArgs } from '@wordpress/url'; -import { useDispatch, useSelect } from '@wordpress/data'; +import { useDispatch, useSelect, useRegistry } from '@wordpress/data'; import { decodeEntities } from '@wordpress/html-entities'; import { store as coreStore } from '@wordpress/core-data'; import { __, _n, sprintf, _x } from '@wordpress/i18n'; @@ -147,165 +147,207 @@ const deletePostAction = { }, }; -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, onActionPerformed } ) => { - const [ isBusy, setIsBusy ] = useState( false ); - const { createSuccessNotice, createErrorNotice } = - useDispatch( noticesStore ); - const { deleteEntityRecord } = useDispatch( coreStore ); - return ( - - - { items.length === 1 - ? sprintf( - // translators: %s: The item's title. - __( - '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 move to trash %d item?', - 'Are you sure you want to move to trash %d items?', - items.length - ), - items.length - ) } - - - - + - - - ); - }, -}; + if ( onActionPerformed ) { + onActionPerformed( items ); + } + setIsBusy( false ); + closeModal(); + } } + isBusy={ isBusy } + disabled={ isBusy } + __experimentalIsFocusable + > + { __( 'Trash' ) } + + + + ); + }, + } ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [ registry, resource, canUserResolvers ] + ); +} const permanentlyDeletePostAction = { id: 'permanently-delete', @@ -1020,6 +1062,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); const duplicatePostAction = useDuplicatePostAction( postType ); + const trashPostAction = useTrashPostAction( postType ); const isTemplateOrTemplatePart = [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE, @@ -1113,6 +1156,9 @@ export function usePostActions( { postType, onActionPerformed, context } ) { isPattern, postTypeObject?.viewable, duplicatePostAction, + permanentlyDeletePostAction, + trashPostAction, + restorePostAction, onActionPerformed, isLoaded, supportsRevisions, From 93a35ee232a4e4f98da237ef5a391856ef5e0626 Mon Sep 17 00:00:00 2001 From: Ella Date: Thu, 20 Jun 2024 15:36:37 +0300 Subject: [PATCH 2/3] Minimize diff --- .../src/components/post-actions/actions.js | 345 +++++++++--------- 1 file changed, 166 insertions(+), 179 deletions(-) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 3b795ac2a04a44..a0580fa6b43bdb 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -147,6 +147,166 @@ const deletePostAction = { }, }; +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, onActionPerformed } ) => { + const [ isBusy, setIsBusy ] = useState( false ); + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + const { deleteEntityRecord } = useDispatch( coreStore ); + return ( + + + { items.length === 1 + ? sprintf( + // translators: %s: The item's title. + __( + '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 move to trash %d item?', + 'Are you sure you want to move to trash %d items?', + items.length + ), + items.length + ) } + + + + + + + ); + }, +}; + function useTrashPostAction( postType ) { const registry = useRegistry(); const { resource, canUserResolvers } = useSelect( @@ -161,186 +321,13 @@ function useTrashPostAction( postType ) { ); return useMemo( () => ( { - id: 'move-to-trash', - label: __( 'Move to Trash' ), - isPrimary: true, - icon: trash, + ...trashPostAction, isEligible( item ) { return ( + trashPostAction.isEligible( item ) && registry .select( coreStore ) - .canUser( 'delete', resource, item.id ) && - ! [ 'auto-draft', 'trash' ].includes( item.status ) - ); - }, - supportsBulk: true, - hideModalHeader: true, - RenderModal: ( { items, closeModal, onActionPerformed } ) => { - const [ isBusy, setIsBusy ] = useState( false ); - const { createSuccessNotice, createErrorNotice } = - useDispatch( noticesStore ); - const { deleteEntityRecord } = useDispatch( coreStore ); - return ( - - - { items.length === 1 - ? sprintf( - // translators: %s: The item's title. - __( - '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 move to trash %d item?', - 'Are you sure you want to move to trash %d items?', - items.length - ), - items.length - ) } - - - - - - + .canUser( 'delete', resource, item.id ) ); }, } ), @@ -1062,7 +1049,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { ); const duplicatePostAction = useDuplicatePostAction( postType ); - const trashPostAction = useTrashPostAction( postType ); + const trashPostActionForPostType = useTrashPostAction( postType ); const isTemplateOrTemplatePart = [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE, @@ -1091,7 +1078,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { isTemplateOrTemplatePart ? resetTemplateAction : restorePostAction, isTemplateOrTemplatePart || isPattern ? deletePostAction - : trashPostAction, + : trashPostActionForPostType, ! isTemplateOrTemplatePart && permanentlyDeletePostAction, ...defaultActions, ].filter( Boolean ); @@ -1157,7 +1144,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { postTypeObject?.viewable, duplicatePostAction, permanentlyDeletePostAction, - trashPostAction, + trashPostActionForPostType, restorePostAction, onActionPerformed, isLoaded, From df4207a147e833f6925609dda6ed3b1ef5732e7c Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 20 Jun 2024 15:57:25 +0100 Subject: [PATCH 3/3] Add inline comment. --- packages/editor/src/components/post-actions/actions.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index a0580fa6b43bdb..0034e2b2664c6a 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -309,12 +309,12 @@ const trashPostAction = { function useTrashPostAction( postType ) { const registry = useRegistry(); - const { resource, canUserResolvers } = useSelect( + const { resource, cachedCanUserResolvers } = useSelect( ( select ) => { const { getPostType, getCachedResolvers } = select( coreStore ); return { resource: getPostType( postType )?.rest_base || '', - canUserResolvers: getCachedResolvers().canUser, + cachedCanUserResolvers: getCachedResolvers().canUser, }; }, [ postType ] @@ -331,8 +331,10 @@ function useTrashPostAction( postType ) { ); }, } ), + // We are making this use memo depend on cachedCanUserResolvers as a way to make the component using this hook re-render + // when user capabilities are resolved. This makes sure the isEligible function is re-evaluated. // eslint-disable-next-line react-hooks/exhaustive-deps - [ registry, resource, canUserResolvers ] + [ registry, resource, cachedCanUserResolvers ] ); } @@ -1143,9 +1145,7 @@ export function usePostActions( { postType, onActionPerformed, context } ) { isPattern, postTypeObject?.viewable, duplicatePostAction, - permanentlyDeletePostAction, trashPostActionForPostType, - restorePostAction, onActionPerformed, isLoaded, supportsRevisions,