Onboarding: Add purchase products task list item (https://github.com/woocommerce/woocommerce-admin/pull/3472)
* Add an array of installed plugins to wcSettings * Don't include already installed plugins in cart items * Move cart modal component * Add purchase task and modal to task list * Rename ambiguous task getter method * Remove modal purchase later prop * Show completed product purchase task item after purchase * Don't show cart modal if all items previously purchased
This commit is contained in:
parent
1a83c50e19
commit
700cf7bb2d
|
@ -24,7 +24,7 @@ import Section from './section';
|
|||
import withSelect from 'wc-api/with-select';
|
||||
import { recordEvent } from 'lib/tracks';
|
||||
import TaskList from './task-list';
|
||||
import { getTasks } from './task-list/tasks';
|
||||
import { getAllTasks } from './task-list/tasks';
|
||||
import { isOnboardingEnabled } from 'dashboard/utils';
|
||||
import { getCurrentDates, getDateParamsFromQuery, isoDateFormat } from 'lib/date';
|
||||
import ReportFilters from 'analytics/components/report-filters';
|
||||
|
@ -277,7 +277,7 @@ export default compose(
|
|||
|
||||
if ( isOnboardingEnabled() ) {
|
||||
const profileItems = getProfileItems();
|
||||
const tasks = getTasks( {
|
||||
const tasks = getAllTasks( {
|
||||
profileItems,
|
||||
options: getOptions( [ 'woocommerce_task_list_payments' ] ),
|
||||
query: props.query,
|
||||
|
|
|
@ -17,7 +17,7 @@ import { updateQueryString } from '@woocommerce/navigation';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import BusinessDetails from './steps/business-details';
|
||||
import CartModal from './cart-modal';
|
||||
import CartModal from '../components/cart-modal';
|
||||
import Industry from './steps/industry';
|
||||
import Plugins from './steps/plugins';
|
||||
import ProductTypes from './steps/product-types';
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Component, Fragment } from '@wordpress/element';
|
||||
import { filter, get } from 'lodash';
|
||||
import { get } from 'lodash';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import classNames from 'classnames';
|
||||
import { Snackbar, Icon, Button, Modal } from '@wordpress/components';
|
||||
|
@ -20,14 +20,16 @@ import { updateQueryString } from '@woocommerce/navigation';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
import CartModal from '../components/cart-modal';
|
||||
import { getAllTasks } from './tasks';
|
||||
import { recordEvent } from 'lib/tracks';
|
||||
import { getTasks } from './tasks';
|
||||
import withSelect from 'wc-api/with-select';
|
||||
|
||||
class TaskDashboard extends Component {
|
||||
constructor( props ) {
|
||||
super( props );
|
||||
this.state = {
|
||||
isCartModalOpen: false,
|
||||
isWelcomeModalOpen: ! props.modalDismissed,
|
||||
};
|
||||
}
|
||||
|
@ -61,6 +63,17 @@ class TaskDashboard extends Component {
|
|||
document.body.classList.remove( 'woocommerce-task-dashboard__body' );
|
||||
}
|
||||
|
||||
getTasks() {
|
||||
const { profileItems, query, taskListPayments } = this.props;
|
||||
|
||||
return getAllTasks( {
|
||||
profileItems,
|
||||
options: taskListPayments,
|
||||
query: query,
|
||||
toggleCartModal: this.toggleCartModal.bind( this ),
|
||||
} ).filter( task => task.visible );
|
||||
}
|
||||
|
||||
recordTaskView() {
|
||||
const { task } = this.props.query;
|
||||
|
||||
|
@ -78,7 +91,7 @@ class TaskDashboard extends Component {
|
|||
return;
|
||||
}
|
||||
const { profileItems } = this.props;
|
||||
const tasks = filter( this.props.tasks, task => task.visible );
|
||||
const tasks = this.getTasks();
|
||||
recordEvent( 'tasklist_view', {
|
||||
number_tasks: tasks.length,
|
||||
store_connected: profileItems.wccom_connected,
|
||||
|
@ -107,7 +120,7 @@ class TaskDashboard extends Component {
|
|||
|
||||
getCurrentTask() {
|
||||
const { task } = this.props.query;
|
||||
const currentTask = this.props.tasks.find( s => s.key === task );
|
||||
const currentTask = this.getTasks().find( s => s.key === task );
|
||||
|
||||
if ( ! currentTask ) {
|
||||
return null;
|
||||
|
@ -156,6 +169,10 @@ class TaskDashboard extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
toggleCartModal() {
|
||||
this.setState( { isCartModalOpen: ! this.state.isCartModalOpen } );
|
||||
}
|
||||
|
||||
closeWelcomeModal() {
|
||||
// Prevent firing this event before the modal is seen.
|
||||
if ( document.body.classList.contains( 'woocommerce-admin-is-loading' ) ) {
|
||||
|
@ -211,10 +228,10 @@ class TaskDashboard extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { inline, tasks } = this.props;
|
||||
const { isWelcomeModalOpen } = this.state;
|
||||
const { inline } = this.props;
|
||||
const { isCartModalOpen, isWelcomeModalOpen } = this.state;
|
||||
const currentTask = this.getCurrentTask();
|
||||
const listTasks = filter( tasks, task => task.visible ).map( task => {
|
||||
const listTasks = this.getTasks().map( task => {
|
||||
task.className = classNames( task.completed ? 'is-complete' : null, task.className );
|
||||
task.before = task.completed ? (
|
||||
<i className="material-icons-outlined">check_circle</i>
|
||||
|
@ -253,13 +270,19 @@ class TaskDashboard extends Component {
|
|||
</Fragment>
|
||||
) }
|
||||
</div>
|
||||
{ isCartModalOpen && (
|
||||
<CartModal
|
||||
onClose={ () => this.toggleCartModal() }
|
||||
onClickPurchaseLater={ () => this.toggleCartModal() }
|
||||
/>
|
||||
) }
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSelect( ( select, props ) => {
|
||||
withSelect( select => {
|
||||
const { getProfileItems, getOptions } = select( 'wc-api' );
|
||||
const profileItems = getProfileItems();
|
||||
|
||||
|
@ -273,18 +296,13 @@ export default compose(
|
|||
[ 'woocommerce_task_list_welcome_modal_dismissed' ],
|
||||
false
|
||||
);
|
||||
|
||||
const tasks = getTasks( {
|
||||
profileItems,
|
||||
options: getOptions( [ 'woocommerce_task_list_payments' ] ),
|
||||
query: props.query,
|
||||
} );
|
||||
const taskListPayments = getOptions( [ 'woocommerce_task_list_payments' ] );
|
||||
|
||||
return {
|
||||
modalDismissed,
|
||||
profileItems,
|
||||
promptShown,
|
||||
tasks,
|
||||
taskListPayments,
|
||||
};
|
||||
} ),
|
||||
withDispatch( dispatch => {
|
||||
|
|
|
@ -19,12 +19,13 @@ import { updateQueryString } from '@woocommerce/navigation';
|
|||
*/
|
||||
import Appearance from './tasks/appearance';
|
||||
import Connect from './tasks/connect';
|
||||
import { getProductIdsForCart } from 'dashboard/utils';
|
||||
import Products from './tasks/products';
|
||||
import Shipping from './tasks/shipping';
|
||||
import Tax from './tasks/tax';
|
||||
import Payments from './tasks/payments';
|
||||
|
||||
export function getTasks( { profileItems, options, query } ) {
|
||||
export function getAllTasks( { profileItems, options, query, toggleCartModal } ) {
|
||||
const {
|
||||
hasHomepage,
|
||||
hasPhysicalProducts,
|
||||
|
@ -39,6 +40,9 @@ export function getTasks( { profileItems, options, query } ) {
|
|||
shippingZonesCount: 0,
|
||||
} );
|
||||
|
||||
const productIds = getProductIdsForCart( profileItems, true );
|
||||
const remainingProductIds = getProductIdsForCart( profileItems );
|
||||
|
||||
const paymentsCompleted = get(
|
||||
options,
|
||||
[ 'woocommerce_task_list_payments', 'completed' ],
|
||||
|
@ -46,6 +50,19 @@ export function getTasks( { profileItems, options, query } ) {
|
|||
);
|
||||
|
||||
const tasks = [
|
||||
{
|
||||
key: 'purchase',
|
||||
title: __( 'Purchase & install extensions', 'woocommerce-admin' ),
|
||||
content: __(
|
||||
'Purchase, install, and manage your extensions directly from your dashboard',
|
||||
'wooocommerce-admin'
|
||||
),
|
||||
icon: 'extension',
|
||||
container: null,
|
||||
onClick: () => ( remainingProductIds.length ? toggleCartModal() : null ),
|
||||
visible: productIds.length,
|
||||
completed: ! remainingProductIds.length,
|
||||
},
|
||||
{
|
||||
key: 'connect',
|
||||
title: __( 'Connect your store to WooCommerce.com', 'woocommerce-admin' ),
|
||||
|
|
|
@ -41,9 +41,10 @@ export function getCurrencyRegion( countryState ) {
|
|||
* Gets the product IDs for items based on the product types and theme selected in the onboarding profiler.
|
||||
*
|
||||
* @param {object} profileItems Onboarding profile.
|
||||
* @param {bool} includeInstalledItems Include installed items in returned product IDs.
|
||||
* @return {array} Product Ids.
|
||||
*/
|
||||
export function getProductIdsForCart( profileItems ) {
|
||||
export function getProductIdsForCart( profileItems, includeInstalledItems = false ) {
|
||||
const productIds = [];
|
||||
const onboarding = getSetting( 'onboarding', {} );
|
||||
const productTypes = profileItems.product_types || [];
|
||||
|
@ -51,7 +52,9 @@ export function getProductIdsForCart( profileItems ) {
|
|||
productTypes.forEach( productType => {
|
||||
if (
|
||||
onboarding.productTypes[ productType ] &&
|
||||
onboarding.productTypes[ productType ].product
|
||||
onboarding.productTypes[ productType ].product &&
|
||||
( includeInstalledItems ||
|
||||
! onboarding.installedPlugins.includes( onboarding.productTypes[ productType ].slug ) )
|
||||
) {
|
||||
productIds.push( onboarding.productTypes[ productType ].product );
|
||||
}
|
||||
|
@ -59,7 +62,12 @@ export function getProductIdsForCart( profileItems ) {
|
|||
|
||||
const theme = onboarding.themes.find( themeData => themeData.slug === profileItems.theme );
|
||||
|
||||
if ( theme && theme.id && ! theme.is_installed && getPriceValue( theme.price ) > 0 ) {
|
||||
if (
|
||||
theme &&
|
||||
theme.id &&
|
||||
getPriceValue( theme.price ) > 0 &&
|
||||
( includeInstalledItems || ! theme.is_installed )
|
||||
) {
|
||||
productIds.push( theme.id );
|
||||
}
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ class Onboarding {
|
|||
$product_types[ $key ]['label'] .= sprintf( __( ' — %s per year', 'woocommerce-admin' ), html_entity_decode( $products[ $product_type['product'] ]->price ) );
|
||||
$product_types[ $key ]['description'] = $products[ $product_type['product'] ]->excerpt;
|
||||
$product_types[ $key ]['more_url'] = $products[ $product_type['product'] ]->link;
|
||||
$product_types[ $key ]['slug'] = strtolower( preg_replace( '~[^\pL\d]+~u', '-', $products[ $product_type['product'] ]->slug ) );
|
||||
} elseif ( isset( $product_type['product'] ) ) {
|
||||
/* translators: site currency symbol (used to show that the product costs money) */
|
||||
$product_types[ $key ]['label'] .= sprintf( __( ' — %s', 'woocommerce-admin' ), html_entity_decode( get_woocommerce_currency_symbol() ) );
|
||||
|
@ -367,6 +368,7 @@ class Onboarding {
|
|||
// Only fetch if the onboarding wizard OR the task list is incomplete.
|
||||
if ( self::should_show_profiler() || self::should_show_tasks() ) {
|
||||
$settings['onboarding']['activePlugins'] = self::get_active_plugins();
|
||||
$settings['onboarding']['installedPlugins'] = self::get_installed_plugins();
|
||||
$settings['onboarding']['stripeSupportedCountries'] = self::get_stripe_supported_countries();
|
||||
$settings['onboarding']['euCountries'] = WC()->countries->get_european_union_countries();
|
||||
$settings['onboarding']['connectNonce'] = wp_create_nonce( 'connect' );
|
||||
|
@ -537,6 +539,21 @@ class Onboarding {
|
|||
return apply_filters( 'woocommerce_admin_onboarding_themes_whitelist', $allowed_themes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of installed plugin slugs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_installed_plugins() {
|
||||
return array_map(
|
||||
function( $plugin_path ) {
|
||||
$path_parts = explode( '/', $plugin_path );
|
||||
return $path_parts[0];
|
||||
},
|
||||
array_keys( get_plugins() )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the app know that we will be showing the onboarding route, so wp-admin elements should be hidden while loading.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue