diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js index 9df2e22b111d3..5c89c9f72a23b 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js @@ -20,7 +20,6 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import { SidebarNavigationItemGlobalStyles } from '../sidebar-navigation-screen-global-styles'; import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; -import SidebarNavigationScreenNavigationMenuButton from '../sidebar-navigation-screen-navigation-menus/navigator-button'; export default function SidebarNavigationScreenMain() { const { location } = useNavigator(); @@ -44,14 +43,14 @@ export default function SidebarNavigationScreenMain() { ) } content={ - { __( 'Navigation' ) } - - + { const { isSavingEntityRecord, @@ -60,120 +49,19 @@ export default function SidebarNavigationScreenNavigationMenu() { getEditedEntityRecord: getEditedEntityRecordSelector, }; }, - [ postId, postType ] + [ postId ] ); const isLoading = isResolving || isSaving || isDeleting; const menuTitle = navigationMenu?.title?.rendered || navigationMenu?.slug; - const handleSave = async ( edits = {} ) => { - // Prepare for revert in case of error. - const originalRecord = getEditedEntityRecord( - 'postType', - 'wp_navigation', - postId - ); - - // Apply the edits. - editEntityRecord( 'postType', postType, postId, edits ); + const { handleSave, handleDelete, handleDuplicate } = + useNavigationMenuHandlers(); - // Attempt to persist. - try { - await saveEditedEntityRecord( 'postType', postType, postId, { - throwOnError: true, - } ); - createSuccessNotice( __( 'Renamed Navigation menu' ), { - type: 'snackbar', - } ); - } catch ( error ) { - // Revert to original in case of error. - editEntityRecord( 'postType', postType, postId, originalRecord ); - - createErrorNotice( - sprintf( - /* translators: %s: error message describing why the navigation menu could not be renamed. */ - __( `Unable to rename Navigation menu (%s).` ), - error?.message - ), - - { - type: 'snackbar', - } - ); - } - }; - - const handleDelete = async () => { - try { - await deleteEntityRecord( - 'postType', - postType, - postId, - { - force: true, - }, - { - throwOnError: true, - } - ); - createSuccessNotice( __( 'Deleted Navigation menu' ), { - type: 'snackbar', - } ); - goTo( '/navigation' ); - } catch ( error ) { - createErrorNotice( - sprintf( - /* translators: %s: error message describing why the navigation menu could not be deleted. */ - __( `Unable to delete Navigation menu (%s).` ), - error?.message - ), - - { - type: 'snackbar', - } - ); - } - }; - const handleDuplicate = async () => { - try { - const savedRecord = await saveEntityRecord( - 'postType', - postType, - { - title: sprintf( - /* translators: %s: Navigation menu title */ - __( '%s (Copy)' ), - menuTitle - ), - content: navigationMenu?.content?.raw, - status: 'publish', - }, - { - throwOnError: true, - } - ); - - if ( savedRecord ) { - createSuccessNotice( __( 'Duplicated Navigation menu' ), { - type: 'snackbar', - } ); - goTo( `/navigation/${ postType }/${ savedRecord.id }` ); - } - } catch ( error ) { - createErrorNotice( - sprintf( - /* translators: %s: error message describing why the navigation menu could not be deleted. */ - __( `Unable to duplicate Navigation menu (%s).` ), - error?.message - ), - - { - type: 'snackbar', - } - ); - } - }; + const _handleDelete = () => handleDelete( navigationMenu ); + const _handleSave = () => handleSave( navigationMenu ); + const _handleDuplicate = () => handleDuplicate( navigationMenu ); if ( isLoading ) { return ( @@ -201,9 +89,9 @@ export default function SidebarNavigationScreenNavigationMenu() { actions={ } title={ decodeEntities( menuTitle ) } @@ -213,37 +101,11 @@ export default function SidebarNavigationScreenNavigationMenu() { } return ( - - - - - } - title={ decodeEntities( menuTitle ) } - description={ - <> -

- { sprintf( - /* translators: %s: Navigation menu title */ - 'This is your "%s" navigation menu. ', - decodeEntities( menuTitle ) - ) } -

-

- { __( - 'You can edit this menu here, but be aware that visual styles might be applied separately in templates or template parts, so the preview shown here can be incomplete.' - ) } -

- - } - > - -
+ ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/single-navigation-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/single-navigation-menu.js new file mode 100644 index 0000000000000..6351c83323f98 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/single-navigation-menu.js @@ -0,0 +1,39 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { decodeEntities } from '@wordpress/html-entities'; +/** + * Internal dependencies + */ +import { SidebarNavigationScreenWrapper } from '../sidebar-navigation-screen-navigation-menus'; +import ScreenNavigationMoreMenu from './more-menu'; +import NavigationMenuEditor from './navigation-menu-editor'; + +export default function SingleNavigationMenu( { + navigationMenu, + handleDelete, + handleDuplicate, + handleSave, +} ) { + const menuTitle = navigationMenu?.title?.rendered; + + return ( + + } + title={ decodeEntities( menuTitle ) } + description={ __( + 'Navigation menus are a curated collection of blocks that allow visitors to get around your site.' + ) } + > + + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js new file mode 100644 index 0000000000000..1ddf1c8d86c6e --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js @@ -0,0 +1,175 @@ +/** + * WordPress dependencies + */ +import { store as coreStore } from '@wordpress/core-data'; +import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; +import { __, sprintf } from '@wordpress/i18n'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { store as noticesStore } from '@wordpress/notices'; +/** + * Internal dependencies + */ +import { postType } from '.'; + +function useDeleteNavigationMenu() { + const { goTo } = useNavigator(); + + const { deleteEntityRecord } = useDispatch( coreStore ); + + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + const handleDelete = async ( navigationMenu ) => { + const postId = navigationMenu?.id; + try { + await deleteEntityRecord( + 'postType', + postType, + postId, + { + force: true, + }, + { + throwOnError: true, + } + ); + createSuccessNotice( __( 'Deleted Navigation menu' ), { + type: 'snackbar', + } ); + goTo( '/navigation' ); + } catch ( error ) { + createErrorNotice( + sprintf( + /* translators: %s: error message describing why the navigation menu could not be deleted. */ + __( `Unable to delete Navigation menu (%s).` ), + error?.message + ), + + { + type: 'snackbar', + } + ); + } + }; + + return handleDelete; +} + +function useSaveNavigationMenu() { + const { getEditedEntityRecord } = useSelect( ( select ) => { + const { getEditedEntityRecord: getEditedEntityRecordSelector } = + select( coreStore ); + + return { + getEditedEntityRecord: getEditedEntityRecordSelector, + }; + }, [] ); + + const { editEntityRecord, saveEditedEntityRecord } = + useDispatch( coreStore ); + + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + const handleSave = async ( navigationMenu, edits = {} ) => { + const postId = navigationMenu?.id; + // Prepare for revert in case of error. + const originalRecord = getEditedEntityRecord( + 'postType', + 'wp_navigation', + postId + ); + + // Apply the edits. + editEntityRecord( 'postType', postType, postId, edits ); + + // Attempt to persist. + try { + await saveEditedEntityRecord( 'postType', postType, postId, { + throwOnError: true, + } ); + createSuccessNotice( __( 'Renamed Navigation menu' ), { + type: 'snackbar', + } ); + } catch ( error ) { + // Revert to original in case of error. + editEntityRecord( 'postType', postType, postId, originalRecord ); + + createErrorNotice( + sprintf( + /* translators: %s: error message describing why the navigation menu could not be renamed. */ + __( `Unable to rename Navigation menu (%s).` ), + error?.message + ), + + { + type: 'snackbar', + } + ); + } + }; + + return handleSave; +} + +function useDuplicateNavigationMenu() { + const { goTo } = useNavigator(); + + const { saveEntityRecord } = useDispatch( coreStore ); + + const { createSuccessNotice, createErrorNotice } = + useDispatch( noticesStore ); + + const handleDuplicate = async ( navigationMenu ) => { + const menuTitle = + navigationMenu?.title?.rendered || navigationMenu?.slug; + + try { + const savedRecord = await saveEntityRecord( + 'postType', + postType, + { + title: sprintf( + /* translators: %s: Navigation menu title */ + __( '%s (Copy)' ), + menuTitle + ), + content: navigationMenu?.content?.raw, + status: 'publish', + }, + { + throwOnError: true, + } + ); + + if ( savedRecord ) { + createSuccessNotice( __( 'Duplicated Navigation menu' ), { + type: 'snackbar', + } ); + goTo( `/navigation/${ postType }/${ savedRecord.id }` ); + } + } catch ( error ) { + createErrorNotice( + sprintf( + /* translators: %s: error message describing why the navigation menu could not be deleted. */ + __( `Unable to duplicate Navigation menu (%s).` ), + error?.message + ), + + { + type: 'snackbar', + } + ); + } + }; + + return handleDuplicate; +} + +export default function useNavigationMenuHandlers() { + return { + handleDelete: useDeleteNavigationMenu(), + handleSave: useSaveNavigationMenu(), + handleDuplicate: useDuplicateNavigationMenu(), + }; +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js index 5706ff17bc038..b3fae528aaed2 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/index.js @@ -18,6 +18,8 @@ import SidebarNavigationScreen from '../sidebar-navigation-screen'; import SidebarNavigationItem from '../sidebar-navigation-item'; import { PRELOADED_NAVIGATION_MENUS_QUERY } from './constants'; import { useLink } from '../routes/link'; +import SingleNavigationMenu from '../sidebar-navigation-screen-navigation-menu/single-navigation-menu'; +import useNavigationMenuHandlers from '../sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers'; export default function SidebarNavigationScreenNavigationMenus() { const { records: navigationMenus, isResolving: isLoading } = @@ -27,6 +29,11 @@ export default function SidebarNavigationScreenNavigationMenus() { PRELOADED_NAVIGATION_MENUS_QUERY ); + const firstNavigationMenu = navigationMenus?.[ 0 ]; + + const { handleSave, handleDelete, handleDuplicate } = + useNavigationMenuHandlers(); + const hasNavigationMenus = !! navigationMenus?.length; if ( isLoading ) { @@ -45,6 +52,18 @@ export default function SidebarNavigationScreenNavigationMenus() { ); } + // if single menu then render it + if ( navigationMenus?.length === 1 ) { + return ( + handleDelete( firstNavigationMenu ) } + handleDuplicate={ () => handleDuplicate( firstNavigationMenu ) } + handleSave={ () => handleSave( firstNavigationMenu ) } + /> + ); + } + return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/navigator-button.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/navigator-button.js deleted file mode 100644 index 7e75c544a0f16..0000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/navigator-button.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * WordPress dependencies - */ - -import { __experimentalNavigatorButton as NavigatorButton } from '@wordpress/components'; -import { useEntityRecords } from '@wordpress/core-data'; - -/** - * Internal dependencies - */ -import { PRELOADED_NAVIGATION_MENUS_QUERY } from './constants'; - -export default function SidebarNavigationScreenNavigationMenuButton( { - children, - ...props -} ) { - const { records: navigationMenus, isResolving: isLoading } = - useEntityRecords( - 'postType', - `wp_navigation`, - PRELOADED_NAVIGATION_MENUS_QUERY - ); - - const hasNavigationMenus = !! navigationMenus?.length; - const hasSingleNavigationMenu = navigationMenus?.length === 1; - const firstNavigationMenu = navigationMenus?.[ 0 ]; - - const showNavigationScreen = process.env.IS_GUTENBERG_PLUGIN - ? hasNavigationMenus - : false; - - // If there is a single menu then we can go directly to that menu. - // Otherwise we go to the navigation listing screen. - const path = hasSingleNavigationMenu - ? `/navigation/wp_navigation/${ firstNavigationMenu?.id }` - : '/navigation'; - - if ( ! showNavigationScreen ) { - return null; - } - - return ( - - { children } - - ); -}