* Update menu ID when favoriting an item

* Allow favorites to be included alongside the primary menu items

* Add categories to favorites menu server-side

* Don't reset menu state when active item is the same

* Make sure favorites are finished resolving before showing
This commit is contained in:
Joshua T Flowers 2021-02-16 11:12:25 -05:00 committed by GitHub
parent 8629318f46
commit 452494a4fe
5 changed files with 81 additions and 32 deletions

View File

@ -15,9 +15,12 @@ import './style.scss';
export const CategoryTitle = ( { category } ) => {
const { id, title } = category;
const { favorites } = useSelect( ( select ) => {
const { favorites, isResolving } = useSelect( ( select ) => {
return {
favorites: select( NAVIGATION_STORE_NAME ).getFavorites(),
isResolving: select( NAVIGATION_STORE_NAME ).isResolving(
'getFavorites'
),
};
} );
@ -25,7 +28,7 @@ export const CategoryTitle = ( { category } ) => {
NAVIGATION_STORE_NAME
);
const isFavorited = favorites.includes( id );
const isFavorited = ( favorites || [] ).includes( id );
const className = 'woocommerce-navigation-category-title';
const toggleFavorite = () => {
@ -37,27 +40,29 @@ export const CategoryTitle = ( { category } ) => {
} );
};
if ( category.menuId === 'plugins' ) {
if ( [ 'plugins', 'favorites' ].includes( category.menuId ) ) {
return (
<span className={ className }>
<span className={ `${ className }__text` }>{ title }</span>
<Button
className={ `${ className }__favorite-button` }
isTertiary
onClick={ toggleFavorite }
icon={ isFavorited ? 'star-filled' : 'star-empty' }
aria-label={
isFavorited
? __(
'Add this item to your favorites.',
'woocommerce-admin'
)
: __(
'Remove this item from your favorites.',
'woocommerce-admin'
)
}
/>
{ ! isResolving && (
<Button
className={ `${ className }__favorite-button` }
isTertiary
onClick={ toggleFavorite }
icon={ isFavorited ? 'star-filled' : 'star-empty' }
aria-label={
isFavorited
? __(
'Add this item to your favorites.',
'woocommerce-admin'
)
: __(
'Remove this item from your favorites.',
'woocommerce-admin'
)
}
/>
) }
</span>
);
}

View File

@ -66,7 +66,7 @@ const Container = ( { menuItems } ) => {
useEffect( () => {
const initialMatchedItem = getMatchingItem( menuItems );
if ( initialMatchedItem ) {
if ( initialMatchedItem && activeItem !== initialMatchedItem ) {
setActiveItem( initialMatchedItem );
setActiveLevel( initialMatchedItem.parent );
}
@ -94,7 +94,9 @@ const Container = ( { menuItems } ) => {
if (
item.parent !== 'woocommerce' &&
categoriesMap[ item.parent ] &&
categoriesMap[ item.parent ].menuId !== item.menuId
categoriesMap[ item.parent ].menuId !== item.menuId &&
// Allow favorites to exist under any menu.
categoriesMap[ item.parent ].menuId !== 'favorites'
) {
return acc;
}
@ -147,11 +149,19 @@ const Container = ( { menuItems } ) => {
{ categories.map( ( category ) => {
const {
primary: primaryItems,
favorites: favoriteItems,
secondary: secondaryItems,
plugins: pluginItems,
} = categorizedItems[ category.id ] || {};
const primaryAndFavoriteItems = [
...( primaryItems || [] ),
...( favoriteItems || [] ),
];
return [
( !! primaryItems || !! pluginItems ) && (
( !! primaryAndFavoriteItems ||
!! pluginItems ) && (
<NavigationMenu
key={ category.id }
title={
@ -178,14 +188,16 @@ const Container = ( { menuItems } ) => {
)
}
>
{ !! primaryItems && (
{ !! primaryAndFavoriteItems && (
<NavigationGroup>
{ primaryItems.map( ( item ) => (
<Item
key={ item.id }
item={ item }
/>
) ) }
{ primaryAndFavoriteItems.map(
( item ) => (
<Item
key={ item.id }
item={ item }
/>
)
) }
</NavigationGroup>
) }
{ !! pluginItems && (

View File

@ -87,6 +87,15 @@ const reducer = (
state = {
...state,
favorites: newFavorites,
menuItems: state.menuItems.map( ( item ) => {
if ( item.id === favorite ) {
return {
...item,
menuId: 'favorites',
};
}
return item;
} ),
requesting: {
...state.requesting,
addFavorite: false,
@ -120,6 +129,15 @@ const reducer = (
state = {
...state,
favorites: filteredFavorites,
menuItems: state.menuItems.map( ( item ) => {
if ( item.id === favorite ) {
return {
...item,
menuId: 'plugins',
};
}
return item;
} ),
requesting: {
...state.requesting,
removeFavorite: false,

View File

@ -97,6 +97,7 @@ describe( 'navigation reducer', () => {
it( 'should add a favorite', () => {
const state = reducer(
{
...defaultState,
favorites: [ 'favorite1', 'favorite2' ],
},
{
@ -115,6 +116,7 @@ describe( 'navigation reducer', () => {
it( 'should remove a favorite', () => {
const state = reducer(
{
...defaultState,
favorites: [ 'favorite1', 'favorite2' ],
},
{

View File

@ -7,6 +7,7 @@
namespace Automattic\WooCommerce\Admin\Features\Navigation;
use Automattic\WooCommerce\Admin\Features\Navigation\Favorites;
use Automattic\WooCommerce\Admin\Features\Navigation\Screen;
use Automattic\WooCommerce\Admin\Features\Navigation\CoreMenu;
@ -256,8 +257,16 @@ class Menu {
* @return string
*/
public static function get_item_menu_id( $item ) {
$favorites = Favorites::get_all();
if ( ! empty( $favorites ) && in_array( $item['id'], $favorites, true ) ) {
return 'favorites';
}
if ( isset( $item['parent'] ) && isset( self::$menu_items[ $item['parent'] ] ) ) {
return self::$menu_items[ $item['parent'] ]['menuId'];
$menu_id = self::$menu_items[ $item['parent'] ]['menuId'];
return 'favorites' === $menu_id
? 'plugins'
: $menu_id;
}
return $item['menuId'];
@ -288,10 +297,12 @@ class Menu {
}
$menu_id = self::get_item_menu_id( $category_args );
if ( 'plugins' !== $menu_id ) {
if ( ! in_array( $menu_id, array( 'plugins', 'favorites' ), true ) ) {
return;
}
$category_args['menuId'] = $menu_id;
self::add_category( $category_args );
}
@ -719,6 +730,7 @@ class Menu {
'primary' => 0,
'secondary' => 1,
'plugins' => 2,
'favorites' => 3,
);
$menu = array_map( function( $item ) use( $menuOrder ) { return $menuOrder[ $item['menuId'] ]; }, $menu_items );
$order = array_column( $menu_items, 'order' );