Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataViews Extensibility: Allow unregistering restore post action #64134

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 1 addition & 109 deletions packages/editor/src/components/post-actions/actions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { external, backup } from '@wordpress/icons';
import { external } from '@wordpress/icons';
import { addQueryArgs } from '@wordpress/url';
import { useDispatch, useSelect } from '@wordpress/data';
import { decodeEntities } from '@wordpress/html-entities';
Expand Down Expand Up @@ -81,113 +81,6 @@ function isTemplateRemovable( template ) {
);
}

const restorePostAction = {
id: 'restore',
label: __( 'Restore' ),
isPrimary: true,
icon: backup,
supportsBulk: true,
isEligible( { status, permissions } ) {
return status === 'trash' && permissions?.update;
},
async callback( posts, { registry, onActionPerformed } ) {
const { createSuccessNotice, createErrorNotice } =
registry.dispatch( noticesStore );
const { editEntityRecord, saveEditedEntityRecord } =
registry.dispatch( coreStore );
await Promise.allSettled(
posts.map( ( post ) => {
return editEntityRecord( 'postType', post.type, post.id, {
status: 'draft',
} );
} )
);
const promiseResult = await Promise.allSettled(
posts.map( ( post ) => {
return saveEditedEntityRecord( 'postType', post.type, post.id, {
throwOnError: true,
} );
} )
);

if ( promiseResult.every( ( { status } ) => status === 'fulfilled' ) ) {
let successMessage;
if ( posts.length === 1 ) {
successMessage = sprintf(
/* translators: The number of posts. */
__( '"%s" has been restored.' ),
getItemTitle( posts[ 0 ] )
);
} else if ( posts[ 0 ].type === 'page' ) {
successMessage = sprintf(
/* translators: The number of posts. */
__( '%d pages have been restored.' ),
posts.length
);
} else {
successMessage = sprintf(
/* translators: The number of posts. */
__( '%d posts have been restored.' ),
posts.length
);
}
createSuccessNotice( successMessage, {
type: 'snackbar',
id: 'restore-post-action',
} );
if ( onActionPerformed ) {
onActionPerformed( posts );
}
} else {
// If there was at lease one failure.
let errorMessage;
// If we were trying to move a single post to the trash.
if ( promiseResult.length === 1 ) {
if ( promiseResult[ 0 ].reason?.message ) {
errorMessage = promiseResult[ 0 ].reason.message;
} else {
errorMessage = __(
'An error occurred while restoring the post.'
);
}
// If we were trying to move multiple posts to the trash
} 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 restoring the posts.'
);
} else if ( errorMessages.size === 1 ) {
errorMessage = sprintf(
/* translators: %s: an error message */
__( 'An error occurred while restoring the posts: %s' ),
[ ...errorMessages ][ 0 ]
);
} else {
errorMessage = sprintf(
/* translators: %s: a list of comma separated error messages */
__(
'Some errors occurred while restoring the posts: %s'
),
[ ...errorMessages ].join( ',' )
);
}
}
createErrorNotice( errorMessage, {
type: 'snackbar',
} );
}
},
};

