2020-10-13 01:40:53 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { __ } from '@wordpress/i18n';
|
2020-11-12 17:10:42 +00:00
|
|
|
import { useEffect, useMemo, useState, useRef } from '@wordpress/element';
|
2021-02-08 20:41:08 +00:00
|
|
|
import classnames from 'classnames';
|
2020-10-13 01:40:53 +00:00
|
|
|
import { compose } from '@wordpress/compose';
|
|
|
|
import {
|
2021-01-07 23:57:09 +00:00
|
|
|
Navigation,
|
|
|
|
NavigationMenu,
|
|
|
|
NavigationGroup,
|
|
|
|
} from '@woocommerce/experimental';
|
2020-10-21 17:02:45 +00:00
|
|
|
import { NAVIGATION_STORE_NAME } from '@woocommerce/data';
|
2020-12-02 18:16:54 +00:00
|
|
|
import { recordEvent } from '@woocommerce/tracks';
|
2020-10-13 01:40:53 +00:00
|
|
|
import { withSelect } from '@wordpress/data';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { addHistoryListener, getMatchingItem } from '../../utils';
|
|
|
|
import Header from '../header';
|
|
|
|
import Item from '../../components/Item';
|
|
|
|
|
|
|
|
const Container = ( { menuItems } ) => {
|
|
|
|
useEffect( () => {
|
|
|
|
// Collapse the original WP Menu.
|
|
|
|
const adminMenu = document.getElementById( 'adminmenumain' );
|
|
|
|
adminMenu.classList.add( 'folded' );
|
|
|
|
}, [] );
|
|
|
|
|
2020-12-15 17:05:32 +00:00
|
|
|
const { rootBackLabel, rootBackUrl } = window.wcNavigation;
|
2020-10-13 01:40:53 +00:00
|
|
|
|
2020-12-02 14:36:35 +00:00
|
|
|
const parentCategory = {
|
2020-10-13 01:40:53 +00:00
|
|
|
capability: 'manage_woocommerce',
|
|
|
|
id: 'woocommerce',
|
|
|
|
isCategory: true,
|
|
|
|
menuId: 'primary',
|
|
|
|
migrate: true,
|
|
|
|
order: 10,
|
|
|
|
parent: '',
|
|
|
|
title: 'WooCommerce',
|
2020-12-02 14:36:35 +00:00
|
|
|
};
|
|
|
|
const categoriesMap = menuItems.reduce(
|
|
|
|
( acc, item ) => {
|
|
|
|
if ( item.isCategory ) {
|
|
|
|
return { ...acc, [ item.id ]: item };
|
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
woocommerce: parentCategory,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
const categories = Object.values( categoriesMap );
|
2020-10-13 01:40:53 +00:00
|
|
|
|
|
|
|
const [ activeItem, setActiveItem ] = useState( 'woocommerce-home' );
|
|
|
|
const [ activeLevel, setActiveLevel ] = useState( 'woocommerce' );
|
|
|
|
|
|
|
|
useEffect( () => {
|
|
|
|
const initialMatchedItem = getMatchingItem( menuItems );
|
2020-11-11 18:16:12 +00:00
|
|
|
if ( initialMatchedItem ) {
|
|
|
|
setActiveItem( initialMatchedItem );
|
|
|
|
setActiveLevel( initialMatchedItem.parent );
|
|
|
|
}
|
2020-10-13 01:40:53 +00:00
|
|
|
|
|
|
|
const removeListener = addHistoryListener( () => {
|
|
|
|
setTimeout( () => {
|
|
|
|
const matchedItem = getMatchingItem( menuItems );
|
|
|
|
if ( matchedItem ) {
|
|
|
|
setActiveItem( matchedItem );
|
|
|
|
}
|
|
|
|
}, 0 );
|
|
|
|
} );
|
|
|
|
|
|
|
|
return removeListener;
|
|
|
|
}, [ menuItems ] );
|
|
|
|
|
2020-10-21 17:01:46 +00:00
|
|
|
const getMenuItemsByCategory = ( items ) => {
|
|
|
|
return items.reduce( ( acc, item ) => {
|
2020-12-02 14:36:35 +00:00
|
|
|
// Set up the category if it doesn't yet exist.
|
2020-10-21 17:01:46 +00:00
|
|
|
if ( ! acc[ item.parent ] ) {
|
2020-12-02 14:36:35 +00:00
|
|
|
acc[ item.parent ] = {};
|
2020-11-05 14:00:04 +00:00
|
|
|
}
|
2020-12-02 14:36:35 +00:00
|
|
|
|
|
|
|
// Check if parent category is in the same menu.
|
|
|
|
if (
|
|
|
|
item.parent !== 'woocommerce' &&
|
|
|
|
categoriesMap[ item.parent ] &&
|
|
|
|
categoriesMap[ item.parent ].menuId !== item.menuId
|
|
|
|
) {
|
|
|
|
return acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the menu object if it doesn't exist in this category.
|
|
|
|
if ( ! acc[ item.parent ][ item.menuId ] ) {
|
|
|
|
acc[ item.parent ][ item.menuId ] = [];
|
2020-10-21 17:01:46 +00:00
|
|
|
}
|
2020-12-02 14:36:35 +00:00
|
|
|
|
|
|
|
acc[ item.parent ][ item.menuId ].push( item );
|
2020-10-21 17:01:46 +00:00
|
|
|
return acc;
|
|
|
|
}, {} );
|
|
|
|
};
|
|
|
|
|
|
|
|
const categorizedItems = useMemo(
|
|
|
|
() => getMenuItemsByCategory( menuItems ),
|
|
|
|
[ menuItems ]
|
|
|
|
);
|
|
|
|
|
2020-11-12 17:10:42 +00:00
|
|
|
const navDomRef = useRef( null );
|
|
|
|
|
2020-12-02 18:16:54 +00:00
|
|
|
const trackBackClick = ( id ) => {
|
|
|
|
recordEvent( 'navigation_back_click', {
|
|
|
|
category: id,
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2021-02-08 20:41:08 +00:00
|
|
|
const isRoot = activeLevel === 'woocommerce';
|
|
|
|
const isRootBackVisible = isRoot && rootBackUrl;
|
|
|
|
|
|
|
|
const classes = classnames( 'woocommerce-navigation', {
|
|
|
|
'is-root': isRoot,
|
|
|
|
} );
|
2021-01-04 17:00:42 +00:00
|
|
|
|
2020-10-13 01:40:53 +00:00
|
|
|
return (
|
2021-02-08 20:41:08 +00:00
|
|
|
<div className={ classes }>
|
2020-10-13 01:40:53 +00:00
|
|
|
<Header />
|
2020-11-12 17:10:42 +00:00
|
|
|
<div className="woocommerce-navigation__wrapper" ref={ navDomRef }>
|
|
|
|
<Navigation
|
|
|
|
activeItem={ activeItem ? activeItem.id : null }
|
|
|
|
activeMenu={ activeLevel }
|
|
|
|
onActivateMenu={ ( ...args ) => {
|
|
|
|
if ( navDomRef && navDomRef.current ) {
|
|
|
|
navDomRef.current.scrollTop = 0;
|
|
|
|
}
|
2020-11-06 20:52:01 +00:00
|
|
|
|
2020-11-12 17:10:42 +00:00
|
|
|
setActiveLevel( ...args );
|
|
|
|
} }
|
|
|
|
>
|
|
|
|
{ categories.map( ( category ) => {
|
2020-12-02 14:36:35 +00:00
|
|
|
const {
|
|
|
|
primary: primaryItems,
|
|
|
|
secondary: secondaryItems,
|
|
|
|
plugins: pluginItems,
|
|
|
|
} = categorizedItems[ category.id ] || {};
|
2021-02-08 20:41:08 +00:00
|
|
|
return [
|
|
|
|
( !! primaryItems || !! pluginItems ) && (
|
|
|
|
<NavigationMenu
|
|
|
|
key={ category.id }
|
|
|
|
title={ category.title }
|
|
|
|
menu={ category.id }
|
|
|
|
parentMenu={ category.parent }
|
|
|
|
backButtonLabel={
|
|
|
|
isRootBackVisible
|
|
|
|
? rootBackLabel
|
|
|
|
: category.backButtonLabel || null
|
|
|
|
}
|
|
|
|
onBackButtonClick={
|
|
|
|
isRootBackVisible
|
|
|
|
? () => {
|
|
|
|
trackBackClick(
|
|
|
|
'woocommerce'
|
|
|
|
);
|
|
|
|
window.location = rootBackUrl;
|
|
|
|
}
|
|
|
|
: () =>
|
|
|
|
trackBackClick(
|
|
|
|
category.id
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{ !! primaryItems && (
|
|
|
|
<NavigationGroup>
|
|
|
|
{ primaryItems.map( ( item ) => (
|
|
|
|
<Item
|
|
|
|
key={ item.id }
|
|
|
|
item={ item }
|
|
|
|
/>
|
|
|
|
) ) }
|
|
|
|
</NavigationGroup>
|
|
|
|
) }
|
|
|
|
{ !! pluginItems && (
|
|
|
|
<NavigationGroup
|
|
|
|
title={
|
|
|
|
category.id === 'woocommerce'
|
|
|
|
? __(
|
|
|
|
'Extensions',
|
|
|
|
'woocommerce-admin'
|
|
|
|
)
|
|
|
|
: null
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{ pluginItems.map( ( item ) => (
|
|
|
|
<Item
|
|
|
|
key={ item.id }
|
|
|
|
item={ item }
|
|
|
|
/>
|
|
|
|
) ) }
|
|
|
|
</NavigationGroup>
|
|
|
|
) }
|
|
|
|
</NavigationMenu>
|
|
|
|
),
|
|
|
|
!! secondaryItems && (
|
|
|
|
<NavigationMenu
|
|
|
|
className="components-navigation__menu-secondary"
|
|
|
|
key={ `secondary/${ category.id }` }
|
|
|
|
title={ ! isRoot ? category.title : null }
|
|
|
|
menu={ category.id }
|
|
|
|
parentMenu={ category.parent }
|
|
|
|
backButtonLabel={
|
|
|
|
category.backButtonLabel || null
|
|
|
|
}
|
|
|
|
onBackButtonClick={
|
|
|
|
isRootBackVisible
|
|
|
|
? null
|
|
|
|
: () =>
|
|
|
|
trackBackClick(
|
|
|
|
category.id
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
2020-12-02 18:16:54 +00:00
|
|
|
<NavigationGroup
|
|
|
|
onBackButtonClick={ () =>
|
|
|
|
trackBackClick( category.id )
|
|
|
|
}
|
|
|
|
>
|
2020-11-12 17:10:42 +00:00
|
|
|
{ secondaryItems.map( ( item ) => (
|
|
|
|
<Item
|
|
|
|
key={ item.id }
|
|
|
|
item={ item }
|
|
|
|
/>
|
|
|
|
) ) }
|
|
|
|
</NavigationGroup>
|
2021-02-08 20:41:08 +00:00
|
|
|
</NavigationMenu>
|
|
|
|
),
|
|
|
|
];
|
2020-11-12 17:10:42 +00:00
|
|
|
} ) }
|
|
|
|
</Navigation>
|
|
|
|
</div>
|
2020-10-13 01:40:53 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default compose(
|
|
|
|
withSelect( ( select ) => {
|
|
|
|
const { getActiveItem, getMenuItems } = select( NAVIGATION_STORE_NAME );
|
|
|
|
|
|
|
|
return {
|
|
|
|
activeItem: getActiveItem(),
|
|
|
|
menuItems: getMenuItems(),
|
|
|
|
};
|
|
|
|
} )
|
|
|
|
)( Container );
|