From 30afe974a3b63a90d2bfe4f2c6c851b11280a389 Mon Sep 17 00:00:00 2001 From: Jorge Date: Mon, 13 Feb 2023 21:07:43 +0000 Subject: [PATCH] Second approach using a single block editor. --- .../components/navigation-inspector/index.js | 177 ++++-------------- .../navigation-inspector/navigation-menu.js | 76 ++------ 2 files changed, 53 insertions(+), 200 deletions(-) diff --git a/packages/edit-site/src/components/navigation-inspector/index.js b/packages/edit-site/src/components/navigation-inspector/index.js index e25cb30d7b180..e6d25ba25c6ef 100644 --- a/packages/edit-site/src/components/navigation-inspector/index.js +++ b/packages/edit-site/src/components/navigation-inspector/index.js @@ -2,12 +2,9 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useState, useEffect } from '@wordpress/element'; -import { store as coreStore, useEntityBlockEditor } from '@wordpress/core-data'; -import { - store as blockEditorStore, - BlockEditorProvider, -} from '@wordpress/block-editor'; +import { useEffect } from '@wordpress/element'; +import { store as coreStore } from '@wordpress/core-data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; import { speak } from '@wordpress/a11y'; import { __ } from '@wordpress/i18n'; @@ -16,129 +13,38 @@ import { __ } from '@wordpress/i18n'; */ import NavigationMenu from './navigation-menu'; -const NAVIGATION_MENUS_QUERY = [ { per_page: -1, status: 'publish' } ]; - export default function NavigationInspector( { onSelect } ) { - const { - selectedNavigationBlockId, - clientIdToRef, - navigationMenus, - isResolvingNavigationMenus, - hasResolvedNavigationMenus, - firstNavigationBlockId, - } = useSelect( ( select ) => { - const { - __experimentalGetActiveBlockIdByBlockNames, - __experimentalGetGlobalBlocksByName, - getBlock, - } = select( blockEditorStore ); - - const { getEntityRecords, hasFinishedResolution, isResolving } = - select( coreStore ); - - const navigationMenusQuery = [ - 'postType', - 'wp_navigation', - NAVIGATION_MENUS_QUERY[ 0 ], - ]; - - // Get the active Navigation block (if present). - const selectedNavId = - __experimentalGetActiveBlockIdByBlockNames( 'core/navigation' ); - - // Get all Navigation blocks currently within the editor canvas. - const navBlockIds = - __experimentalGetGlobalBlocksByName( 'core/navigation' ); - const idToRef = {}; - navBlockIds.forEach( ( id ) => { - idToRef[ id ] = getBlock( id )?.attributes?.ref; - } ); - return { - selectedNavigationBlockId: selectedNavId, - firstNavigationBlockId: navBlockIds?.[ 0 ], - clientIdToRef: idToRef, - navigationMenus: getEntityRecords( ...navigationMenusQuery ), - isResolvingNavigationMenus: isResolving( - 'getEntityRecords', - navigationMenusQuery - ), - hasResolvedNavigationMenus: hasFinishedResolution( - 'getEntityRecords', - navigationMenusQuery - ), - }; - }, [] ); - - const firstNavRefInTemplate = clientIdToRef[ firstNavigationBlockId ]; - const firstNavigationMenuRef = navigationMenus?.[ 0 ]?.id; - - // Default Navigation Menu is either: - // - the Navigation Menu referenced by the first Nav block within the template. - // - the first of the available Navigation Menus (`wp_navigation`) posts. - const defaultNavigationMenuId = - firstNavRefInTemplate || firstNavigationMenuRef; - - // The Navigation Menu manually selected by the user within the Nav inspector. - const [ currentMenuId, setCurrentMenuId ] = useState( - firstNavRefInTemplate - ); - - // If a Nav block is selected within the canvas then set the - // Navigation Menu referenced by it's `ref` attribute to be - // active within the Navigation sidebar. - useEffect( () => { - if ( selectedNavigationBlockId ) { - setCurrentMenuId( clientIdToRef[ selectedNavigationBlockId ] ); - } - }, [ selectedNavigationBlockId ] ); + const { navigationBlockId, isLoadingInnerBlocks, hasLoadedInnerBlocks } = + useSelect( ( select ) => { + const { + __experimentalGetActiveBlockIdByBlockNames, + __experimentalGetGlobalBlocksByName, + getBlock, + } = select( blockEditorStore ); + const { isResolving, hasFinishedResolution } = select( coreStore ); - const [ innerBlocks, onInput, onChange ] = useEntityBlockEditor( - 'postType', - 'wp_navigation', - { id: currentMenuId || defaultNavigationMenuId } - ); + const selectedNavBlockId = + __experimentalGetActiveBlockIdByBlockNames( + 'core/navigation' + ) || + __experimentalGetGlobalBlocksByName( 'core/navigation' )?.[ 0 ]; + const selectedNavigationPost = + selectedNavBlockId && + getBlock( selectedNavBlockId )?.attributes?.ref; - const { isLoadingInnerBlocks, hasLoadedInnerBlocks } = useSelect( - ( select ) => { - const { isResolving, hasFinishedResolution } = select( coreStore ); return { + navigationBlockId: selectedNavBlockId, isLoadingInnerBlocks: isResolving( 'getEntityRecord', [ 'postType', 'wp_navigation', - currentMenuId || defaultNavigationMenuId, + selectedNavigationPost, ] ), hasLoadedInnerBlocks: hasFinishedResolution( 'getEntityRecord', - [ - 'postType', - 'wp_navigation', - currentMenuId || defaultNavigationMenuId, - ] + [ 'postType', 'wp_navigation', selectedNavigationPost ] ), }; - }, - [ currentMenuId, defaultNavigationMenuId ] - ); - - const isLoading = ! ( hasResolvedNavigationMenus && hasLoadedInnerBlocks ); - - const hasNavigationMenus = !! navigationMenus?.length; - - // Entity block editor will return entities that are not currently published. - // Guard by only allowing their usage if there are published Nav Menus. - const publishedInnerBlocks = hasNavigationMenus ? innerBlocks : []; - - const hasInnerBlocks = !! publishedInnerBlocks?.length; - - useEffect( () => { - if ( isResolvingNavigationMenus ) { - speak( 'Loading Navigation sidebar menus.' ); - } - - if ( hasResolvedNavigationMenus ) { - speak( 'Navigation sidebar menus have loaded.' ); - } - }, [ isResolvingNavigationMenus, hasResolvedNavigationMenus ] ); + }, [] ); useEffect( () => { if ( isLoadingInnerBlocks ) { @@ -152,36 +58,29 @@ export default function NavigationInspector( { onSelect } ) { return (
- { hasResolvedNavigationMenus && ! hasNavigationMenus && ( -

- { __( 'There are no Navigation Menus.' ) } -

- ) } - - { ! hasResolvedNavigationMenus && ( + { hasLoadedInnerBlocks && + ! isLoadingInnerBlocks && + ! navigationBlockId && ( +

+ { __( 'There are no Navigation Menus.' ) } +

+ ) } + + { ! hasLoadedInnerBlocks && (
) } - { isLoading && ( + { isLoadingInnerBlocks && ( <>
) } - { hasInnerBlocks && ! isLoading && ( - - - - ) } - - { ! hasInnerBlocks && ! isLoading && ( -

- { __( 'Navigation Menu is empty.' ) } -

+ { navigationBlockId && hasLoadedInnerBlocks && ( + ) }
); diff --git a/packages/edit-site/src/components/navigation-inspector/navigation-menu.js b/packages/edit-site/src/components/navigation-inspector/navigation-menu.js index 56ad6b9fac762..7e2255f874ddb 100644 --- a/packages/edit-site/src/components/navigation-inspector/navigation-menu.js +++ b/packages/edit-site/src/components/navigation-inspector/navigation-menu.js @@ -4,71 +4,30 @@ import { privateApis as blockEditorPrivateApis, store as blockEditorStore, - BlockList, - BlockTools, } from '@wordpress/block-editor'; -import { useEffect } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import { unlock } from '../../private-apis'; -const ALLOWED_BLOCKS = { - 'core/navigation': [ - 'core/navigation-link', - 'core/search', - 'core/social-links', - 'core/page-list', - 'core/spacer', - 'core/home-link', - 'core/site-title', - 'core/site-logo', - 'core/navigation-submenu', - ], - 'core/social-links': [ 'core/social-link' ], - 'core/navigation-submenu': [ - 'core/navigation-link', - 'core/navigation-submenu', - ], - 'core/navigation-link': [ - 'core/navigation-link', - 'core/navigation-submenu', - ], - 'core/page-list': [ 'core/page-list-item' ], -}; - -export default function NavigationMenu( { onSelect } ) { - const { clientIdsTree, innerBlocks } = useSelect( ( select ) => { - const { __unstableGetClientIdsTree, getBlocks } = - select( blockEditorStore ); - return { - clientIdsTree: __unstableGetClientIdsTree(), - innerBlocks: getBlocks(), - }; - } ); - const { updateBlockListSettings } = useDispatch( blockEditorStore ); - - const { OffCanvasEditor, LeafMoreMenu } = unlock( blockEditorPrivateApis ); +/** + * Experimental dependencies + */ +const { OffCanvasEditor, LeafMoreMenu } = unlock( blockEditorPrivateApis ); - //TODO: Block settings are normally updated as a side effect of rendering InnerBlocks in BlockList - //Think through a better way of doing this, possible with adding allowed blocks to block library metadata - useEffect( () => { - updateBlockListSettings( '', { - allowedBlocks: ALLOWED_BLOCKS[ 'core/navigation' ], - } ); - innerBlocks.forEach( ( block ) => { - if ( ALLOWED_BLOCKS[ block.name ] ) { - updateBlockListSettings( block.clientId, { - allowedBlocks: ALLOWED_BLOCKS[ block.name ], - } ); - } - } ); - }, [ updateBlockListSettings, innerBlocks ] ); +export default function NavigationMenu( { onSelect, navigationBlockId } ) { + const { clientIdsTree } = useSelect( + ( select ) => { + const { __unstableGetClientIdsTree } = select( blockEditorStore ); + return { + clientIdsTree: __unstableGetClientIdsTree( navigationBlockId ), + }; + }, + [ navigationBlockId ] + ); - // The hidden block is needed because it makes block edit side effects trigger. - // For example a navigation page list load its items has an effect on edit to load its items. return ( <> -
- - - -
); }