From 338e34095f1540256c6c0f78e6b49b5e1877b11e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 19 Sep 2024 14:55:24 +0100 Subject: [PATCH 1/7] Inserter: Update how we compute the actual insertion point for blocks --- .../inserter/hooks/use-block-types-state.js | 58 ++++++++++--------- .../inserter/hooks/use-insertion-point.js | 35 +++++++---- .../src/store/private-selectors.js | 35 +++++++++++ packages/block-editor/src/store/selectors.js | 53 +---------------- packages/block-editor/src/store/utils.js | 3 +- 5 files changed, 93 insertions(+), 91 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js index 8db23267eee8f..955f2fb97d3ae 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js @@ -14,7 +14,8 @@ import { useCallback, useMemo } from '@wordpress/element'; * Internal dependencies */ import { store as blockEditorStore } from '../../../store'; -import { withRootClientIdOptionKey } from '../../../store/utils'; +import { noFilter } from '../../../store/utils'; +import { unlock } from '../../../lock-unlock'; /** * Retrieves the block types inserter state. @@ -26,7 +27,7 @@ import { withRootClientIdOptionKey } from '../../../store/utils'; */ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { const options = useMemo( - () => ( { [ withRootClientIdOptionKey ]: ! isQuick } ), + () => ( { [ noFilter ]: ! isQuick } ), [ isQuick ] ); const [ items ] = useSelect( @@ -38,6 +39,9 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { ], [ rootClientId, options ] ); + const { getClosestAllowedInsertionPoint } = unlock( + useSelect( blockEditorStore ) + ); const [ categories, collections ] = useSelect( ( select ) => { const { getCategories, getCollections } = select( blocksStore ); @@ -46,35 +50,35 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { const onSelectItem = useCallback( ( - { - name, - initialAttributes, - innerBlocks, - syncStatus, - content, - rootClientId: _rootClientId, - }, + { name, initialAttributes, innerBlocks, syncStatus, content }, shouldFocusBlock ) => { - const insertedBlock = - syncStatus === 'unsynced' - ? parse( content, { - __unstableSkipMigrationLogs: true, - } ) - : createBlock( - name, - initialAttributes, - createBlocksFromInnerBlocksTemplate( innerBlocks ) - ); - - onInsert( - insertedBlock, - undefined, - shouldFocusBlock, - _rootClientId + const destinationClientId = getClosestAllowedInsertionPoint( + name, + rootClientId ); + if ( destinationClientId !== null ) { + const insertedBlock = + syncStatus === 'unsynced' + ? parse( content, { + __unstableSkipMigrationLogs: true, + } ) + : createBlock( + name, + initialAttributes, + createBlocksFromInnerBlocksTemplate( + innerBlocks + ) + ); + onInsert( + insertedBlock, + undefined, + shouldFocusBlock, + destinationClientId + ); + } }, - [ onInsert ] + [ onInsert, getClosestAllowedInsertionPoint, rootClientId ] ); return [ items, categories, collections, onSelectItem ]; diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js index 24074ec500456..0cd71bf77b983 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js +++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js @@ -71,7 +71,11 @@ function useInsertionPoint( { selectBlockOnInsert = true, } ) { const registry = useRegistry(); - const { getSelectedBlock } = useSelect( blockEditorStore ); + const { + getSelectedBlock, + getClosestAllowedInsertionPoint, + isBlockInsertionPointVisible, + } = unlock( useSelect( blockEditorStore ) ); const { destinationRootClientId, destinationIndex } = useSelect( ( select ) => { const { @@ -193,21 +197,30 @@ function useInsertionPoint( { const onToggleInsertionPoint = useCallback( ( item ) => { - if ( item?.hasOwnProperty( 'rootClientId' ) ) { - showInsertionPoint( - item.rootClientId, - getIndex( { - destinationRootClientId, - destinationIndex, - rootClientId: item.rootClientId, - registry, - } ) - ); + if ( item && ! isBlockInsertionPointVisible() ) { + const allowedDestinationRootClientId = + getClosestAllowedInsertionPoint( + item.name, + destinationRootClientId + ); + if ( allowedDestinationRootClientId !== null ) { + showInsertionPoint( + allowedDestinationRootClientId, + getIndex( { + destinationRootClientId, + destinationIndex, + rootClientId: allowedDestinationRootClientId, + registry, + } ) + ); + } } else { hideInsertionPoint(); } }, [ + getClosestAllowedInsertionPoint, + isBlockInsertionPointVisible, showInsertionPoint, hideInsertionPoint, destinationRootClientId, diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index 9e99176819ae8..6b4ea779942fe 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -16,6 +16,7 @@ import { getTemplateLock, getClientIdsWithDescendants, isNavigationMode, + getBlockRootClientId, } from './selectors'; import { checkAllowListRecursive, @@ -637,3 +638,37 @@ export function getZoomLevel( state ) { export function isZoomOut( state ) { return getZoomLevel( state ) < 100; } + +/* + * + * @param {Object} state Editor state. + * @param {string} name Block name. + * @param {string} clientId Default insertion point. + */ +export function getClosestAllowedInsertionPoint( state, name, clientId = '' ) { + // If we're trying to insert at the root level and it's not allowed + // Try the section root instead. + if ( ! clientId ) { + if ( canInsertBlockType( state, name, clientId ) ) { + return clientId; + } + + const sectionRootClientId = getSectionRootClientId( state ); + if ( + sectionRootClientId && + canInsertBlockType( state, name, sectionRootClientId ) + ) { + return sectionRootClientId; + } + return null; + } + + // Traverse the block tree up until we find a place where we can insert. + let current = clientId; + while ( current !== null && ! canInsertBlockType( state, name, current ) ) { + const parentClientId = getBlockRootClientId( state, current ); + current = parentClientId; + } + + return current; +} diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 20d6627398886..96b64d118d569 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -21,7 +21,7 @@ import { createSelector, createRegistrySelector } from '@wordpress/data'; * Internal dependencies */ import { - withRootClientIdOptionKey, + noFilter, checkAllowListRecursive, checkAllowList, getAllPatternsDependants, @@ -2056,56 +2056,7 @@ export const getInserterItems = createRegistrySelector( ( select ) => ) .map( buildBlockTypeInserterItem ); - if ( options[ withRootClientIdOptionKey ] ) { - blockTypeInserterItems = blockTypeInserterItems.reduce( - ( accumulator, item ) => { - item.rootClientId = rootClientId ?? ''; - - while ( - ! canInsertBlockTypeUnmemoized( - state, - item.name, - item.rootClientId - ) - ) { - if ( ! item.rootClientId ) { - let sectionRootClientId; - try { - sectionRootClientId = - getSectionRootClientId( state ); - } catch ( e ) {} - if ( - sectionRootClientId && - canInsertBlockTypeUnmemoized( - state, - item.name, - sectionRootClientId - ) - ) { - item.rootClientId = sectionRootClientId; - } else { - delete item.rootClientId; - } - break; - } else { - const parentClientId = getBlockRootClientId( - state, - item.rootClientId - ); - item.rootClientId = parentClientId; - } - } - - // We could also add non insertable items and gray them out. - if ( item.hasOwnProperty( 'rootClientId' ) ) { - accumulator.push( item ); - } - - return accumulator; - }, - [] - ); - } else { + if ( ! options[ noFilter ] ) { blockTypeInserterItems = blockTypeInserterItems.filter( ( blockType ) => canIncludeBlockTypeInInserter( diff --git a/packages/block-editor/src/store/utils.js b/packages/block-editor/src/store/utils.js index 79e15255e6cc1..aaf5061ac49ca 100644 --- a/packages/block-editor/src/store/utils.js +++ b/packages/block-editor/src/store/utils.js @@ -12,8 +12,7 @@ import { unlock } from '../lock-unlock'; import { STORE_NAME } from './constants'; import { getSectionRootClientId } from './private-selectors'; -export const withRootClientIdOptionKey = Symbol( 'withRootClientId' ); - +export const noFilter = Symbol( 'noFilter' ); const parsedPatternCache = new WeakMap(); const grammarMapCache = new WeakMap(); From e51193019b318c7905eaf58ddd8a5f2a7417d0c0 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 19 Sep 2024 15:50:52 +0100 Subject: [PATCH 2/7] Fix contextual items --- .../src/components/inserter/block-types-tab.js | 2 +- packages/block-editor/src/store/selectors.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/block-types-tab.js b/packages/block-editor/src/components/inserter/block-types-tab.js index 50a8b46b46427..844d5dd341437 100644 --- a/packages/block-editor/src/components/inserter/block-types-tab.js +++ b/packages/block-editor/src/components/inserter/block-types-tab.js @@ -186,7 +186,7 @@ export function BlockTypesTab( continue; } - if ( rootClientId && item.rootClientId === rootClientId ) { + if ( rootClientId && item.isAllowedInCurrentRoot ) { itemsForCurrentRoot.push( item ); } else { itemsRemaining.push( item ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 96b64d118d569..d89c90d7c2c95 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2065,6 +2065,17 @@ export const getInserterItems = createRegistrySelector( ( select ) => rootClientId ) ); + } else { + blockTypeInserterItems = blockTypeInserterItems.map( + ( blockType ) => ( { + ...blockType, + isAllowedInCurrentRoot: canIncludeBlockTypeInInserter( + state, + blockType, + rootClientId + ), + } ) + ); } const items = blockTypeInserterItems.reduce( From 196d951cab11b45143188846ec25672644274f39 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 20 Sep 2024 14:30:48 +0100 Subject: [PATCH 3/7] Remove useless test --- .../inserter/test/block-types-tab.native.js | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 packages/block-editor/src/components/inserter/test/block-types-tab.native.js diff --git a/packages/block-editor/src/components/inserter/test/block-types-tab.native.js b/packages/block-editor/src/components/inserter/test/block-types-tab.native.js deleted file mode 100644 index 925570130359a..0000000000000 --- a/packages/block-editor/src/components/inserter/test/block-types-tab.native.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * External dependencies - */ -import { render } from 'test/helpers'; - -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import items from './fixtures'; -import BlockTypesTab from '../block-types-tab'; - -jest.mock( '../hooks/use-clipboard-block' ); -jest.mock( '@wordpress/data/src/components/use-select' ); - -const selectMock = { - getCategories: jest.fn().mockReturnValue( [] ), - getCollections: jest.fn().mockReturnValue( [] ), - getInserterItems: jest.fn().mockReturnValue( [] ), - canInsertBlockType: jest.fn(), - getBlockType: jest.fn(), - getClipboard: jest.fn(), - getSettings: jest.fn( () => ( { impressions: {} } ) ), -}; - -describe( 'BlockTypesTab component', () => { - beforeEach( () => { - useSelect.mockImplementation( ( callback ) => - callback( () => selectMock ) - ); - } ); - - it( 'renders without crashing', () => { - const component = render( - - ); - expect( component ).toBeTruthy(); - } ); - - it( 'shows block items', () => { - selectMock.getInserterItems.mockReturnValue( items ); - - const blockItems = items.filter( - ( { id, category } ) => - category !== 'reusable' && id !== 'core-embed/a-paragraph-embed' - ); - const component = render( - - ); - - blockItems.forEach( ( item ) => { - expect( component.getByText( item.title ) ).toBeTruthy(); - } ); - } ); -} ); From 61c87579ac725dd40dc9ed5b26c40a7668ffca9c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 23 Sep 2024 09:17:12 +0100 Subject: [PATCH 4/7] Invert check for clarity --- .../components/inserter/hooks/use-block-types-state.js | 4 ++-- packages/block-editor/src/store/selectors.js | 8 +++++--- packages/block-editor/src/store/utils.js | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js index 955f2fb97d3ae..ba0c7e4ded564 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js @@ -14,7 +14,7 @@ import { useCallback, useMemo } from '@wordpress/element'; * Internal dependencies */ import { store as blockEditorStore } from '../../../store'; -import { noFilter } from '../../../store/utils'; +import { isFiltered } from '../../../store/utils'; import { unlock } from '../../../lock-unlock'; /** @@ -27,7 +27,7 @@ import { unlock } from '../../../lock-unlock'; */ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { const options = useMemo( - () => ( { [ noFilter ]: ! isQuick } ), + () => ( { [ isFiltered ]: isQuick } ), [ isQuick ] ); const [ items ] = useSelect( diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d89c90d7c2c95..da0ac9dbb271c 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -21,7 +21,7 @@ import { createSelector, createRegistrySelector } from '@wordpress/data'; * Internal dependencies */ import { - noFilter, + isFiltered, checkAllowListRecursive, checkAllowList, getAllPatternsDependants, @@ -80,7 +80,9 @@ const EMPTY_ARRAY = []; */ const EMPTY_SET = new Set(); -const EMPTY_OBJECT = {}; +const EMPTY_OBJECT = { + [ isFiltered ]: true, +}; /** * Returns a block's name given its client ID, or null if no block exists with @@ -2056,7 +2058,7 @@ export const getInserterItems = createRegistrySelector( ( select ) => ) .map( buildBlockTypeInserterItem ); - if ( ! options[ noFilter ] ) { + if ( options[ isFiltered ] === false ) { blockTypeInserterItems = blockTypeInserterItems.filter( ( blockType ) => canIncludeBlockTypeInInserter( diff --git a/packages/block-editor/src/store/utils.js b/packages/block-editor/src/store/utils.js index aaf5061ac49ca..9b83a8f74cf9a 100644 --- a/packages/block-editor/src/store/utils.js +++ b/packages/block-editor/src/store/utils.js @@ -12,7 +12,7 @@ import { unlock } from '../lock-unlock'; import { STORE_NAME } from './constants'; import { getSectionRootClientId } from './private-selectors'; -export const noFilter = Symbol( 'noFilter' ); +export const isFiltered = Symbol( 'isFiltered' ); const parsedPatternCache = new WeakMap(); const grammarMapCache = new WeakMap(); From 0d2481b3871e267060c105da472e2961ec92fb51 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 23 Sep 2024 09:18:49 +0100 Subject: [PATCH 5/7] Better JSDocs --- packages/block-editor/src/store/private-selectors.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index 6b4ea779942fe..02a37b94ec27f 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -639,11 +639,14 @@ export function isZoomOut( state ) { return getZoomLevel( state ) < 100; } -/* +/** + * Finds the closest block where the block is allowed to be inserted. * * @param {Object} state Editor state. * @param {string} name Block name. * @param {string} clientId Default insertion point. + * + * @return {string} clientID of the closest container when the block name can be inserted. */ export function getClosestAllowedInsertionPoint( state, name, clientId = '' ) { // If we're trying to insert at the root level and it's not allowed From 55e7adf55cc53e2c2a67e82e61bd88521da928b8 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 23 Sep 2024 09:26:55 +0100 Subject: [PATCH 6/7] Small fix --- .../src/components/inserter/hooks/use-block-types-state.js | 2 +- packages/block-editor/src/store/selectors.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js index ba0c7e4ded564..4bed58b06e0f8 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js @@ -27,7 +27,7 @@ import { unlock } from '../../../lock-unlock'; */ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { const options = useMemo( - () => ( { [ isFiltered ]: isQuick } ), + () => ( { [ isFiltered ]: !! isQuick } ), [ isQuick ] ); const [ items ] = useSelect( diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index da0ac9dbb271c..3163bb5257a9a 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -80,7 +80,7 @@ const EMPTY_ARRAY = []; */ const EMPTY_SET = new Set(); -const EMPTY_OBJECT = { +const DEFAULT_INSERTER_OPTIONS = { [ isFiltered ]: true, }; @@ -2010,7 +2010,7 @@ const buildBlockTypeItem = */ export const getInserterItems = createRegistrySelector( ( select ) => createSelector( - ( state, rootClientId = null, options = EMPTY_OBJECT ) => { + ( state, rootClientId = null, options = DEFAULT_INSERTER_OPTIONS ) => { const buildReusableBlockInserterItem = ( reusableBlock ) => { const icon = ! reusableBlock.wp_pattern_sync_status ? { @@ -2058,7 +2058,7 @@ export const getInserterItems = createRegistrySelector( ( select ) => ) .map( buildBlockTypeInserterItem ); - if ( options[ isFiltered ] === false ) { + if ( options[ isFiltered ] !== false ) { blockTypeInserterItems = blockTypeInserterItems.filter( ( blockType ) => canIncludeBlockTypeInInserter( From a386831bc004c5ce296d4abcfef8aeaef82e0f13 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 23 Sep 2024 15:12:20 +0100 Subject: [PATCH 7/7] Trigger snackbar if you can't insert a block --- .../inserter/hooks/use-block-types-state.js | 54 ++++++++++++------- .../inserter/hooks/use-patterns-state.js | 2 +- .../inserter/media-tab/media-preview.js | 8 ++- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js index 4bed58b06e0f8..6f11060c75c49 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-block-types-state.js @@ -2,13 +2,16 @@ * WordPress dependencies */ import { + getBlockType, createBlock, createBlocksFromInnerBlocksTemplate, store as blocksStore, parse, } from '@wordpress/blocks'; -import { useSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { useCallback, useMemo } from '@wordpress/element'; +import { store as noticesStore } from '@wordpress/notices'; +import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies @@ -42,6 +45,7 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { const { getClosestAllowedInsertionPoint } = unlock( useSelect( blockEditorStore ) ); + const { createErrorNotice } = useDispatch( noticesStore ); const [ categories, collections ] = useSelect( ( select ) => { const { getCategories, getCollections } = select( blocksStore ); @@ -57,26 +61,38 @@ const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => { name, rootClientId ); - if ( destinationClientId !== null ) { - const insertedBlock = - syncStatus === 'unsynced' - ? parse( content, { - __unstableSkipMigrationLogs: true, - } ) - : createBlock( - name, - initialAttributes, - createBlocksFromInnerBlocksTemplate( - innerBlocks - ) - ); - onInsert( - insertedBlock, - undefined, - shouldFocusBlock, - destinationClientId + if ( destinationClientId === null ) { + const title = getBlockType( name )?.title ?? name; + createErrorNotice( + sprintf( + /* translators: %s: block pattern title. */ + __( 'Block "%s" can\'t be inserted.' ), + title + ), + { + type: 'snackbar', + id: 'inserter-notice', + } ); + return; } + + const insertedBlock = + syncStatus === 'unsynced' + ? parse( content, { + __unstableSkipMigrationLogs: true, + } ) + : createBlock( + name, + initialAttributes, + createBlocksFromInnerBlocksTemplate( innerBlocks ) + ); + onInsert( + insertedBlock, + undefined, + shouldFocusBlock, + destinationClientId + ); }, [ onInsert, getClosestAllowedInsertionPoint, rootClientId ] ); diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index 6483dc58ae8b9..f8b083d4eedf1 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -87,7 +87,7 @@ const usePatternsState = ( onInsert, rootClientId, selectedCategory ) => { ), { type: 'snackbar', - id: 'block-pattern-inserted-notice', + id: 'inserter-notice', } ); }, diff --git a/packages/block-editor/src/components/inserter/media-tab/media-preview.js b/packages/block-editor/src/components/inserter/media-tab/media-preview.js index 64088f45fa1c3..a890e5fe8dc13 100644 --- a/packages/block-editor/src/components/inserter/media-tab/media-preview.js +++ b/packages/block-editor/src/components/inserter/media-tab/media-preview.js @@ -184,13 +184,16 @@ export function MediaPreview( { media, onClick, category } ) { } ); createSuccessNotice( __( 'Image uploaded and inserted.' ), - { type: 'snackbar' } + { type: 'snackbar', id: 'inserter-notice' } ); setIsInserting( false ); }, allowedTypes: ALLOWED_MEDIA_TYPES, onError( message ) { - createErrorNotice( message, { type: 'snackbar' } ); + createErrorNotice( message, { + type: 'snackbar', + id: 'inserter-notice', + } ); setIsInserting( false ); }, } ); @@ -281,6 +284,7 @@ export function MediaPreview( { media, onClick, category } ) { onClick( cloneBlock( block ) ); createSuccessNotice( __( 'Image inserted.' ), { type: 'snackbar', + id: 'inserter-notice', } ); setShowExternalUploadModal( false ); } }