diff --git a/package-lock.json b/package-lock.json
index 68ee222ddb1be3..23e229d1fcf868 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -53796,6 +53796,7 @@
"@wordpress/a11y": "file:../a11y",
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
+ "@wordpress/data": "file:../data",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
@@ -68987,6 +68988,7 @@
"@wordpress/a11y": "file:../a11y",
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
+ "@wordpress/data": "file:../data",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/dataviews/package.json b/packages/dataviews/package.json
index 394c41e35cea3c..b8d4e04c0c4e07 100644
--- a/packages/dataviews/package.json
+++ b/packages/dataviews/package.json
@@ -32,6 +32,7 @@
"@wordpress/a11y": "file:../a11y",
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
+ "@wordpress/data": "file:../data",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/dataviews/src/bulk-actions.js b/packages/dataviews/src/bulk-actions.js
index 5e4139fe0622e7..8509081673369a 100644
--- a/packages/dataviews/src/bulk-actions.js
+++ b/packages/dataviews/src/bulk-actions.js
@@ -8,6 +8,7 @@ import {
} from '@wordpress/components';
import { __, sprintf, _n } from '@wordpress/i18n';
import { useMemo, useState, useCallback, useEffect } from '@wordpress/element';
+import { useRegistry } from '@wordpress/data';
/**
* Internal dependencies
@@ -52,6 +53,15 @@ function ActionWithModal( {
const onCloseModal = useCallback( () => {
setActionWithModal( undefined );
}, [ setActionWithModal ] );
+ const actionWithCallbacks = useMemo( () => {
+ return {
+ ...action,
+ onActionPerformed: ( ...args ) => {
+ onMenuOpenChange( false );
+ action.onActionPerformed?.( ...args );
+ },
+ };
+ }, [ action, onMenuOpenChange ] );
return (
onMenuOpenChange( false ) }
+ action={ actionWithCallbacks }
/>
);
}
function BulkActionItem( { action, selectedItems, setActionWithModal } ) {
+ const registry = useRegistry();
const eligibleItems = useMemo( () => {
return selectedItems.filter( ( item ) => action.isEligible( item ) );
}, [ action, selectedItems ] );
@@ -84,7 +95,14 @@ function BulkActionItem( { action, selectedItems, setActionWithModal } ) {
if ( shouldShowModal ) {
setActionWithModal( action );
} else {
- await action.callback( eligibleItems );
+ const returnResult = await action.callback( eligibleItems );
+ if ( typeof returnResult === 'function' ) {
+ await returnResult( {
+ registry,
+ select: registry.select,
+ dispatch: registry.dispatch,
+ } );
+ }
}
} }
suffix={
diff --git a/packages/dataviews/src/item-actions.js b/packages/dataviews/src/item-actions.js
index db4da0d4924896..42fcfe756e89e3 100644
--- a/packages/dataviews/src/item-actions.js
+++ b/packages/dataviews/src/item-actions.js
@@ -10,6 +10,7 @@ import {
import { __ } from '@wordpress/i18n';
import { useMemo, useState } from '@wordpress/element';
import { moreVertical } from '@wordpress/icons';
+import { useRegistry } from '@wordpress/data';
/**
* Internal dependencies
@@ -71,6 +72,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
setIsModalOpen( false ) }
+ action={ action }
/>
) }
@@ -79,6 +81,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
}
function ActionsDropdownMenuGroup( { actions, item } ) {
+ const registry = useRegistry();
return (
{ actions.map( ( action ) => {
@@ -96,7 +99,18 @@ function ActionsDropdownMenuGroup( { actions, item } ) {
action.callback( [ item ] ) }
+ onClick={ async () => {
+ const returnResult = await action.callback( [
+ item,
+ ] );
+ if ( typeof returnResult === 'function' ) {
+ await returnResult( {
+ registry,
+ select: registry.select,
+ dispatch: registry.dispatch,
+ } );
+ }
+ } }
/>
);
} ) }
@@ -105,6 +119,7 @@ function ActionsDropdownMenuGroup( { actions, item } ) {
}
export default function ItemActions( { item, actions, isCompact } ) {
+ const registry = useRegistry();
const { primaryActions, eligibleActions } = useMemo( () => {
// If an action is eligible for all items, doesn't need
// to provide the `isEligible` function.
@@ -148,7 +163,18 @@ export default function ItemActions( { item, actions, isCompact } ) {
action.callback( [ item ] ) }
+ onClick={ async () => {
+ const returnResult = await action.callback( [
+ item,
+ ] );
+ if ( typeof returnResult === 'function' ) {
+ await returnResult( {
+ registry,
+ select: registry.select,
+ dispatch: registry.dispatch,
+ } );
+ }
+ } }
/>
);
} ) }
diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js
index e98896ab2e8cc9..307761e91b2c29 100644
--- a/packages/edit-site/src/components/page-pages/index.js
+++ b/packages/edit-site/src/components/page-pages/index.js
@@ -34,7 +34,7 @@ import AddNewPageModal from '../add-new-page';
import Media from '../media';
import { unlock } from '../../lock-unlock';
-const { usePostActions } = unlock( editorPrivateApis );
+const { postActions } = unlock( editorPrivateApis );
const { useLocation, useHistory } = unlock( routerPrivateApis );
@@ -189,15 +189,15 @@ function FeaturedImage( { item, viewType } ) {
);
}
-const PAGE_ACTIONS = [
- 'edit-post',
- 'view-post',
- 'restore',
- 'permanently-delete',
- 'view-post-revisions',
- 'rename-post',
- 'move-to-trash',
-];
+const {
+ editPostAction,
+ viewPostAction,
+ restorePostAction,
+ permanentlyDeletePostAction,
+ postRevisionsAction,
+ renamePostAction,
+ trashPostAction,
+} = postActions;
export default function PagePages() {
const postType = 'page';
@@ -350,20 +350,33 @@ export default function PagePages() {
],
[ authors, view.type ]
);
- const onActionPerformed = useCallback(
- ( actionId, items ) => {
- if ( actionId === 'edit-post' ) {
- const post = items[ 0 ];
- history.push( {
- postId: post.id,
- postType: post.type,
- canvas: 'edit',
- } );
- }
- },
- [ history ]
- );
- const actions = usePostActions( onActionPerformed, PAGE_ACTIONS );
+
+ const actions = useMemo( () => {
+ const onEditPostActionPerformed = ( items ) => {
+ const post = items[ 0 ];
+ history.push( {
+ postId: post.id,
+ postType: post.type,
+ canvas: 'edit',
+ } );
+ };
+ return [
+ {
+ ...editPostAction,
+ onActionPerformed: ( ...args ) => {
+ onEditPostActionPerformed( ...args );
+ editPostAction.onActionPerformed?.( ...args );
+ },
+ },
+ viewPostAction,
+ restorePostAction,
+ permanentlyDeletePostAction,
+ postRevisionsAction,
+ renamePostAction,
+ trashPostAction,
+ ];
+ }, [ history ] );
+
const onChangeView = useCallback(
( newView ) => {
if ( newView.type !== view.type ) {
diff --git a/packages/edit-site/src/components/page-patterns/index.js b/packages/edit-site/src/components/page-patterns/index.js
index 102f1b3cd075e9..580749a28ed69b 100644
--- a/packages/edit-site/src/components/page-patterns/index.js
+++ b/packages/edit-site/src/components/page-patterns/index.js
@@ -67,7 +67,7 @@ import { useAddedBy } from '../page-templates/hooks';
const { ExperimentalBlockEditorProvider, useGlobalStyle } = unlock(
blockEditorPrivateApis
);
-const { usePostActions } = unlock( editorPrivateApis );
+const { postActions } = unlock( editorPrivateApis );
const { useHistory } = unlock( routerPrivateApis );
const EMPTY_ARRAY = [];
@@ -252,6 +252,8 @@ function Title( { item, categoryId } ) {
);
}
+const { editPostAction, postRevisionsAction } = postActions;
+
export default function DataviewsPatterns() {
const {
categoryType,
@@ -394,9 +396,9 @@ export default function DataviewsPatterns() {
}, [ patterns, view, fields, type ] );
const history = useHistory();
- const onActionPerformed = useCallback(
- ( actionId, items ) => {
- if ( actionId === 'edit-post' ) {
+ const actions = useMemo( () => {
+ if ( type === TEMPLATE_PART_POST_TYPE ) {
+ const onEditPostActionPerformed = ( items ) => {
const post = items[ 0 ];
history.push( {
postId: post.id,
@@ -405,21 +407,18 @@ export default function DataviewsPatterns() {
categoryType: type,
canvas: 'edit',
} );
- }
- },
- [ history, categoryId, type ]
- );
- const [ editAction, viewRevisionsAction ] = usePostActions(
- onActionPerformed,
- [ 'edit-post', 'view-post-revisions' ]
- );
- const actions = useMemo( () => {
- if ( type === TEMPLATE_PART_POST_TYPE ) {
+ };
return [
- editAction,
+ {
+ ...editPostAction,
+ onActionPerformed: ( ...args ) => {
+ onEditPostActionPerformed( ...args );
+ editPostAction.onActionPerformed?.( ...args );
+ },
+ },
renameAction,
duplicateTemplatePartAction,
- viewRevisionsAction,
+ postRevisionsAction,
resetAction,
deleteAction,
];
@@ -431,7 +430,7 @@ export default function DataviewsPatterns() {
resetAction,
deleteAction,
];
- }, [ type, editAction, viewRevisionsAction ] );
+ }, [ type, history, categoryId ] );
const onChangeView = useCallback(
( newView ) => {
if ( newView.type !== view.type ) {
diff --git a/packages/edit-site/src/components/page-templates/index.js b/packages/edit-site/src/components/page-templates/index.js
index a64cb63cfbc8c4..66fdb897ffdb03 100644
--- a/packages/edit-site/src/components/page-templates/index.js
+++ b/packages/edit-site/src/components/page-templates/index.js
@@ -45,7 +45,7 @@ import {
import usePatternSettings from '../page-patterns/use-pattern-settings';
import { unlock } from '../../lock-unlock';
-const { usePostActions } = unlock( editorPrivateApis );
+const { postActions } = unlock( editorPrivateApis );
const { ExperimentalBlockEditorProvider, useGlobalStyle } = unlock(
blockEditorPrivateApis
@@ -187,13 +187,13 @@ function Preview( { item, viewType } ) {
);
}
-const TEMPLATE_ACTIONS = [
- 'edit-post',
- 'reset-template',
- 'rename-template',
- 'view-post-revisions',
- 'delete-template',
-];
+const {
+ editPostAction,
+ resetTemplateAction,
+ renameTemplateAction,
+ postRevisionsAction,
+ deleteTemplateAction,
+} = postActions;
export default function PageTemplates() {
const { params } = useLocation();
@@ -335,21 +335,29 @@ export default function PageTemplates() {
return filterSortAndPaginate( records, view, fields );
}, [ records, view, fields ] );
- const onActionPerformed = useCallback(
- ( actionId, items ) => {
- if ( actionId === 'edit-post' ) {
- const post = items[ 0 ];
- history.push( {
- postId: post.id,
- postType: post.type,
- canvas: 'edit',
- } );
- }
- },
- [ history ]
- );
-
- const actions = usePostActions( onActionPerformed, TEMPLATE_ACTIONS );
+ const actions = useMemo( () => {
+ const onEditPostActionPerformed = ( items ) => {
+ const post = items[ 0 ];
+ history.push( {
+ postId: post.id,
+ postType: post.type,
+ canvas: 'edit',
+ } );
+ };
+ return [
+ {
+ ...editPostAction,
+ onActionPerformed: ( ...args ) => {
+ onEditPostActionPerformed( ...args );
+ editPostAction.onActionPerformed?.( ...args );
+ },
+ },
+ resetTemplateAction,
+ renameTemplateAction,
+ postRevisionsAction,
+ deleteTemplateAction,
+ ];
+ }, [ history ] );
const onChangeView = useCallback(
( newView ) => {
diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js
index 7b91c2c5c96e3e..da91f010712c97 100644
--- a/packages/editor/src/components/post-actions/actions.js
+++ b/packages/editor/src/components/post-actions/actions.js
@@ -8,7 +8,7 @@ import { decodeEntities } from '@wordpress/html-entities';
import { store as coreStore } from '@wordpress/core-data';
import { __, _n, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
-import { useMemo, useState } from '@wordpress/element';
+import { useState } from '@wordpress/element';
import {
Button,
@@ -33,7 +33,7 @@ function getItemTitle( item ) {
return decodeEntities( item.title?.rendered || '' );
}
-const trashPostAction = {
+export const trashPostAction = {
id: 'move-to-trash',
label: __( 'Move to Trash' ),
isPrimary: true,
@@ -43,7 +43,7 @@ const trashPostAction = {
},
supportsBulk: true,
hideModalHeader: true,
- RenderModal: ( { items: posts, closeModal, onActionPerformed } ) => {
+ RenderModal( { items: posts, closeModal, action } ) {
const { createSuccessNotice, createErrorNotice } =
useDispatch( noticesStore );
const { deleteEntityRecord } = useDispatch( coreStore );
@@ -158,9 +158,7 @@ const trashPostAction = {
type: 'snackbar',
} );
}
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
+ action.onActionPerformed?.( posts );
closeModal();
} }
>
@@ -172,200 +170,176 @@ const trashPostAction = {
},
};
-function usePermanentlyDeletePostAction() {
- const { createSuccessNotice, createErrorNotice } =
- useDispatch( noticesStore );
- const { deleteEntityRecord } = useDispatch( coreStore );
-
- return useMemo(
- () => ( {
- id: 'permanently-delete',
- label: __( 'Permanently delete' ),
- supportsBulk: true,
- isEligible( { status } ) {
- return status === 'trash';
- },
- async callback( posts, onActionPerformed ) {
- const promiseResult = await Promise.allSettled(
- posts.map( ( post ) => {
- return deleteEntityRecord(
- 'postType',
- post.type,
- post.id,
- { force: true },
- { throwOnError: true }
- );
- } )
- );
- // 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" permanently deleted.' ),
- getItemTitle( posts[ 0 ] )
- );
+export const permanentlyDeletePostAction = {
+ id: 'permanently-delete',
+ label: __( 'Permanently delete' ),
+ supportsBulk: true,
+ isEligible( { status } ) {
+ return status === 'trash';
+ },
+ callback( posts ) {
+ return async ( { dispatch } ) => {
+ const { createSuccessNotice, createErrorNotice } =
+ dispatch( noticesStore );
+ const { deleteEntityRecord } = dispatch( coreStore );
+ const promiseResult = await Promise.allSettled(
+ posts.map( ( post ) => {
+ return deleteEntityRecord(
+ 'postType',
+ post.type,
+ post.id,
+ { force: true },
+ { throwOnError: true }
+ );
+ } )
+ );
+ // 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" permanently deleted.' ),
+ getItemTitle( posts[ 0 ] )
+ );
+ } else {
+ successMessage = __(
+ 'The posts were permanently deleted.'
+ );
+ }
+ createSuccessNotice( successMessage, {
+ type: 'snackbar',
+ id: 'permanently-delete-post-action',
+ } );
+ this?.onActionPerformed?.( posts );
+ } else {
+ // If there was at lease one failure.
+ let errorMessage;
+ // If we were trying to permanently delete a single post.
+ if ( promiseResult.length === 1 ) {
+ if ( promiseResult[ 0 ].reason?.message ) {
+ errorMessage = promiseResult[ 0 ].reason.message;
} else {
- successMessage = __(
- 'The posts were permanently deleted.'
+ errorMessage = __(
+ 'An error occurred while permanently deleting the post.'
);
}
- createSuccessNotice( successMessage, {
- type: 'snackbar',
- id: 'permanently-delete-post-action',
- } );
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
+ // If we were trying to permanently delete multiple posts
} else {
- // If there was at lease one failure.
- let errorMessage;
- // If we were trying to permanently delete a single post.
- if ( promiseResult.length === 1 ) {
- if ( promiseResult[ 0 ].reason?.message ) {
- errorMessage = promiseResult[ 0 ].reason.message;
- } else {
- errorMessage = __(
- 'An error occurred while permanently deleting the post.'
- );
- }
- // If we were trying to permanently delete multiple posts
- } 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 permanently deleting the posts.'
- );
- } else if ( errorMessages.size === 1 ) {
- errorMessage = sprintf(
- /* translators: %s: an error message */
- __(
- 'An error occurred while permanently deleting the posts: %s'
- ),
- [ ...errorMessages ][ 0 ]
- );
- } else {
- errorMessage = sprintf(
- /* translators: %s: a list of comma separated error messages */
- __(
- 'Some errors occurred while permanently deleting the posts: %s'
- ),
- [ ...errorMessages ].join( ',' )
- );
+ 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 );
}
}
- createErrorNotice( errorMessage, {
- type: 'snackbar',
- } );
- }
- },
- } ),
- [ createSuccessNotice, createErrorNotice, deleteEntityRecord ]
- );
-}
-
-function useRestorePostAction() {
- const { createSuccessNotice, createErrorNotice } =
- useDispatch( noticesStore );
- const { editEntityRecord, saveEditedEntityRecord } =
- useDispatch( coreStore );
-
- return useMemo(
- () => ( {
- id: 'restore',
- label: __( 'Restore' ),
- isPrimary: true,
- icon: backup,
- supportsBulk: true,
- isEligible( { status } ) {
- return status === 'trash';
- },
- async callback( posts, onActionPerformed ) {
- try {
- for ( const post of posts ) {
- await editEntityRecord(
- 'postType',
- post.type,
- post.id,
- {
- status: 'draft',
- }
+ if ( errorMessages.size === 0 ) {
+ errorMessage = __(
+ 'An error occurred while permanently deleting the posts.'
);
- await saveEditedEntityRecord(
- 'postType',
- post.type,
- post.id,
- { throwOnError: true }
+ } else if ( errorMessages.size === 1 ) {
+ errorMessage = sprintf(
+ /* translators: %s: an error message */
+ __(
+ 'An error occurred while permanently deleting the posts: %s'
+ ),
+ [ ...errorMessages ][ 0 ]
+ );
+ } else {
+ errorMessage = sprintf(
+ /* translators: %s: a list of comma separated error messages */
+ __(
+ 'Some errors occurred while permanently deleting the posts: %s'
+ ),
+ [ ...errorMessages ].join( ',' )
);
}
+ }
+ createErrorNotice( errorMessage, {
+ type: 'snackbar',
+ } );
+ }
+ };
+ },
+};
- createSuccessNotice(
- posts.length > 1
- ? sprintf(
- /* translators: The number of posts. */
- __( '%d posts have been restored.' ),
- posts.length
- )
- : sprintf(
- /* translators: The number of posts. */
- __( '"%s" has been restored.' ),
- getItemTitle( posts[ 0 ] )
- ),
+export const restorePostAction = {
+ id: 'restore',
+ label: __( 'Restore' ),
+ isPrimary: true,
+ icon: backup,
+ supportsBulk: true,
+ isEligible( { status } ) {
+ return status === 'trash';
+ },
+ callback( posts ) {
+ return async ( { dispatch } ) => {
+ const { createSuccessNotice, createErrorNotice } =
+ dispatch( noticesStore );
+ const { editEntityRecord, saveEditedEntityRecord } =
+ dispatch( coreStore );
+ try {
+ for ( const post of posts ) {
+ await editEntityRecord( 'postType', post.type, post.id, {
+ status: 'draft',
+ } );
+ await saveEditedEntityRecord(
+ 'postType',
+ post.type,
+ post.id,
{
- type: 'snackbar',
- id: 'restore-post-action',
+ throwOnError: true,
}
);
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
- } catch ( error ) {
- let errorMessage;
- if (
- error.message &&
- error.code !== 'unknown_error' &&
- error.message
- ) {
- errorMessage = error.message;
- } else if ( posts.length > 1 ) {
- errorMessage = __(
- 'An error occurred while restoring the posts.'
- );
- } else {
- errorMessage = __(
- 'An error occurred while restoring the post.'
- );
- }
+ }
- createErrorNotice( errorMessage, { type: 'snackbar' } );
+ createSuccessNotice(
+ posts.length > 1
+ ? sprintf(
+ /* translators: The number of posts. */
+ __( '%d posts have been restored.' ),
+ posts.length
+ )
+ : sprintf(
+ /* translators: The number of posts. */
+ __( '"%s" has been restored.' ),
+ getItemTitle( posts[ 0 ] )
+ ),
+ {
+ type: 'snackbar',
+ id: 'restore-post-action',
+ }
+ );
+ this?.onActionPerformed?.( posts );
+ } catch ( error ) {
+ let errorMessage;
+ if (
+ error.message &&
+ error.code !== 'unknown_error' &&
+ error.message
+ ) {
+ errorMessage = error.message;
+ } else if ( posts.length > 1 ) {
+ errorMessage = __(
+ 'An error occurred while restoring the posts.'
+ );
+ } else {
+ errorMessage = __(
+ 'An error occurred while restoring the post.'
+ );
}
- },
- } ),
- [
- createSuccessNotice,
- createErrorNotice,
- editEntityRecord,
- saveEditedEntityRecord,
- ]
- );
-}
-const viewPostAction = {
+ createErrorNotice( errorMessage, { type: 'snackbar' } );
+ }
+ };
+ },
+};
+
+export const viewPostAction = {
id: 'view-post',
label: __( 'View' ),
isPrimary: true,
@@ -373,16 +347,14 @@ const viewPostAction = {
isEligible( post ) {
return post.status !== 'trash';
},
- callback( posts, onActionPerformed ) {
+ callback( posts ) {
const post = posts[ 0 ];
window.open( post.link, '_blank' );
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
+ this?.onActionPerformed?.( posts );
},
};
-const editPostAction = {
+export const editPostAction = {
id: 'edit-post',
label: __( 'Edit' ),
isPrimary: true,
@@ -390,13 +362,11 @@ const editPostAction = {
isEligible( { status } ) {
return status !== 'trash';
},
- callback( posts, onActionPerformed ) {
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
+ callback( posts ) {
+ this?.onActionPerformed?.( posts );
},
};
-const postRevisionsAction = {
+export const postRevisionsAction = {
id: 'view-post-revisions',
label: __( 'View revisions' ),
isPrimary: false,
@@ -410,25 +380,23 @@ const postRevisionsAction = {
post?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0;
return lastRevisionId && revisionsCount > 1;
},
- callback( posts, onActionPerformed ) {
+ callback( posts ) {
const post = posts[ 0 ];
const href = addQueryArgs( 'revision.php', {
revision: post?._links?.[ 'predecessor-version' ]?.[ 0 ]?.id,
} );
document.location.href = href;
- if ( onActionPerformed ) {
- onActionPerformed( posts );
- }
+ this?.onActionPerformed?.( posts );
},
};
-const renamePostAction = {
+export const renamePostAction = {
id: 'rename-post',
label: __( 'Rename' ),
isEligible( post ) {
return post.status !== 'trash';
},
- RenderModal: ( { items, closeModal, onActionPerformed } ) => {
+ RenderModal: ( { items, closeModal, action } ) => {
const [ item ] = items;
const originalTitle = decodeEntities(
typeof item.title === 'string' ? item.title : item.title.rendered
@@ -455,7 +423,7 @@ const renamePostAction = {
createSuccessNotice( __( 'Name updated' ), {
type: 'snackbar',
} );
- onActionPerformed?.( items );
+ action.onActionPerformed?.( items );
} catch ( error ) {
const errorMessage =
error.message && error.code !== 'unknown_error'
@@ -500,13 +468,13 @@ const renamePostAction = {
},
};
-const resetTemplateAction = {
+export const resetTemplateAction = {
id: 'reset-template',
label: __( 'Reset' ),
isEligible: isTemplateRevertable,
supportsBulk: true,
hideModalHeader: true,
- RenderModal: ( { items, closeModal, onActionPerformed } ) => {
+ RenderModal: ( { items, closeModal, action } ) => {
const { revertTemplate } = unlock( useDispatch( editorStore ) );
const { saveEditedEntityRecord } = useDispatch( coreStore );
const { createSuccessNotice, createErrorNotice } =
@@ -541,6 +509,7 @@ const resetTemplateAction = {
id: 'revert-template-action',
}
);
+ action.onActionPerformed?.( items );
} catch ( error ) {
let fallbackErrorMessage;
if ( items[ 0 ].type === TEMPLATE_POST_TYPE ) {
@@ -583,7 +552,7 @@ const resetTemplateAction = {
variant="primary"
onClick={ async () => {
await onConfirm( items );
- onActionPerformed?.( items );
+ this?.onActionPerformed?.( items );
closeModal();
} }
>
@@ -612,13 +581,13 @@ function isTemplateRemovable( template ) {
);
}
-const deleteTemplateAction = {
+export const deleteTemplateAction = {
id: 'delete-template',
label: __( 'Delete' ),
isEligible: isTemplateRemovable,
supportsBulk: true,
hideModalHeader: true,
- RenderModal: ( { items: templates, closeModal, onActionPerformed } ) => {
+ RenderModal: ( { items: templates, closeModal, action } ) => {
const { removeTemplates } = unlock( useDispatch( editorStore ) );
return (
@@ -651,7 +620,7 @@ const deleteTemplateAction = {
await removeTemplates( templates, {
allowUndo: false,
} );
- onActionPerformed?.( templates );
+ action.onActionPerformed?.( templates );
closeModal();
} }
>
@@ -663,7 +632,7 @@ const deleteTemplateAction = {
},
};
-const renameTemplateAction = {
+export const renameTemplateAction = {
id: 'rename-template',
label: __( 'Rename' ),
isEligible: ( template ) => {
@@ -677,7 +646,7 @@ const renameTemplateAction = {
}
return true;
},
- RenderModal: ( { items: templates, closeModal, onActionPerformed } ) => {
+ RenderModal: ( { items: templates, closeModal, action } ) => {
const template = templates[ 0 ];
const title = decodeEntities( template.title.rendered );
const [ editedTitle, setEditedTitle ] = useState( title );
@@ -719,7 +688,7 @@ const renameTemplateAction = {
type: 'snackbar',
}
);
- onActionPerformed?.( templates );
+ action.onActionPerformed?.( templates );
} catch ( error ) {
const fallbackErrorMessage =
template.type === TEMPLATE_POST_TYPE
@@ -767,96 +736,3 @@ const renameTemplateAction = {
);
},
};
-
-export function usePostActions( onActionPerformed, actionIds = null ) {
- const permanentlyDeletePostAction = usePermanentlyDeletePostAction();
- const restorePostAction = useRestorePostAction();
- return useMemo(
- () => {
- // By default, return all actions...
- const defaultActions = [
- editPostAction,
- resetTemplateAction,
- viewPostAction,
- restorePostAction,
- deleteTemplateAction,
- permanentlyDeletePostAction,
- postRevisionsAction,
- renamePostAction,
- renameTemplateAction,
- trashPostAction,
- ];
-
- // ... unless `actionIds` was specified, in which case we find the
- // actions matching the given IDs.
- const actions = actionIds
- ? actionIds.map( ( actionId ) =>
- defaultActions.find( ( { id } ) => actionId === id )
- )
- : defaultActions;
-
- if ( onActionPerformed ) {
- for ( let i = 0; i < actions.length; ++i ) {
- if ( actions[ i ].callback ) {
- const existingCallback = actions[ i ].callback;
- actions[ i ] = {
- ...actions[ i ],
- callback: ( items, _onActionPerformed ) => {
- existingCallback( items, ( _items ) => {
- if ( _onActionPerformed ) {
- _onActionPerformed( _items );
- }
- onActionPerformed(
- actions[ i ].id,
- _items
- );
- } );
- },
- };
- }
- if ( actions[ i ].RenderModal ) {
- const ExistingRenderModal = actions[ i ].RenderModal;
- actions[ i ] = {
- ...actions[ i ],
- RenderModal: ( props ) => {
- return (
- {
- if ( props.onActionPerformed ) {
- props.onActionPerformed(
- _items
- );
- }
- onActionPerformed(
- actions[ i ].id,
- _items
- );
- } }
- />
- );
- },
- };
- }
- }
- }
- return actions;
- },
-
- // Disable reason: if provided, `actionIds` is a shallow array of
- // strings, and the strings themselves should be part of the useMemo
- // dependencies. Two different disable statements are needed, as the
- // first flags what it thinks are missing dependencies, and the second
- // flags the array spread operation.
- //
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [
- // eslint-disable-next-line react-hooks/exhaustive-deps
- ...( actionIds || [] ),
- permanentlyDeletePostAction,
- restorePostAction,
- onActionPerformed,
- ]
- );
-}
diff --git a/packages/editor/src/components/post-actions/index.js b/packages/editor/src/components/post-actions/index.js
index 48d83f992e7056..acf9596359dd4e 100644
--- a/packages/editor/src/components/post-actions/index.js
+++ b/packages/editor/src/components/post-actions/index.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { useSelect } from '@wordpress/data';
+import { useRegistry, useSelect } from '@wordpress/data';
import { useState, useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import {
@@ -15,7 +15,12 @@ import { moreVertical } from '@wordpress/icons';
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
-import { usePostActions } from './actions';
+import {
+ viewPostAction,
+ postRevisionsAction,
+ renamePostAction,
+ trashPostAction,
+} from './actions';
import { store as editorStore } from '../../store';
import {
TEMPLATE_POST_TYPE,
@@ -31,13 +36,6 @@ const {
kebabCase,
} = unlock( componentsPrivateApis );
-const POST_ACTIONS_WHILE_EDITING = [
- 'view-post',
- 'view-post-revisions',
- 'rename-post',
- 'move-to-trash',
-];
-
export default function PostActions( { onActionPerformed, buttonProps } ) {
const { postType, item } = useSelect( ( select ) => {
const { getCurrentPostType, getCurrentPost } = select( editorStore );
@@ -46,16 +44,26 @@ export default function PostActions( { onActionPerformed, buttonProps } ) {
item: getCurrentPost(),
};
} );
- const allActions = usePostActions(
- onActionPerformed,
- POST_ACTIONS_WHILE_EDITING
- );
const actions = useMemo( () => {
- return allActions.filter( ( action ) => {
+ const eligibleActions = [
+ viewPostAction,
+ postRevisionsAction,
+ renamePostAction,
+ trashPostAction,
+ ].filter( ( action ) => {
return ! action.isEligible || action.isEligible( item );
} );
- }, [ allActions, item ] );
+ return eligibleActions.map( ( action ) => {
+ return {
+ ...action,
+ onActionPerformed: ( ...args ) => {
+ onActionPerformed?.( action.id, ...args );
+ action.onActionPerformed?.( ...args );
+ },
+ };
+ } );
+ }, [ item, onActionPerformed ] );
if (
[
@@ -127,6 +135,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
setIsModalOpen( false ) }
+ action={ action }
/>
) }
@@ -136,6 +145,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
// Copied as is from packages/dataviews/src/item-actions.js
function ActionsDropdownMenuGroup( { actions, item } ) {
+ const registry = useRegistry();
return (
{ actions.map( ( action ) => {
@@ -153,7 +163,18 @@ function ActionsDropdownMenuGroup( { actions, item } ) {
action.callback( [ item ] ) }
+ onClick={ async () => {
+ const returnResult = await action.callback( [
+ item,
+ ] );
+ if ( typeof returnResult === 'function' ) {
+ await returnResult( {
+ registry,
+ select: registry.select,
+ dispatch: registry.dispatch,
+ } );
+ }
+ } }
/>
);
} ) }
diff --git a/packages/editor/src/private-apis.js b/packages/editor/src/private-apis.js
index aae3762794b4d6..c66fc85760b01d 100644
--- a/packages/editor/src/private-apis.js
+++ b/packages/editor/src/private-apis.js
@@ -23,7 +23,7 @@ import PostViewLink from './components/post-view-link';
import PreviewDropdown from './components/preview-dropdown';
import PreferencesModal from './components/preferences-modal';
import PostActions from './components/post-actions';
-import { usePostActions } from './components/post-actions/actions';
+import * as postActions from './components/post-actions/actions';
import PostCardPanel from './components/post-card-panel';
import PostStatus from './components/post-status';
import ToolsMoreMenuGroup from './components/more-menu/tools-more-menu-group';
@@ -47,7 +47,7 @@ lock( privateApis, {
PostViewLink,
PreviewDropdown,
PreferencesModal,
- usePostActions,
+ postActions,
PostCardPanel,
PostStatus,
ToolsMoreMenuGroup,