const viewPostAction = {
id: 'view-post',
label: __( 'View' ),
Expand Down Expand Up @@ -726,7 +619,6 @@ export function usePostActions( { postType, onActionPerformed, context } ) {
isPattern && userCanCreatePostType && duplicatePatternAction,
supportsTitle && renamePostAction,
reorderPagesAction,
! isTemplateOrTemplatePart && ! isPattern && restorePostAction,
...defaultActions,
].filter( Boolean );
// Filter actions based on provided context. If not provided
Expand Down
2 changes: 2 additions & 0 deletions packages/editor/src/dataviews/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import exportPattern from './export-pattern';
import resetPost from './reset-post';
import trashPost from './trash-post';
import permanentlyDeletePost from './permanently-delete-post';
import restorePost from './restore-post';

// @ts-ignore
import { store as editorStore } from '../../store';
Expand All @@ -23,6 +24,7 @@ export default function registerDefaultActions() {

registerEntityAction( 'postType', 'wp_block', exportPattern );
registerEntityAction( 'postType', '*', resetPost );
registerEntityAction( 'postType', '*', restorePost );
registerEntityAction( 'postType', '*', deletePost );
registerEntityAction( 'postType', '*', trashPost );
registerEntityAction( 'postType', '*', permanentlyDeletePost );
Expand Down
134 changes: 134 additions & 0 deletions packages/editor/src/dataviews/actions/restore-post.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* WordPress dependencies
*/
import { backup } from '@wordpress/icons';
import { store as coreStore } from '@wordpress/core-data';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import type { Action } from '@wordpress/dataviews';

/**
* Internal dependencies
*/
import { getItemTitle, isTemplateOrTemplatePart } from './utils';
import type { CoreDataError, PostWithPermissions } from '../types';

const restorePost: Action< PostWithPermissions > = {
id: 'restore',
label: __( 'Restore' ),
isPrimary: true,
icon: backup,
supportsBulk: true,
isEligible( item ) {
return (
! isTemplateOrTemplatePart( item ) &&
item.type !== 'wp_block' &&
item.status === 'trash' &&
item.permissions?.update
);
},
async callback( posts, { registry, onActionPerformed } ) {
const { createSuccessNotice, createErrorNotice } =
registry.dispatch( noticesStore );
const { editEntityRecord, saveEditedEntityRecord } =
registry.dispatch( coreStore );
await Promise.allSettled(
posts.map( ( post ) => {
return editEntityRecord( 'postType', post.type, post.id, {
status: 'draft',
} );
} )
);
const promiseResult = await Promise.allSettled(
posts.map( ( post ) => {
return saveEditedEntityRecord( 'postType', post.type, post.id, {
throwOnError: true,
} );
} )
);

if ( promiseResult.every( ( { status } ) => status === 'fulfilled' ) ) {
let successMessage;
if ( posts.length === 1 ) {
successMessage = sprintf(
/* translators: The number of posts. */
__( '"%s" has been restored.' ),
getItemTitle( posts[ 0 ] )
);
} else if ( posts[ 0 ].type === 'page' ) {
successMessage = sprintf(
/* translators: The number of posts. */
__( '%d pages have been restored.' ),
posts.length
);
} else {
successMessage = sprintf(
/* translators: The number of posts. */
__( '%d posts have been restored.' ),
posts.length
);
}
createSuccessNotice( successMessage, {
type: 'snackbar',
id: 'restore-post-action',
} );
if ( onActionPerformed ) {
onActionPerformed( posts );
}
} else {
// If there was at lease one failure.
let errorMessage;
// If we were trying to move a single post to the trash.
if ( promiseResult.length === 1 ) {
const typedError = promiseResult[ 0 ] as {
reason?: CoreDataError;
};
if ( typedError.reason?.message ) {
errorMessage = typedError.reason.message;
} else {
errorMessage = __(
'An error occurred while restoring the post.'
);
}
// If we were trying to move multiple posts to the trash
} else {
const errorMessages = new Set();
const failedPromises = promiseResult.filter(
( { status } ) => status === 'rejected'
);
for ( const failedPromise of failedPromises ) {
const typedError = failedPromise as {
reason?: CoreDataError;
};
if ( typedError.reason?.message ) {
errorMessages.add( typedError.reason.message );
}
}
if ( errorMessages.size === 0 ) {
errorMessage = __(
'An error occurred while restoring the posts.'
);
} else if ( errorMessages.size === 1 ) {
errorMessage = sprintf(
/* translators: %s: an error message */
__( 'An error occurred while restoring the posts: %s' ),
[ ...errorMessages ][ 0 ]
);
} else {
errorMessage = sprintf(
/* translators: %s: a list of comma separated error messages */
__(
'Some errors occurred while restoring the posts: %s'
),
[ ...errorMessages ].join( ',' )
);
}
}
createErrorNotice( errorMessage, {
type: 'snackbar',
} );
}
},
};

export default restorePost;
Loading