Skip to content

Conversation

@tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Apr 17, 2020

Description

Closes #21590 and #21593

Added ability to render submenus as nested, and save nested items, in the experimental navigation page.

TODO: Render new nested items in the correct order (currently they're appended to the end of the list).

How has this been tested?

Tested in browser.

Screenshots

Screen Shot 2020-04-17 at 5 27 03 pm

We might need some styling fixes for this 🙀 :

Screen Shot 2020-04-17 at 5 27 26 pm

Types of changes

New feature (non-breaking change which adds functionality)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@tellthemachines tellthemachines added the [Block] Navigation Affects the Navigation Block label Apr 17, 2020
@tellthemachines tellthemachines self-assigned this Apr 17, 2020
@github-actions
Copy link

github-actions bot commented Apr 17, 2020

Size Change: -12.2 kB (1%)

Total Size: 828 kB

Filename Size Change
build/a11y/index.js 1.02 kB +1 B
build/annotations/index.js 3.62 kB +4 B (0%)
build/api-fetch/index.js 4.08 kB +73 B (1%)
build/autop/index.js 2.82 kB -1 B
build/block-directory/index.js 6.59 kB +356 B (5%) 🔍
build/block-directory/style-rtl.css 764 B +4 B (0%)
build/block-directory/style.css 764 B +4 B (0%)
build/block-editor/index.js 104 kB -1.1 kB (1%)
build/block-editor/style-rtl.css 10.6 kB +389 B (3%)
build/block-editor/style.css 10.6 kB +385 B (3%)
build/block-library/editor-rtl.css 7.12 kB +28 B (0%)
build/block-library/editor.css 7.12 kB +31 B (0%)
build/block-library/index.js 115 kB +3.4 kB (2%)
build/block-library/style-rtl.css 7.38 kB +216 B (2%)
build/block-library/style.css 7.38 kB +212 B (2%)
build/block-serialization-default-parser/index.js 1.88 kB +3 B (0%)
build/blocks/index.js 48.1 kB -9.58 kB (19%) 👏
build/components/index.js 181 kB -17.5 kB (9%)
build/components/style-rtl.css 17 kB +228 B (1%)
build/components/style.css 16.9 kB +230 B (1%)
build/compose/index.js 6.66 kB +3 B (0%)
build/core-data/index.js 11.4 kB +295 B (2%)
build/data-controls/index.js 1.29 kB +43 B (3%)
build/data/index.js 8.42 kB -4 B (0%)
build/date/index.js 5.47 kB +1 B
build/dom-ready/index.js 568 B -1 B
build/edit-navigation/index.js 5.59 kB +2.05 kB (36%) 🚨
build/edit-navigation/style-rtl.css 618 B +133 B (21%) 🚨
build/edit-navigation/style.css 617 B +132 B (21%) 🚨
build/edit-post/index.js 28 kB +301 B (1%)
build/edit-post/style-rtl.css 12.2 kB -87 B (0%)
build/edit-post/style.css 12.2 kB -83 B (0%)
build/edit-site/index.js 12.1 kB +1.69 kB (13%) ⚠️
build/edit-site/style-rtl.css 5.22 kB +195 B (3%)
build/edit-site/style.css 5.22 kB +197 B (3%)
build/edit-widgets/index.js 8.37 kB +903 B (10%) ⚠️
build/edit-widgets/style-rtl.css 4.69 kB +47 B (1%)
build/edit-widgets/style.css 4.69 kB +47 B (1%)
build/editor/editor-styles-rtl.css 425 B -3 B (0%)
build/editor/editor-styles.css 428 B -3 B (0%)
build/editor/index.js 44.3 kB +1.02 kB (2%)
build/editor/style-rtl.css 5.07 kB +1.6 kB (31%) 🚨
build/editor/style.css 5.08 kB +1.6 kB (31%) 🚨
build/element/index.js 4.65 kB +3 B (0%)
build/escape-html/index.js 734 B +1 B
build/format-library/index.js 7.63 kB +316 B (4%)
build/hooks/index.js 2.13 kB +1 B
build/keyboard-shortcuts/index.js 2.51 kB -3 B (0%)
build/keycodes/index.js 1.94 kB +31 B (1%)
build/list-reusable-blocks/index.js 3.13 kB +4 B (0%)
build/media-utils/index.js 5.29 kB +13 B (0%)
build/notices/index.js 1.79 kB +2 B (0%)
build/nux/index.js 3.4 kB -1 B
build/plugins/index.js 2.56 kB -115 B (4%)
build/primitives/index.js 1.5 kB +8 B (0%)
build/priority-queue/index.js 789 B +1 B
build/redux-routine/index.js 2.85 kB +7 B (0%)
build/rich-text/index.js 14.8 kB +7 B (0%)
build/server-side-render/index.js 2.68 kB +5 B (0%)
build/url/index.js 4.02 kB -1 B
build/viewport/index.js 1.84 kB -2 B (0%)
build/wordcount/index.js 1.17 kB +1 B
ℹ️ View Unchanged
Filename Size Change
build/blob/index.js 620 B 0 B
build/block-library/theme-rtl.css 683 B 0 B
build/block-library/theme.css 685 B 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom/index.js 3.1 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.56 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.28 kB 0 B
build/warning/index.js 1.14 kB 0 B

compressed-size-action

@tellthemachines tellthemachines linked an issue Apr 24, 2020 that may be closed by this pull request
Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

This looks good, but It'd be great to see some helpful comments as the code is significantly more complicated now.

I also think considering how it can be unit tested soon would be good given the complexity.

}

