From e9f4d452743e6d772d0dd5b737f56c86fa6a98cb Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 23 Oct 2019 11:17:38 -0400 Subject: [PATCH] Install business extensions on the business details page (https://github.com/woocommerce/woocommerce-admin/pull/3084) * Install Facebook & MailChimp plugins on the business details page * Handle PR feedback: Add missing plugin name constants, and improve plugin component error handling --- .../profile-wizard/steps/business-details.js | 135 ++++++++++++------ .../task-list/tasks/steps/plugins.js | 17 ++- .../client/wc-api/onboarding/constants.js | 2 + .../src/API/OnboardingProfile.php | 2 +- .../src/Features/Onboarding.php | 1 + 5 files changed, 109 insertions(+), 48 deletions(-) diff --git a/plugins/woocommerce-admin/client/dashboard/profile-wizard/steps/business-details.js b/plugins/woocommerce-admin/client/dashboard/profile-wizard/steps/business-details.js index c0d1b4a21dd..fecd9fa052b 100644 --- a/plugins/woocommerce-admin/client/dashboard/profile-wizard/steps/business-details.js +++ b/plugins/woocommerce-admin/client/dashboard/profile-wizard/steps/business-details.js @@ -23,6 +23,8 @@ import { H, Card, SelectControl, Form } from '@woocommerce/components'; import withSelect from 'wc-api/with-select'; import { recordEvent } from 'lib/tracks'; import { formatCurrency } from '@woocommerce/currency'; +import Plugins from 'dashboard/task-list/tasks/steps/plugins'; +import { pluginNames } from 'wc-api/onboarding/constants'; const wcAdminAssetUrl = getSetting( 'wcAdminAssetUrl', '' ); @@ -35,11 +37,17 @@ class BusinessDetails extends Component { product_count: '', selling_venues: '', revenue: '', - facebook: true, - mailchimp: true, + 'facebook-for-woocommerce': true, + 'mailchimp-for-woocommerce': true, }; - this.extensions = [ 'facebook', 'mailchimp' ]; + this.state = { + installExtensions: false, + isInstallingExtensions: false, + extensionInstallError: false, + }; + + this.extensions = [ 'facebook-for-woocommerce', 'mailchimp-for-woocommerce' ]; this.onContinue = this.onContinue.bind( this ); this.validate = this.validate.bind( this ); @@ -47,7 +55,7 @@ class BusinessDetails extends Component { async onContinue( values ) { const { createNotice, goToNextStep, isError, updateProfileItems } = this.props; - const { facebook, mailchimp, other_platform, product_count, revenue, selling_venues } = values; + const { other_platform, product_count, revenue, selling_venues } = values; const businessExtensions = this.getBusinessExtensions( values ); recordEvent( 'storeprofiler_store_business_details_continue', { @@ -56,8 +64,8 @@ class BusinessDetails extends Component { currency: currency.code, revenue, used_platform: other_platform, - install_facebook: facebook, - install_mailchimp: mailchimp, + install_facebook: values[ 'facebook-for-woocommerce' ], + install_mailchimp: values[ 'mailchimp-for-woocommerce' ], } ); const _updates = { @@ -79,7 +87,15 @@ class BusinessDetails extends Component { await updateProfileItems( updates ); if ( ! isError ) { - goToNextStep(); + if ( 0 === businessExtensions.length ) { + goToNextStep(); + return; + } + + this.setState( { + installExtensions: true, + isInstallingExtensions: true, + } ); } else { createNotice( 'error', @@ -134,34 +150,37 @@ class BusinessDetails extends Component { } renderBusinessExtensionHelpText( values ) { + const { isInstallingExtensions } = this.state; const extensions = this.getBusinessExtensions( values ); - const extensionSlugs = { - facebook: __( 'Facebook for WooCommerce', 'woocommerce-admin' ), - mailchimp: __( 'Mailchimp for WooCommerce', 'woocommerce-admin' ), - }; if ( 0 === extensions.length ) { return null; } + const extensionsList = extensions + .map( extension => { + return pluginNames[ extension ]; + } ) + .join( ', ' ); + + if ( isInstallingExtensions ) { + return

{ sprintf( __( 'Installing the following plugins: %s' ), extensionsList ) }

; + } + return (

- { sprintf( - __( 'The following plugins will be installed for free: %s' ), - extensions - .map( extension => { - return extensionSlugs[ extension ]; - } ) - .join( ', ' ) - ) } + { sprintf( __( 'The following plugins will be installed for free: %s' ), extensionsList ) }

); } renderBusinessExtensions( values, getInputProps ) { + const { installExtensions } = this.state; + const { goToNextStep } = this.props; + const extensionsToInstall = this.getBusinessExtensions( values ); const extensionBenefits = [ { - slug: 'facebook', + slug: 'facebook-for-woocommerce', title: __( 'Market on Facebook', 'woocommerce-admin' ), icon: 'onboarding/facebook.png', description: __( @@ -170,7 +189,7 @@ class BusinessDetails extends Component { ), }, { - slug: 'mailchimp', + slug: 'mailchimp-for-woocommerce', title: __( 'Contact customers with Mailchimp', 'woocommerce-admin' ), icon: 'onboarding/mailchimp.png', description: __( @@ -181,26 +200,51 @@ class BusinessDetails extends Component { ]; return ( -
- { extensionBenefits.map( benefit => ( -
-
- + +
+ { extensionBenefits.map( benefit => ( +
+
+ +
+
+ { benefit.title } +

{ benefit.description }

+
+
+ +
-
- { benefit.title } -

{ benefit.description }

-
-
- -
-
- ) ) } -
+ ) ) } +
+ + { installExtensions && ( + { + goToNextStep(); + } } + onSkip={ () => { + goToNextStep(); + } } + onError={ () => { + this.setState( { + extensionInstallError: true, + isInstallingExtensions: false, + } ); + } } + autoInstall + pluginSlugs={ extensionsToInstall } + /> + ) } + ); } render() { + const { isInstallingExtensions, extensionInstallError } = this.state; const productCountOptions = [ { key: '1-10', @@ -359,14 +403,17 @@ class BusinessDetails extends Component { { showExtensions && this.renderBusinessExtensions( values, getInputProps ) } - + { ! extensionInstallError && ( + + ) } diff --git a/plugins/woocommerce-admin/client/dashboard/task-list/tasks/steps/plugins.js b/plugins/woocommerce-admin/client/dashboard/task-list/tasks/steps/plugins.js index 07539d8317f..f62c7cb8edc 100644 --- a/plugins/woocommerce-admin/client/dashboard/task-list/tasks/steps/plugins.js +++ b/plugins/woocommerce-admin/client/dashboard/task-list/tasks/steps/plugins.js @@ -41,6 +41,8 @@ class Plugins extends Component { installedPlugins, isRequesting, pluginSlugs, + onError, + hasErrors, } = this.props; const newErrors = difference( errors, prevProps.errors ); @@ -62,6 +64,10 @@ class Plugins extends Component { ); onComplete(); } + + if ( ! prevProps.hasErrors && hasErrors ) { + onError(); + } } async installAndActivatePlugins( event ) { @@ -87,9 +93,14 @@ class Plugins extends Component { if ( hasErrors ) { return ( - + + + + ); } diff --git a/plugins/woocommerce-admin/client/wc-api/onboarding/constants.js b/plugins/woocommerce-admin/client/wc-api/onboarding/constants.js index 69267471b0a..ca174c345bd 100644 --- a/plugins/woocommerce-admin/client/wc-api/onboarding/constants.js +++ b/plugins/woocommerce-admin/client/wc-api/onboarding/constants.js @@ -10,4 +10,6 @@ import { __ } from '@wordpress/i18n'; export const pluginNames = { jetpack: __( 'Jetpack', 'woocommerce-admin' ), 'woocommerce-services': __( 'WooCommerce Services', 'woocommerce-admin' ), + 'mailchimp-for-woocommerce': __( 'Mailchimp for WooCommerce', 'woocommerce-admin' ), + 'facebook-for-woocommerce': __( 'Facebook for WooCommerce', 'woocommerce-admin' ), }; diff --git a/plugins/woocommerce-admin/src/API/OnboardingProfile.php b/plugins/woocommerce-admin/src/API/OnboardingProfile.php index 8c92a03d45d..0e217f4fcc3 100644 --- a/plugins/woocommerce-admin/src/API/OnboardingProfile.php +++ b/plugins/woocommerce-admin/src/API/OnboardingProfile.php @@ -322,7 +322,7 @@ class OnboardingProfile extends \WC_REST_Data_Controller { 'sanitize_callback' => 'wp_parse_slug_list', 'validate_callback' => 'rest_validate_request_arg', 'items' => array( - 'enum' => array( 'mailchimp', 'facebook' ), + 'enum' => array( 'mailchimp-for-woocommerce', 'facebook-for-woocommerce' ), 'type' => 'string', ), ), diff --git a/plugins/woocommerce-admin/src/Features/Onboarding.php b/plugins/woocommerce-admin/src/Features/Onboarding.php index 477673ef1bc..543660ebb11 100644 --- a/plugins/woocommerce-admin/src/Features/Onboarding.php +++ b/plugins/woocommerce-admin/src/Features/Onboarding.php @@ -390,6 +390,7 @@ class Onboarding { 'woocommerce_onboarding_plugins_whitelist', array( 'facebook-for-woocommerce' => 'facebook-for-woocommerce/facebook-for-woocommerce.php', + 'mailchimp-for-woocommerce' => 'mailchimp-for-woocommerce/mailchimp-woocommerce.php', 'jetpack' => 'jetpack/jetpack.php', 'woocommerce-services' => 'woocommerce-services/woocommerce-services.php', 'woocommerce-gateway-stripe' => 'woocommerce-gateway-stripe/woocommerce-gateway-stripe.php',