diff --git a/editor/components/block-settings-menu/block-transformations.js b/editor/components/block-settings-menu/block-transformations.js index 8f936e2503752a..8c863c9bd3fea2 100644 --- a/editor/components/block-settings-menu/block-transformations.js +++ b/editor/components/block-settings-menu/block-transformations.js @@ -1,13 +1,13 @@ /** * External dependencies */ -import { noop } from 'lodash'; +import { castArray, filter, first, mapKeys, noop, sortBy } from 'lodash'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { IconButton } from '@wordpress/components'; +import { IconButton, ifCondition } from '@wordpress/components'; import { getPossibleBlockTransformations, switchToBlockType } from '@wordpress/blocks'; import { compose, Fragment } from '@wordpress/element'; import { withSelect, withDispatch } from '@wordpress/data'; @@ -17,9 +17,16 @@ import { withSelect, withDispatch } from '@wordpress/data'; */ import './style.scss'; -function BlockTransformations( { blocks, small = false, onTransform, onClick = noop, isLocked, itemsRole } ) { - const possibleBlockTransformations = getPossibleBlockTransformations( blocks ); - if ( isLocked || ! possibleBlockTransformations.length ) { +function BlockTransformations( { blocks, small = false, onTransform, onClick = noop, inserterItems, itemsRole } ) { + const itemsByName = mapKeys( inserterItems, ( { name } ) => name ); + const possibleBlockTransformations = sortBy( + filter( + getPossibleBlockTransformations( blocks ), + ( block ) => !! itemsByName[ block.name ] + ), + ( block ) => -itemsByName[ block.name ].frecency, + ); + if ( ! possibleBlockTransformations.length ) { return null; } return ( @@ -52,13 +59,14 @@ function BlockTransformations( { blocks, small = false, onTransform, onClick = n } export default compose( [ withSelect( ( select, { uids } ) => { - const { getEditorSettings, getBlocksByUID } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getBlocksByUID, getBlockRootUID, getInserterItems } = select( 'core/editor' ); + const rootUID = getBlockRootUID( first( castArray( uids ) ) ); return { - isLocked: !! templateLock, blocks: getBlocksByUID( uids ), + inserterItems: getInserterItems( rootUID ), }; } ), + ifCondition( ( { inserterItems } ) => inserterItems.length > 0 ), withDispatch( ( dispatch, ownProps ) => ( { onTransform( blocks, name ) { dispatch( 'core/editor' ).replaceBlocks( diff --git a/editor/components/block-switcher/index.js b/editor/components/block-switcher/index.js index 23441f8b3da71b..f01d007d3849fd 100644 --- a/editor/components/block-switcher/index.js +++ b/editor/components/block-switcher/index.js @@ -1,8 +1,13 @@ +/** + * External dependencies + */ +import { castArray, filter, first, mapKeys, sortBy } from 'lodash'; + /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Dropdown, Dashicon, IconButton, Toolbar, NavigableMenu } from '@wordpress/components'; +import { Dropdown, Dashicon, IconButton, ifCondition, Toolbar, NavigableMenu } from '@wordpress/components'; import { getBlockType, getPossibleBlockTransformations, switchToBlockType } from '@wordpress/blocks'; import { compose } from '@wordpress/element'; import { keycodes } from '@wordpress/utils'; @@ -19,10 +24,17 @@ import BlockIcon from '../block-icon'; */ const { DOWN } = keycodes; -export function BlockSwitcher( { blocks, onTransform, isLocked } ) { - const allowedBlocks = getPossibleBlockTransformations( blocks ); +export function BlockSwitcher( { blocks, onTransform, inserterItems } ) { + const itemsByName = mapKeys( inserterItems, ( { name } ) => name ); + const possibleBlockTransformations = sortBy( + filter( + getPossibleBlockTransformations( blocks ), + ( block ) => !! itemsByName[ block.name ] + ), + ( block ) => -itemsByName[ block.name ].frecency, + ); - if ( isLocked || ! allowedBlocks.length ) { + if ( ! possibleBlockTransformations.length ) { return null; } @@ -71,7 +83,7 @@ export function BlockSwitcher( { blocks, onTransform, isLocked } ) { role="menu" aria-label={ __( 'Block types' ) } > - { allowedBlocks.map( ( { name, title, icon } ) => ( + { possibleBlockTransformations.map( ( { name, title, icon } ) => ( { @@ -97,14 +109,15 @@ export function BlockSwitcher( { blocks, onTransform, isLocked } ) { } export default compose( - withSelect( ( select, ownProps ) => { - const { getBlock, getEditorSettings } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + withSelect( ( select, { uids } ) => { + const { getBlocksByUID, getBlockRootUID, getInserterItems } = select( 'core/editor' ); + const rootUID = getBlockRootUID( first( castArray( uids ) ) ); return { - blocks: ownProps.uids.map( getBlock ), - isLocked: !! templateLock, + blocks: getBlocksByUID( uids ), + inserterItems: getInserterItems( rootUID ), }; } ), + ifCondition( ( { inserterItems } ) => inserterItems.length > 0 ), withDispatch( ( dispatch, ownProps ) => ( { onTransform( blocks, name ) { dispatch( 'core/editor' ).replaceBlocks( diff --git a/editor/components/block-switcher/test/__snapshots__/index.js.snap b/editor/components/block-switcher/test/__snapshots__/index.js.snap index 3c19baa2d4fd1f..59f47f0fb18d56 100644 --- a/editor/components/block-switcher/test/__snapshots__/index.js.snap +++ b/editor/components/block-switcher/test/__snapshots__/index.js.snap @@ -1,10 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`BlockSwitcher should render switcher with blocks 1`] = ` - -`; +exports[`BlockSwitcher should render switcher with blocks 1`] = `""`; diff --git a/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap b/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap index c35141f5834c4f..32b3d7ac329d0d 100644 --- a/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap +++ b/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MultiBlocksSwitcher should return a BlockSwitcher element matching the snapshot. 1`] = ` - { headingBlock1, ]; + const inserterItems = [ + { name: 'core/quote', frecency: 1 }, + { name: 'core/cover-image', frecency: 2 }, + { name: 'core/paragraph', frecency: 3 }, + { name: 'core/heading', frecency: 4 }, + { name: 'core/text', frecency: 5 }, + ]; + const onTransformStub = jest.fn(); const getDropdown = () => { - const blockSwitcher = shallow( ); + const blockSwitcher = shallow( ); return blockSwitcher.find( 'Dropdown' ); };