woocommerce/plugins/woocommerce-admin/client/header/activity-panel/index.js

349 lines
8.9 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';
import clickOutside from 'react-click-outside';
import { Component } from '@wordpress/element';
import Gridicon from 'gridicons';
import { IconButton, NavigableMenu } from '@wordpress/components';
import { partial, uniqueId, find } from 'lodash';
import { getSetting } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
import './style.scss';
import ActivityPanelToggleBubble from './toggle-bubble';
import { H, Section } from '@woocommerce/components';
import {
getUnreadNotes,
getUnreadOrders,
getUnapprovedReviews,
getUnreadStock,
} from './unread-indicators';
2018-10-12 19:20:48 +00:00
import InboxPanel from './panels/inbox';
import OrdersPanel from './panels/orders';
import StockPanel from './panels/stock';
import { recordEvent } from 'lib/tracks';
import ReviewsPanel from './panels/reviews';
import withSelect from 'wc-api/with-select';
import WordPressNotices from './wordpress-notices';
const manageStock = getSetting( 'manageStock', 'no' );
const reviewsEnabled = getSetting( 'reviewsEnabled', 'no' );
class ActivityPanel extends Component {
constructor() {
super( ...arguments );
this.togglePanel = this.togglePanel.bind( this );
this.clearPanel = this.clearPanel.bind( this );
this.toggleMobile = this.toggleMobile.bind( this );
this.renderTab = this.renderTab.bind( this );
this.updateNoticeFlag = this.updateNoticeFlag.bind( this );
this.state = {
isPanelOpen: false,
mobileOpen: false,
currentTab: '',
isPanelSwitching: false,
hasWordPressNotices: false,
};
}
togglePanel( tabName ) {
const { isPanelOpen, currentTab } = this.state;
// If a panel is being opened, or if an existing panel is already open and a different one is being opened, record a track.
if ( ! isPanelOpen || tabName !== currentTab ) {
recordEvent( 'activity_panel_open', { tab: tabName } );
}
// The WordPress Notices tab is handled differently, since they are displayed inline, so the panel should be closed,
// Close behavior of the expanded notices is based on current tab.
if ( tabName === 'wpnotices' ) {
this.setState( ( state ) => ( {
currentTab: state.currentTab === 'wpnotices' ? '' : tabName,
mobileOpen: state.currentTab !== 'wpnotices',
isPanelOpen: false,
} ) );
return;
}
this.setState( ( state ) => {
if (
tabName === state.currentTab ||
state.currentTab === '' ||
state.currentTab === 'wpnotices'
) {
return {
isPanelOpen: ! state.isPanelOpen,
currentTab: tabName,
mobileOpen: ! state.isPanelOpen,
};
}
return { currentTab: tabName, isPanelSwitching: true };
} );
}
clearPanel() {
this.setState( ( { isPanelOpen } ) =>
isPanelOpen ? { isPanelSwitching: false } : { currentTab: '' }
);
}
// On smaller screen, the panel buttons are hidden behind a toggle.
toggleMobile() {
const tabs = this.getTabs();
this.setState( ( state ) => ( {
mobileOpen: ! state.mobileOpen,
currentTab: state.mobileOpen ? '' : tabs[ 0 ].name,
isPanelOpen: ! state.mobileOpen,
} ) );
}
handleClickOutside() {
const { isPanelOpen, currentTab } = this.state;
if ( isPanelOpen ) {
this.togglePanel( currentTab );
}
}
updateNoticeFlag( noticeCount ) {
this.setState( {
hasWordPressNotices: noticeCount > 0,
} );
}
// @todo Pull in dynamic unread status/count
getTabs() {
const {
hasUnreadNotes,
hasUnreadOrders,
hasUnapprovedReviews,
hasUnreadStock,
} = this.props;
return [
2018-10-12 19:20:48 +00:00
{
name: 'inbox',
title: __( 'Inbox', 'woocommerce-admin' ),
2018-10-12 19:20:48 +00:00
icon: <Gridicon icon="mail" />,
unread: hasUnreadNotes,
2018-10-12 19:20:48 +00:00
},
{
name: 'orders',
title: __( 'Orders', 'woocommerce-admin' ),
icon: <Gridicon icon="pages" />,
unread: hasUnreadOrders,
},
manageStock === 'yes'
? {
name: 'stock',
title: __( 'Stock', 'woocommerce-admin' ),
icon: <Gridicon icon="clipboard" />,
unread: hasUnreadStock,
}
: null,
reviewsEnabled === 'yes'
? {
name: 'reviews',
title: __( 'Reviews', 'woocommerce-admin' ),
icon: <Gridicon icon="star" />,
unread: hasUnapprovedReviews,
}
: null,
].filter( Boolean );
}
getPanelContent( tab ) {
switch ( tab ) {
2018-10-12 19:20:48 +00:00
case 'inbox':
return <InboxPanel />;
case 'orders':
const { hasUnreadOrders } = this.props;
return <OrdersPanel hasActionableOrders={ hasUnreadOrders } />;
case 'stock':
return <StockPanel />;
case 'reviews':
const { hasUnapprovedReviews } = this.props;
return (
<ReviewsPanel
hasUnapprovedReviews={ hasUnapprovedReviews }
/>
);
default:
return null;
}
}
renderPanel() {
const { isPanelOpen, currentTab, isPanelSwitching } = this.state;
const tab = find( this.getTabs(), { name: currentTab } );
if ( ! tab ) {
return (
<div className="woocommerce-layout__activity-panel-wrapper" />
);
}
const classNames = classnames(
'woocommerce-layout__activity-panel-wrapper',
{
'is-open': isPanelOpen,
'is-switching': isPanelSwitching,
}
);
return (
<div
className={ classNames }
tabIndex={ 0 }
role="tabpanel"
aria-label={ tab.title }
onTransitionEnd={ this.clearPanel }
onAnimationEnd={ this.clearPanel }
>
<div
className="woocommerce-layout__activity-panel-content"
key={ 'activity-panel-' + currentTab }
id={ 'activity-panel-' + currentTab }
>
{ this.getPanelContent( currentTab ) }
</div>
</div>
);
}
renderTab( tab, i ) {
const { currentTab, isPanelOpen } = this.state;
const className = classnames(
'woocommerce-layout__activity-panel-tab',
{
'is-active': isPanelOpen && tab.name === currentTab,
'has-unread': tab.unread,
}
);
const selected = tab.name === currentTab;
let tabIndex = -1;
// Only make this item tabbable if it is the currently selected item, or the panel is closed and the item is the first item
// If wpnotices is currently selected, tabindex below should be -1 and <WordPressNotices /> will become the tabbed element.
if (
selected ||
( ! isPanelOpen && i === 0 && currentTab !== 'wpnotices' )
) {
tabIndex = null;
}
return (
<IconButton
role="tab"
className={ className }
tabIndex={ tabIndex }
aria-selected={ selected }
aria-controls={ 'activity-panel-' + tab.name }
key={ 'activity-panel-tab-' + tab.name }
id={ 'activity-panel-tab-' + tab.name }
onClick={ partial( this.togglePanel, tab.name ) }
icon={ tab.icon }
>
{ tab.title }{ ' ' }
{ tab.unread && (
<span className="screen-reader-text">
{ __( 'unread activity', 'woocommerce-admin' ) }
</span>
) }
</IconButton>
);
}
render() {
const tabs = this.getTabs();
const { currentTab, mobileOpen, hasWordPressNotices } = this.state;
const headerId = uniqueId( 'activity-panel-header_' );
const panelClasses = classnames( 'woocommerce-layout__activity-panel', {
'is-mobile-open': this.state.mobileOpen,
} );
const hasUnread =
hasWordPressNotices || tabs.some( ( tab ) => tab.unread );
const viewLabel = hasUnread
? __(
'View Activity Panel, you have unread activity',
'woocommerce-admin'
)
: __( 'View Activity Panel', 'woocommerce-admin' );
return (
<div>
<H id={ headerId } className="screen-reader-text">
{ __( 'Store Activity', 'woocommerce-admin' ) }
</H>
<Section
component="aside"
id="woocommerce-activity-panel"
aria-labelledby={ headerId }
>
<IconButton
onClick={ this.toggleMobile }
icon={
mobileOpen ? (
<Gridicon icon="cross-small" />
) : (
<ActivityPanelToggleBubble
hasUnread={ hasUnread }
/>
)
}
label={
mobileOpen
? __(
'Close Activity Panel',
'woocommerce-admin'
)
: viewLabel
}
aria-expanded={ mobileOpen }
tooltip={ false }
className="woocommerce-layout__activity-panel-mobile-toggle"
/>
<div className={ panelClasses }>
<NavigableMenu
role="tablist"
orientation="horizontal"
className="woocommerce-layout__activity-panel-tabs"
>
{ tabs && tabs.map( this.renderTab ) }
{ Boolean(
document.getElementById( 'wp__notice-list' )
) && (
<WordPressNotices
showNotices={ currentTab === 'wpnotices' }
togglePanel={ this.togglePanel }
onCountUpdate={ this.updateNoticeFlag }
/>
) }
</NavigableMenu>
{ this.renderPanel() }
</div>
</Section>
</div>
);
}
}
export default withSelect( ( select ) => {
const hasUnreadNotes = getUnreadNotes( select );
const hasUnreadOrders = getUnreadOrders( select );
Version/1.0 master merge (https://github.com/woocommerce/woocommerce-admin/pull/3797) * Try: Moving Customers to main Woo Menu (https://github.com/woocommerce/woocommerce-admin/pull/3632) * Only add onboarding settings on wc-admin pages when task list should be shown. (https://github.com/woocommerce/woocommerce-admin/pull/3722) * Use cron for unsnoozing admin notes (https://github.com/woocommerce/woocommerce-admin/pull/3662) * Use wp-cron for admin note snoozing. * Remove "unsnooze" scheduled action. * Use correct version. * Avoid using deprecated method for unscheduling actions. * Onboarding: Fix toggle tracking events (https://github.com/woocommerce/woocommerce-admin/pull/3645) * Fix errant wcadmin prefix on event name * Track the onboarding toggle on the option in case enable_onboarding isn't used * Move toggle actions to separate function * Move onboarding actions * Move onboarding filters * Move help tab updates to add_toggle_actions * Only run onboarding actions when enabled * Onboarding: Add tracks events when profiler steps are completed (https://github.com/woocommerce/woocommerce-admin/pull/3726) * Add tracks for store profiler step completion * Record event when profiler is completed * Ensure continue setup loads the onboarding profiler (https://github.com/woocommerce/woocommerce-admin/pull/3646) * 'All that include' option removed when input field is empty (https://github.com/woocommerce/woocommerce-admin/pull/3700) * 'All that include' option removed when input field is empty Added a control to check that when the input field 'Search by customer name' is empty, the 'All that include' option is not appearing. * Const name improved The constant name hasValues was changed to optionsHaveValues (more descriptive) * Fix select text alignment (https://github.com/woocommerce/woocommerce-admin/pull/3723) * Stock panel indicator - cache and use lookup tables. (https://github.com/woocommerce/woocommerce-admin/pull/3729) * Stock panel indicator - cache and use lookup tables. * Revise query, clear transient on product update. * Fix error, ht Josh. * Checklist: Remove sideloaded images to reduce build size, take 2 (https://github.com/woocommerce/woocommerce-admin/pull/3731) * Remove homepage template images. * Use other-small on all industries, adjust text color. * Remove background dim and opacity set to 0 * Fix/3631 (https://github.com/woocommerce/woocommerce-admin/pull/3730) * Added CBD as an industry type CBD was added as an industry type in API * Industries options modified Modified the industries options. Now we are able to choose if we will use an input or not in the option. * API control changed for industries. API control changed for industries. Now it accepts the data type we need. * Added input in Industries list for the option "Other" Added an input for the option "Other" in the industries list * Added suggested changes in review comments. * Added data preparation for recordEvent * Changed variable to snake_case The variable "industriesWithDetail" was changed to "industries_with_detail" (snake_case) * Onboarding: Create homepage without redirect (https://github.com/woocommerce/woocommerce-admin/pull/3727) * Add link to edit homepage instead of redirect * Add busy state to homepage creation button * Publish homepage on create via API * Update homepage notice to show on first post update * Update homepage creation notice per design * Record event on customize homepage * Set homepage to frontpage on creation * Add deactivation note for feature plugin (https://github.com/woocommerce/woocommerce-admin/pull/3687) * Add version deactivation note * Add the note to deactivate if the version is older than the current WC version * Deactivate wc admin feature plugin on action click * Add notes version hooks * change the Package class namespace to exclude from standalone autoloader * add use statement for FeaturePlugin * add note explaining namespace * use wc-admin-deactivate-plugin note name * Rename file and class to WC_Admin_Notes_Deactivate_Plugin Co-authored-by: Ron Rennick <ron@ronandandrea.com> Co-authored-by: Paul Sealock <psealock@gmail.com> * Add Travis tests on GH for release branch (https://github.com/woocommerce/woocommerce-admin/pull/3751) * Add Travis tests on GH for release branch * fix linter errors * ActivityPanels.php -> use public static functions * Remove free text Search option when no query exists (https://github.com/woocommerce/woocommerce-admin/pull/3755) * Revert changes in woocommerce/woocommerce-admin#3700 * Don't add free text search if no query exists * Add tests for Search without query * Add test for showing free text search option * Fix image sideloading for store industries. (https://github.com/woocommerce/woocommerce-admin/pull/3743) * Fix image sideloading for store industries. Data format changed in https://github.com/woocommerce/woocommerce-admin/pull/3730 * Fix industry image sideload in cases where the count is less than requested. * Be backwards compatible with the old industry data format. * Added event props to identify stores with WCS and Jetpack installed (https://github.com/woocommerce/woocommerce-admin/pull/3750) * Added event props to identify stores with WCS and Jetpack installed Also, added Jeckpack connected status * Improved variable name * Simplified method Simplified method. "intersection" check was removed * Tests errors repeared The method "clear_low_out_of_stock_count_transient" now is static. * OBW: fix sideloading image test error (https://github.com/woocommerce/woocommerce-admin/pull/3762) * Release 0.26.0 changes (https://github.com/woocommerce/woocommerce-admin/pull/3753) * add deactivation hook to Package.php (https://github.com/woocommerce/woocommerce-admin/pull/3770) * Add active version functions (https://github.com/woocommerce/woocommerce-admin/pull/3772) * add active version functions to Package.php Co-authored-by: Joshua T Flowers <joshuatf@gmail.com> * 0.26.1 changes (https://github.com/woocommerce/woocommerce-admin/pull/3773) * Customers Report: fix missing report param in search (https://github.com/woocommerce/woocommerce-admin/pull/3778) * Product titles include encoded entities (https://github.com/woocommerce/woocommerce-admin/pull/3765) * Stripped HTML from product titles and decoded before displaying them Stripped html from product titles and entities are decoded before displaying them * Stripped HTML from product titles and decoded in Stock report Stripped html from product titles and entities are decoded before displaying them. Now in Stock report * Added support for HTML tags and encoded entities on product titles Added support for HTML tags and encoded entities on filtered product list, dropdown menus and tag names. Also, strip_tags() function was replaced with wp_strip_all_tags() instead. * strip_tags() function was replaced with wp_strip_all_tags() instead. * Added control for a variable Added control for "item->data" before applying wp_strip_all_tags method. * pre-commit changes * Test text corrected * fix linting issues * fix mis-merged changes * Update jsdoc Co-Authored-By: Paul Sealock <psealock@gmail.com> Co-authored-by: Timmy Crawford <timmyc@users.noreply.github.com> Co-authored-by: Jeff Stieler <jeff.m.stieler@gmail.com> Co-authored-by: Joshua T Flowers <joshuatf@gmail.com> Co-authored-by: Fernando <ultimoround@gmail.com> Co-authored-by: edmundcwm <edmundcwm@gmail.com> Co-authored-by: Paul Sealock <psealock@gmail.com>
2020-03-02 22:22:32 +00:00
const hasUnreadStock = getUnreadStock();
const hasUnapprovedReviews = getUnapprovedReviews( select );
return {
hasUnreadNotes,
hasUnreadOrders,
hasUnreadStock,
hasUnapprovedReviews,
};
} )( clickOutside( ActivityPanel ) );