Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigation: browse mode list all Navigation Menus. #50840

Merged
merged 11 commits into from
May 23, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { __ } from '@wordpress/i18n';
import { layout, symbol, navigation, styles, page } from '@wordpress/icons';
import { useDispatch, useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';

import { useEffect } from '@wordpress/element';

/**
Expand All @@ -19,27 +19,9 @@ import SidebarNavigationItem from '../sidebar-navigation-item';
import { SidebarNavigationItemGlobalStyles } from '../sidebar-navigation-screen-global-styles';
import { unlock } from '../../private-apis';
import { store as editSiteStore } from '../../store';
import SidebarNavigationScreenNavigationMenuButton from '../sidebar-navigation-screen-navigation-menus/navigator-button';

export default function SidebarNavigationScreenMain() {
const hasNavigationMenus = useSelect( ( select ) => {
// The query needs to be the same as in the "SidebarNavigationScreenNavigationMenus" component,
// to avoid double network calls.
const navigationMenus = select( coreStore ).getEntityRecords(
'postType',
'wp_navigation',
{
per_page: 1,
status: 'publish',
order: 'desc',
orderby: 'date',
}
);
return !! navigationMenus?.length;
}, [] );
const showNavigationScreen = process.env.IS_GUTENBERG_PLUGIN
? hasNavigationMenus
: false;

const editorCanvasContainerView = useSelect( ( select ) => {
return unlock( select( editSiteStore ) ).getEditorCanvasContainerView();
}, [] );
Expand All @@ -64,16 +46,14 @@ export default function SidebarNavigationScreenMain() {
) }
content={
<ItemGroup>
{ showNavigationScreen && (
<NavigatorButton
as={ SidebarNavigationItem }
path="/navigation"
withChevron
icon={ navigation }
>
{ __( 'Navigation' ) }
</NavigatorButton>
) }
<SidebarNavigationScreenNavigationMenuButton
withChevron
icon={ navigation }
as={ SidebarNavigationItem }
>
{ __( 'Navigation' ) }
</SidebarNavigationScreenNavigationMenuButton>

<SidebarNavigationItemGlobalStyles
withChevron
icon={ styles }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* WordPress dependencies
*/
import { useEntityRecord } from '@wordpress/core-data';
import {
__experimentalUseNavigator as useNavigator,
Spinner,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useCallback, useMemo } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { BlockEditorProvider } from '@wordpress/block-editor';
import { createBlock } from '@wordpress/blocks';
import { decodeEntities } from '@wordpress/html-entities';

/**
* Internal dependencies
*/
import { unlock } from '../../private-apis';
import { store as editSiteStore } from '../../store';
import {
isPreviewingTheme,
currentlyPreviewingTheme,
} from '../../utils/is-previewing-theme';
import { SidebarNavigationScreenWrapper } from '../sidebar-navigation-screen-navigation-menus';
import NavigationMenuContent from '../sidebar-navigation-screen-navigation-menus/navigation-menu-content';

const { useHistory } = unlock( routerPrivateApis );
const noop = () => {};

export default function SidebarNavigationScreenNavigationMenu() {
const postType = `wp_navigation`;
const {
params: { postId },
} = useNavigator();

const { record: navigationMenu, isResolving: isLoading } = useEntityRecord(
'postType',
postType,
postId
);

const menuTitle = navigationMenu?.title?.rendered || navigationMenu?.slug;

if ( isLoading ) {
return (
<SidebarNavigationScreenWrapper
description={ __(
'Navigation menus are a curated collection of blocks that allow visitors to get around your site.'
) }
>
<Spinner className="edit-site-sidebar-navigation-screen-navigation-menus__loading" />
</SidebarNavigationScreenWrapper>
);
}

if ( ! isLoading && ! navigationMenu ) {
return (
<SidebarNavigationScreenWrapper
description={ __( 'Navigation Menu missing.' ) }
/>
);
}

return (
<SidebarNavigationScreenWrapper
title={ decodeEntities( menuTitle ) }
description={ __(
'Navigation menus are a curated collection of blocks that allow visitors to get around your site.'
) }
>
<NavigationMenuEditor navigationMenu={ navigationMenu } />
</SidebarNavigationScreenWrapper>
);
}

function NavigationMenuEditor( { navigationMenu } ) {
const history = useHistory();

const onSelect = useCallback(
( selectedBlock ) => {
const { attributes, name } = selectedBlock;
if (
attributes.kind === 'post-type' &&
attributes.id &&
attributes.type &&
history
) {
history.push( {
postType: attributes.type,
postId: attributes.id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using slug instead of ID? Is that possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly. In this PR though?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy for it to be a followup, but remember once people start using these permalinks we have to support them so it would be good to look into it before the next Gutenberg release.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to look at the routing again and see what we have available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, since pages already use IDs, I think it's fine for navigations to do the same

...( isPreviewingTheme() && {
theme_preview: currentlyPreviewingTheme(),
} ),
} );
}
if ( name === 'core/page-list-item' && attributes.id && history ) {
history.push( {
postType: 'page',
postId: attributes.id,
...( isPreviewingTheme() && {
theme_preview: currentlyPreviewingTheme(),
} ),
} );
}
},
[ history ]
);

const { storedSettings } = useSelect( ( select ) => {
const { getSettings } = unlock( select( editSiteStore ) );

return {
storedSettings: getSettings( false ),
};
}, [] );

const blocks = useMemo( () => {
if ( ! NavigationMenuEditor ) {
return [];
}

return [
createBlock( 'core/navigation', { ref: navigationMenu?.id } ),
];
}, [ navigationMenu ] );

if ( ! navigationMenu || ! blocks?.length ) {
return null;
}

return (
<BlockEditorProvider
settings={ storedSettings }
value={ blocks }
onChange={ noop }
onInput={ noop }
>
<div className="edit-site-sidebar-navigation-screen-navigation-menus__content">
<NavigationMenuContent
rootClientId={ blocks[ 0 ].clientId }
onSelect={ onSelect }
/>
</div>
</BlockEditorProvider>
);
}
Loading