diff --git a/packages/editor/src/components/block-settings-menu/reusable-block-convert-button.js b/packages/editor/src/components/block-settings-menu/reusable-block-convert-button.js index 75b675e6c404d..3932c7723a6a2 100644 --- a/packages/editor/src/components/block-settings-menu/reusable-block-convert-button.js +++ b/packages/editor/src/components/block-settings-menu/reusable-block-convert-button.js @@ -15,8 +15,7 @@ import { compose } from '@wordpress/compose'; export function ReusableBlockConvertButton( { isVisible, - isStaticBlock, - canCreateBlocks, + isReusable, onConvertToStatic, onConvertToReusable, } ) { @@ -26,17 +25,16 @@ export function ReusableBlockConvertButton( { return ( - { isStaticBlock && ( + { ! isReusable && ( { __( 'Add to Reusable Blocks' ) } ) } - { ! isStaticBlock && ( + { isReusable && ( ( - // Guard against the case where a regular block has *just* been converted to a - // reusable block and doesn't yet exist in the editor store. - !! block && - // Only show the option to covert to reusable blocks on valid blocks. - block.isValid && - // Make sure the block supports being converted into a reusable block (by default that is the case). - hasBlockSupport( block.name, 'reusable', true ) - ) ) + const isReusable = ( + blocks.length === 1 && + blocks[ 0 ] && + isReusableBlock( blocks[ 0 ] ) && + !! getReusableBlock( blocks[ 0 ].attributes.ref ) ); return { - isVisible, - isStaticBlock: isVisible && ( - blocks.length !== 1 || - ! isReusableBlock( blocks[ 0 ] ) || - ! getReusableBlock( blocks[ 0 ].attributes.ref ) + // Show 'Convert to Regular Block' when selected block is a reusable block + isVisible: isReusable || ( + // Hide 'Add to Reusable Blocks' when reusable blocks are disabled + canInsertBlockType( 'core/block' ) && + + every( blocks, ( block ) => ( + // Guard against the case where a regular block has *just* been converted + !! block && + + // Hide 'Add to Reusable Blocks' on invalid blocks + block.isValid && + + // Hide 'Add to Reusable Blocks' when block doesn't support being made reusable + hasBlockSupport( block.name, 'reusable', true ) + ) ) && + + // Hide 'Add to Reusable Blocks' when current doesn't have permission to do that + canUser( 'create', 'blocks' ) ), - canCreateBlocks: canUser( 'create', 'blocks' ), + + isReusable, }; } ), withDispatch( ( dispatch, { clientIds, onToggle = noop } ) => { diff --git a/packages/editor/src/components/block-settings-menu/reusable-block-delete-button.js b/packages/editor/src/components/block-settings-menu/reusable-block-delete-button.js index 53d0737abc452..0bd65bbaa2b1d 100644 --- a/packages/editor/src/components/block-settings-menu/reusable-block-delete-button.js +++ b/packages/editor/src/components/block-settings-menu/reusable-block-delete-button.js @@ -12,8 +12,8 @@ import { __ } from '@wordpress/i18n'; import { isReusableBlock } from '@wordpress/blocks'; import { withSelect, withDispatch } from '@wordpress/data'; -export function ReusableBlockDeleteButton( { id, isDisabled, onDelete } ) { - if ( ! id ) { +export function ReusableBlockDeleteButton( { isVisible, isDisabled, onDelete } ) { + if ( ! isVisible ) { return null; } @@ -22,7 +22,7 @@ export function ReusableBlockDeleteButton( { id, isDisabled, onDelete } ) { className="editor-block-settings-menu__control" icon="no" disabled={ isDisabled } - onClick={ () => onDelete( id ) } + onClick={ () => onDelete() } > { __( 'Remove from Reusable Blocks' ) } @@ -39,21 +39,23 @@ export default compose( [ const block = getBlock( clientId ); - const id = block && isReusableBlock( block ) ? block.attributes.ref : null; + const reusableBlock = block && isReusableBlock( block ) ? + getReusableBlock( block.attributes.ref ) : + null; + return { - id, - isDisabled: !! id && ( - getReusableBlock( id ).isTemporary || ! canUser( 'delete', 'blocks', id ) - ), + isVisible: !! reusableBlock && canUser( 'delete', 'blocks', reusableBlock.id ), + isDisabled: reusableBlock && reusableBlock.isTemporary, }; } ), - withDispatch( ( dispatch, { onToggle = noop } ) => { + withDispatch( ( dispatch, { clientId, onToggle = noop }, { select } ) => { const { __experimentalDeleteReusableBlock: deleteReusableBlock, } = dispatch( 'core/editor' ); + const { getBlock } = select( 'core/editor' ); return { - onDelete( id ) { + onDelete() { // TODO: Make this a component or similar // eslint-disable-next-line no-alert const hasConfirmed = window.confirm( __( @@ -62,7 +64,8 @@ export default compose( [ ) ); if ( hasConfirmed ) { - deleteReusableBlock( id ); + const block = getBlock( clientId ); + deleteReusableBlock( block.attributes.ref ); onToggle(); } }, diff --git a/packages/editor/src/components/block-settings-menu/test/reusable-block-convert-button.js b/packages/editor/src/components/block-settings-menu/test/reusable-block-convert-button.js index 13a000306d930..c6fba313e31b3 100644 --- a/packages/editor/src/components/block-settings-menu/test/reusable-block-convert-button.js +++ b/packages/editor/src/components/block-settings-menu/test/reusable-block-convert-button.js @@ -27,15 +27,13 @@ describe( 'ReusableBlockConvertButton', () => { const wrapper = getShallowRenderOutput( ); expect( wrapper.props.children[ 1 ] ).toBeFalsy(); const button = wrapper.props.children[ 0 ]; expect( button.props.children ).toBe( 'Add to Reusable Blocks' ); - expect( button.props.disabled ).toBe( false ); button.props.onClick(); expect( onConvert ).toHaveBeenCalled(); } ); @@ -45,7 +43,7 @@ describe( 'ReusableBlockConvertButton', () => { const wrapper = getShallowRenderOutput( ); diff --git a/packages/editor/src/components/block-settings-menu/test/reusable-block-delete-button.js b/packages/editor/src/components/block-settings-menu/test/reusable-block-delete-button.js index ec1e18959d4e8..39299becf29c2 100644 --- a/packages/editor/src/components/block-settings-menu/test/reusable-block-delete-button.js +++ b/packages/editor/src/components/block-settings-menu/test/reusable-block-delete-button.js @@ -16,11 +16,19 @@ describe( 'ReusableBlockDeleteButton', () => { return renderer.getRenderOutput(); } + it( 'should not render when isVisible is false', () => { + const wrapper = getShallowRenderOutput( + + ); + + expect( wrapper ).toBe( null ); + } ); + it( 'matches the snapshot', () => { const wrapper = getShallowRenderOutput( @@ -33,13 +41,13 @@ describe( 'ReusableBlockDeleteButton', () => { const onDelete = jest.fn(); const wrapper = getShallowRenderOutput( ); wrapper.props.onClick(); - expect( onDelete ).toHaveBeenCalledWith( 123 ); + expect( onDelete ).toHaveBeenCalled(); } ); } );