Skip to content

Commit

Permalink
proof of concept: freeze modal while trashing bulk items
Browse files Browse the repository at this point in the history
(this is meant to be reverted or built upon; I just wanted to share my
concept)
  • Loading branch information
mcsf committed Apr 12, 2024
1 parent d55db7d commit e019c92
Showing 1 changed file with 130 additions and 111 deletions.
241 changes: 130 additions & 111 deletions packages/editor/src/components/post-actions/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 { useMemo, useState, useRef } from '@wordpress/element';

import {
Button,
Expand All @@ -25,6 +25,12 @@ function getItemTitle( item ) {
return decodeEntities( item.title?.rendered || '' );
}

function WithFrozenChildren( { shouldFreeze, children } ) {
const cachedChildren = useRef( children );
if ( ! shouldFreeze ) cachedChildren.current = children;
return cachedChildren.current;
}

export const trashPostAction = {
id: 'move-to-trash',
label: __( 'Move to Trash' ),
Expand All @@ -39,127 +45,140 @@ export const trashPostAction = {
const { createSuccessNotice, createErrorNotice } =
useDispatch( noticesStore );
const { deleteEntityRecord } = useDispatch( coreStore );
const [ shouldFreeze, setShouldFreeze ] = useState( false );
return (
<VStack spacing="5">
<Text>
{ posts.length === 1
? sprintf(
// translators: %s: The page's title.
__( 'Are you sure you want to delete "%s"?' ),
getItemTitle( posts[ 0 ] )
)
: sprintf(
// translators: %d: The number of pages (2 or more).
_n(
'Are you sure you want to delete %d page?',
'Are you sure you want to delete %d pages?',
<WithFrozenChildren shouldFreeze={ shouldFreeze }>
<VStack spacing="5">
<Text>
{ posts.length === 1
? sprintf(
// translators: %s: The page's title.
__(
'Are you sure you want to delete "%s"?'
),
getItemTitle( posts[ 0 ] )
)
: sprintf(
// translators: %d: The number of pages (2 or more).
_n(
'Are you sure you want to delete %d page?',
'Are you sure you want to delete %d pages?',
posts.length
),
posts.length
),
posts.length
) }
</Text>
<HStack justify="right">
<Button variant="tertiary" onClick={ closeModal }>
{ __( 'Cancel' ) }
</Button>
<Button
variant="primary"
onClick={ async () => {
const promiseResult = await Promise.allSettled(
posts.map( ( post ) => {
return deleteEntityRecord(
'postType',
post.type,
post.id,
{},
{ 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" moved to the Trash.' ),
getItemTitle( posts[ 0 ] )
);
} else {
successMessage = __(
'Pages moved to the Trash.'
);
}
createSuccessNotice( successMessage, {
type: 'snackbar',
id: 'edit-site-page-trashed',
} );
} 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;
) }
</Text>
<HStack justify="right">
<Button variant="tertiary" onClick={ closeModal }>
{ __( 'Cancel' ) }
</Button>
<Button
variant="primary"
onClick={ async () => {
setShouldFreeze( true );
const promiseResult = await Promise.allSettled(
posts.map( ( post ) => {
return deleteEntityRecord(
'postType',
post.type,
post.id,
{},
{ 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" moved to the Trash.' ),
getItemTitle( posts[ 0 ] )
);
} else {
errorMessage = __(
'An error occurred while moving the post to the trash.'
successMessage = __(
'Pages moved to the Trash.'
);
}
// If we were trying to move multiple posts to the trash
createSuccessNotice( successMessage, {
type: 'snackbar',
id: 'edit-site-page-trashed',
} );
} 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 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 moving the post to the trash.'
);
}
}
if ( errorMessages.size === 0 ) {
errorMessage = __(
'An error occurred while moving the posts to the trash.'
);
} else if ( errorMessages.size === 1 ) {
errorMessage = sprintf(
/* translators: %s: an error message */
__(
'An error occurred while moving the posts to the trash: %s'
),
[ ...errorMessages ][ 0 ]
);
// If we were trying to move multiple posts to the trash
} else {
errorMessage = sprintf(
/* translators: %s: a list of comma separated error messages */
__(
'Some errors occurred while moving the pages to the trash: %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
);
}
}
if ( errorMessages.size === 0 ) {
errorMessage = __(
'An error occurred while moving the posts to the trash.'
);
} else if ( errorMessages.size === 1 ) {
errorMessage = sprintf(
/* translators: %s: an error message */
__(
'An error occurred while moving the posts to the trash: %s'
),
[ ...errorMessages ][ 0 ]
);
} else {
errorMessage = sprintf(
/* translators: %s: a list of comma separated error messages */
__(
'Some errors occurred while moving the pages to the trash: %s'
),
[ ...errorMessages ].join( ',' )
);
}
}
createErrorNotice( errorMessage, {
type: 'snackbar',
} );
}
createErrorNotice( errorMessage, {
type: 'snackbar',
} );
}
if ( onActionPerformed ) {
onActionPerformed( posts );
}
closeModal();
} }
>
{ __( 'Delete' ) }
</Button>
</HStack>
</VStack>
if ( onActionPerformed ) {
onActionPerformed( posts );
}
closeModal();
} }
>
{ __( 'Delete' ) }
</Button>
</HStack>
</VStack>
</WithFrozenChildren>
);
},
};
Expand Down

0 comments on commit e019c92

Please sign in to comment.