menuItemsRef.current = {};
const itemIndex = {};
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at what this does, it seems like it builds an index of items by their parent, I feel like a name like itemsByParent might document this better.

return innerBlocks;
};

const innerBlocks = createMenuItemBlocks( itemIndex[ 0 ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not clear to me why only the item with id 0 is passed in. Would be good to see some comments here.

Copy link
Member

Choose a reason for hiding this comment

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

If it were itemsByParentID[ 0 ] then I think it'd be clear enough what's going on.

return innerBlocks;
};

const innerBlocks = createMenuItemBlocks( itemIndex[ 0 ] );
Copy link
Member

Choose a reason for hiding this comment

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

If it were itemsByParentID[ 0 ] then I think it'd be clear enough what's going on.

const innerBlocks = [];
for ( const item of items ) {
let menuItemInnerBlocks = [];
if ( itemIndex[ item.id ] && itemIndex[ item.id ].length > 0 ) {
Copy link
Member

Choose a reason for hiding this comment

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

Could use ?. to shorten this. (I'm maybe a little obsessed with using this now that we can...)

if ( itemIndex[ item.id ]?.length ) {

menuItemsRef.current[ block.clientId ] = menuItem;
innerBlocks.push( block );
}
const createMenuItemBlocks = ( items ) => {
Copy link
Member

Choose a reason for hiding this comment

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

We're going to want to unit test as much of this logic as possible. It's probably easiest to do that if we move the logic that turns a flat map of menu items into a tree of blocks out of the React hook and into a pure function that is name-exported.

function createBlocksFromMenuItems( menuItems ) {
	...
}
...
const { blocks, menuItemsByClientId } = createBlocksFromMenuItems( menuItems );
menuItemsRef.current = menuItemsByClientId;
setBlocks( [ createBlock( 'core/navigation', {}, blocks ) ] );

This is kind of what I had in mind when I wrote createBlockFromMenuItem, but I didn't really think it through properly.

Happy to defer this for when we do #21285.

saveMenuItem( {
...menuItem,
...createMenuItemAttributesFromBlock( block ),
menus: menuId, // Gotta do this because REST API doesn't like receiving an array here. Maybe a bug in the REST API?
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to set parent here? What happens if a Navigation Link is moved from one submenu to another?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question; it doesn't appear to be possible to move items between nesting levels at the moment. Also, I just realised that nav items can be dragged by the handle from the top toolbar and the experience is... not delightful 🙀

Copy link
Contributor

Choose a reason for hiding this comment

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

We should still send parent even if our UI is missing proper nesting, I think!

@tellthemachines
Copy link
Contributor Author

I've addressed all the feedback so ready for another round of review!

Regarding saving the menu order, it doesn't seem to be too straightforward so it's probably better to do it in a follow up PR.

@adamziel
Copy link
Contributor

adamziel commented May 5, 2020

Just surfacing the discussion about saving menu items in a transactional way here:

#21964 (comment)

#22148

adamziel added a commit that referenced this pull request May 7, 2020
adamziel added a commit that referenced this pull request May 11, 2020
// Disable reason, this code will eventually be implemented.
// eslint-disable-next-line no-unused-vars
for ( const clientId of deletedClientIds ) {
for ( const deletedClientId of deletedClientIds ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

👋 let's revert this line as it will conflict with the PR that implements this ( or tries to :) )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I do that, it fails the lint check because clientId is already declared in the upper scope. The deletion work will require some reworking to integrate with this PR anyway - which is what I attempted in #22128 😅

...createMenuItemAttributesFromBlock( block ),
menus: menuId,
parent: parentId,
} ).then( ( result ) => result );
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this then for?

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 added that when I was trying to save reordering, where I needed to know the parent's position in the menu so I could order its children. That turned out to not be possible with the current API endpoints, and I forgot to remove this code.

saveMenuItem( {
...menuItem,
...createMenuItemAttributesFromBlock( block ),
menus: menuId, // Gotta do this because REST API doesn't like receiving an array here. Maybe a bug in the REST API?
Copy link
Contributor

Choose a reason for hiding this comment

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

We should still send parent even if our UI is missing proper nesting, I think!

adamziel added a commit that referenced this pull request May 12, 2020
@noisysocks
Copy link
Member

There are some PHP lint errors which is what is causing Travis CI to fail.

npm run lint-php

Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

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

Works great! Nice work. Just fix up those PHP lint errors and we're good to go 👍 :shipit:

if ( 0 === (int) $prepared_nav_item['menu-item-position'] ) {
if ( $menu_items ) {
$last_item = array_pop( $menu_items );
$last_item = $menu_items[count( $menu_items ) - 1];
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to update or add a test to phpunit/class-rest-nav-menu-items-controller-test.php to test this change?

@tellthemachines tellthemachines merged commit c3c566f into master May 13, 2020
@github-actions github-actions bot added this to the Gutenberg 8.2 milestone May 13, 2020
@ellatrix ellatrix mentioned this pull request Jun 16, 2020
12 tasks
@aristath aristath deleted the add/saving-submenus branch November 10, 2020 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Block] Navigation Affects the Navigation Block

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Labels don't show in nav-menus.php page Saving submenus in the Navigation screen

6 participants