Skip to content

Commit

Permalink
Hide 'Add to Reusable Blocks' and 'Remove from Reusable Block' buttons
Browse files Browse the repository at this point in the history
Hide the 'Add to Reusable Blocks' and 'Remove from Reusable Blocks'
buttons instead of disabling them when the user does not have the
necessary permissions.
  • Loading branch information
noisysocks committed Dec 24, 2018
1 parent e5ba57a commit 0e5759e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import { compose } from '@wordpress/compose';

export function ReusableBlockConvertButton( {
isVisible,
isStaticBlock,
canCreateBlocks,
isReusable,
onConvertToStatic,
onConvertToReusable,
} ) {
Expand All @@ -26,17 +25,16 @@ export function ReusableBlockConvertButton( {

return (
<Fragment>
{ isStaticBlock && (
{ ! isReusable && (
<MenuItem
className="editor-block-settings-menu__control"
icon="controls-repeat"
disabled={ ! canCreateBlocks }
onClick={ onConvertToReusable }
>
{ __( 'Add to Reusable Blocks' ) }
</MenuItem>
) }
{ ! isStaticBlock && (
{ isReusable && (
<MenuItem
className="editor-block-settings-menu__control"
icon="controls-repeat"
Expand All @@ -60,30 +58,35 @@ export default compose( [

const blocks = getBlocksByClientId( clientIds );

const isVisible = (
// Hide 'Add to Reusable Blocks' when Reusable Blocks are disabled, i.e. when
// core/block is not in the allowed_block_types filter.
canInsertBlockType( 'core/block' ) &&

every( blocks, ( block ) => (
// 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 } ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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' ) }
</MenuItem>
Expand All @@ -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 <Confirm /> component or similar
// eslint-disable-next-line no-alert
const hasConfirmed = window.confirm( __(
Expand All @@ -62,7 +64,8 @@ export default compose( [
) );

if ( hasConfirmed ) {
deleteReusableBlock( id );
const block = getBlock( clientId );
deleteReusableBlock( block.attributes.ref );
onToggle();
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ describe( 'ReusableBlockConvertButton', () => {
const wrapper = getShallowRenderOutput(
<ReusableBlockConvertButton
isVisible
isStaticBlock
canCreateBlocks
isReusable={ false }
onConvertToReusable={ onConvert }
/>
);
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();
} );
Expand All @@ -45,7 +43,7 @@ describe( 'ReusableBlockConvertButton', () => {
const wrapper = getShallowRenderOutput(
<ReusableBlockConvertButton
isVisible
isStaticBlock={ false }
isReusable
onConvertToStatic={ onConvert }
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ describe( 'ReusableBlockDeleteButton', () => {
return renderer.getRenderOutput();
}

it( 'should not render when isVisible is false', () => {
const wrapper = getShallowRenderOutput(
<ReusableBlockDeleteButton isVisible={ false } />
);

expect( wrapper ).toBe( null );
} );

it( 'matches the snapshot', () => {
const wrapper = getShallowRenderOutput(
<ReusableBlockDeleteButton
role="menuitem"
id={ 123 }
isVisible
isDisabled={ false }
onDelete={ noop }
/>
Expand All @@ -33,13 +41,13 @@ describe( 'ReusableBlockDeleteButton', () => {
const onDelete = jest.fn();
const wrapper = getShallowRenderOutput(
<ReusableBlockDeleteButton
id={ 123 }
isVisible
isDisabled={ false }
onDelete={ onDelete }
/>
);

wrapper.props.onClick();
expect( onDelete ).toHaveBeenCalledWith( 123 );
expect( onDelete ).toHaveBeenCalled();
} );
} );

0 comments on commit 0e5759e

Please sign in to comment.