From 76b8042359aec0122f38f8fd6ecb8ca033c0a667 Mon Sep 17 00:00:00 2001 From: Adrian Duffell <9312929+adrianduffell@users.noreply.github.com> Date: Thu, 21 Sep 2023 00:25:35 +0800 Subject: [PATCH] Replace "Personalize Your Store" Task with "Choose Your Theme" (#40239) * Update appearance task to choose a WP theme * Add changelog * Update redirect URL Redirects to the main theme screen. * Update plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Appearance.php Co-authored-by: Ilyas Foo * Wrap URL in getAdminLink * Update position of task * Change title * Change redirect URL to be the site editor * Revert to original task name * Use inherited is_complete function * Use PHP-based action tracking * Fix lint issue --------- Co-authored-by: Ilyas Foo --- .../client/task-lists/fills/appearance.js | 443 +----------------- .../changelog/update-appearance-task | 4 + .../Features/OnboardingTasks/TaskLists.php | 2 +- .../OnboardingTasks/Tasks/Appearance.php | 87 +--- 4 files changed, 40 insertions(+), 496 deletions(-) create mode 100644 plugins/woocommerce/changelog/update-appearance-task diff --git a/plugins/woocommerce-admin/client/task-lists/fills/appearance.js b/plugins/woocommerce-admin/client/task-lists/fills/appearance.js index bdc9a0f48d2..095f1c9b9b3 100644 --- a/plugins/woocommerce-admin/client/task-lists/fills/appearance.js +++ b/plugins/woocommerce-admin/client/task-lists/fills/appearance.js @@ -1,431 +1,36 @@ /** * External dependencies */ -import { __ } from '@wordpress/i18n'; -import apiFetch from '@wordpress/api-fetch'; -import { Button, Card, CardBody } from '@wordpress/components'; -import { Component, Fragment } from '@wordpress/element'; -import { compose } from '@wordpress/compose'; -import { filter } from 'lodash'; -import { withDispatch, withSelect } from '@wordpress/data'; - -import { Stepper, TextControl, ImageUpload } from '@woocommerce/components'; -import { - OPTIONS_STORE_NAME, - ONBOARDING_STORE_NAME, - WC_ADMIN_NAMESPACE, -} from '@woocommerce/data'; -import { queueRecordEvent, recordEvent } from '@woocommerce/tracks'; +import React from 'react'; +import { WooOnboardingTaskListItem } from '@woocommerce/onboarding'; import { registerPlugin } from '@wordpress/plugins'; -import { WooOnboardingTask } from '@woocommerce/onboarding'; +import { getAdminLink } from '@woocommerce/settings'; -/** - * Internal dependencies - */ -class Appearance extends Component { - constructor( props ) { - super( props ); - const { hasHomepage, hasProducts, supportCustomLogo } = - props.task.additionalData; - - this.stepVisibility = { - homepage: ! hasHomepage, - import: ! hasProducts, - logo: supportCustomLogo, - }; - - this.state = { - isDirty: false, - isPending: false, - logo: null, - stepIndex: 0, - isUpdatingLogo: false, - isUpdatingNotice: false, - storeNoticeText: props.demoStoreNotice || '', - }; - - this.completeStep = this.completeStep.bind( this ); - this.createHomepage = this.createHomepage.bind( this ); - this.importProducts = this.importProducts.bind( this ); - this.updateLogo = this.updateLogo.bind( this ); - this.updateNotice = this.updateNotice.bind( this ); - } - - componentDidMount() { - const { themeMods } = this.props.task.additionalData; - - if ( themeMods && themeMods.custom_logo ) { - /* eslint-disable react/no-did-mount-set-state */ - this.setState( { logo: { id: themeMods.custom_logo } } ); - /* eslint-enable react/no-did-mount-set-state */ - } - } - - componentDidUpdate( prevProps ) { - const { isPending, logo } = this.state; - const { demoStoreNotice } = this.props; - - if ( logo && ! logo.url && ! isPending ) { - /* eslint-disable react/no-did-update-set-state */ - this.setState( { isPending: true } ); - wp.media - .attachment( logo.id ) - .fetch() - .then( () => { - const logoUrl = wp.media.attachment( logo.id ).get( 'url' ); - this.setState( { - isPending: false, - logo: { id: logo.id, url: logoUrl }, - } ); - } ); - /* eslint-enable react/no-did-update-set-state */ - } - - if ( - demoStoreNotice && - prevProps.demoStoreNotice !== demoStoreNotice - ) { - /* eslint-disable react/no-did-update-set-state */ - this.setState( { - storeNoticeText: demoStoreNotice, - } ); - /* eslint-enable react/no-did-update-set-state */ - } - } - - async completeStep() { - const { stepIndex } = this.state; - const { actionTask, onComplete } = this.props; - const nextStep = this.getSteps()[ stepIndex + 1 ]; - - if ( nextStep ) { - this.setState( { stepIndex: stepIndex + 1 } ); - } else { - this.setState( { isPending: true } ); - await actionTask( 'appearance' ); - onComplete(); - } - } - - importProducts() { - const { createNotice } = this.props; - this.setState( { isPending: true } ); - - recordEvent( 'tasklist_appearance_import_demo', {} ); - - apiFetch( { - path: `${ WC_ADMIN_NAMESPACE }/onboarding/tasks/import_sample_products`, - method: 'POST', - } ) - .then( ( result ) => { - if ( result.failed && result.failed.length ) { - createNotice( - 'error', - __( - 'There was an error importing some of the sample products', - 'woocommerce' - ) - ); - } else { - createNotice( - 'success', - __( - 'All sample products have been imported', - 'woocommerce' - ) - ); - } - - this.setState( { isPending: false } ); - this.completeStep(); - } ) - .catch( ( { message } ) => { - createNotice( - 'error', - message || - __( - 'There was an error importing the sample products', - 'woocommerce' - ), - { __unstableHTML: true } - ); - this.setState( { isPending: false } ); - } ); - } - - createHomepage() { - const { createNotice } = this.props; - this.setState( { isPending: true } ); - - recordEvent( 'tasklist_appearance_create_homepage', { - create_homepage: true, - } ); - - apiFetch( { - path: '/wc-admin/onboarding/tasks/create_homepage', - method: 'POST', - } ) - .then( ( response ) => { - createNotice( response.status, response.message, { - actions: response.edit_post_link - ? [ - { - label: __( 'Customize', 'woocommerce' ), - onClick: () => { - queueRecordEvent( - 'tasklist_appearance_customize_homepage', - {} - ); - window.location = `${ response.edit_post_link }&wc_onboarding_active_task=appearance`; - }, - }, - ] - : null, - } ); - - this.setState( { isPending: false } ); - this.completeStep(); - } ) - .catch( ( error ) => { - createNotice( 'error', error.message ); - this.setState( { isPending: false } ); - } ); - } - - async updateLogo() { - const { createNotice, task, updateOptions } = this.props; - const { stylesheet, themeMods } = task.additionalData; - const { logo } = this.state; - const updatedThemeMods = { - ...themeMods, - custom_logo: logo ? logo.id : null, - }; - - recordEvent( 'tasklist_appearance_upload_logo' ); - - this.setState( { isUpdatingLogo: true } ); - const update = await updateOptions( { - [ `theme_mods_${ stylesheet }` ]: updatedThemeMods, - } ); - - if ( update.success ) { - this.setState( { isUpdatingLogo: false } ); - createNotice( - 'success', - __( 'Store logo updated successfully', 'woocommerce' ) - ); - this.completeStep(); - } else { - createNotice( 'error', update.message ); - } - } - - async updateNotice() { - const { createNotice, updateOptions } = this.props; - const { storeNoticeText } = this.state; - - recordEvent( 'tasklist_appearance_set_store_notice', { - added_text: Boolean( storeNoticeText.length ), - } ); - - this.setState( { isUpdatingNotice: true } ); - const update = await updateOptions( { - woocommerce_demo_store: storeNoticeText.length ? 'yes' : 'no', - woocommerce_demo_store_notice: storeNoticeText, - } ); - - if ( update.success ) { - this.setState( { isUpdatingNotice: false } ); - createNotice( - 'success', - __( - "🎨 Your store is looking great! Don't forget to continue personalizing it", - 'woocommerce' - ) - ); - this.completeStep(); - } else { - createNotice( 'error', update.message ); - } - } - - getSteps() { - const { isDirty, isPending, logo, storeNoticeText, isUpdatingLogo } = - this.state; - - const steps = [ - { - key: 'import', - label: __( 'Import sample products', 'woocommerce' ), - description: __( - 'We’ll add some products that will make it easier to see what your store looks like', - 'woocommerce' - ), - content: ( - - - - - ), - visible: this.stepVisibility.import, - }, - { - key: 'homepage', - label: __( 'Create a custom homepage', 'woocommerce' ), - description: __( - 'Create a new homepage and customize it to suit your needs', - 'woocommerce' - ), - content: ( - - - - - ), - visible: this.stepVisibility.homepage, - }, - { - key: 'logo', - label: __( 'Upload a logo', 'woocommerce' ), - description: __( - 'Ensure your store is on-brand by adding your logo', - 'woocommerce' - ), - content: isPending ? null : ( - - - this.setState( { isDirty: true, logo: image } ) - } - /> - - - - ), - visible: this.stepVisibility.logo, - }, - { - key: 'notice', - label: __( 'Set a store notice', 'woocommerce' ), - description: __( - 'Optionally display a prominent notice across all pages of your store', - 'woocommerce' - ), - content: ( - - - this.setState( { storeNoticeText: value } ) - } - /> - - - ), - visible: true, - }, - ]; - - return filter( steps, ( step ) => step.visible ); - } - - render() { - const { isPending, stepIndex, isUpdatingLogo, isUpdatingNotice } = - this.state; - const currentStep = this.getSteps()[ stepIndex ].key; - - return ( -
- - - - - -
+const useAppearanceClick = () => { + const onClick = () => { + window.location = getAdminLink( + 'theme-install.php?browse=block-themes' ); - } -} + }; -const AppearanceWrapper = compose( - withSelect( ( select ) => { - const { getOption } = select( OPTIONS_STORE_NAME ); + return { onClick }; +}; - return { - demoStoreNotice: getOption( 'woocommerce_demo_store_notice' ), - }; - } ), - withDispatch( ( dispatch ) => { - const { createNotice } = dispatch( 'core/notices' ); - const { updateOptions } = dispatch( OPTIONS_STORE_NAME ); - const { actionTask } = dispatch( ONBOARDING_STORE_NAME ); - - return { - actionTask, - createNotice, - updateOptions, - }; - } ) -)( Appearance ); +const AppearanceFill = () => { + const { onClick } = useAppearanceClick(); + return ( + + { ( { defaultTaskItem: DefaultTaskItem } ) => ( + + ) } + + ); +}; registerPlugin( 'wc-admin-onboarding-task-appearance', { scope: 'woocommerce-tasks', - render: () => ( - - { ( { onComplete, task } ) => ( - - ) } - - ), + render: () => , } ); diff --git a/plugins/woocommerce/changelog/update-appearance-task b/plugins/woocommerce/changelog/update-appearance-task new file mode 100644 index 00000000000..dc069582853 --- /dev/null +++ b/plugins/woocommerce/changelog/update-appearance-task @@ -0,0 +1,4 @@ +Significance: minor +Type: update + +Replace Personalize Your Store task with Choose Your Theme diff --git a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskLists.php b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskLists.php index 361d8dee1d7..d9215cdbb7b 100644 --- a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskLists.php +++ b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskLists.php @@ -112,12 +112,12 @@ class TaskLists { 'CustomizeStore', 'StoreDetails', 'Products', + 'Appearance', 'WooCommercePayments', 'Payments', 'Tax', 'Shipping', 'Marketing', - 'Appearance', ); if ( Features::is_enabled( 'core-profiler' ) ) { diff --git a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Appearance.php b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Appearance.php index 2b2832bf635..721b3db43e3 100644 --- a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Appearance.php +++ b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Appearance.php @@ -14,14 +14,12 @@ use Automattic\WooCommerce\Internal\Admin\WCAdminAssets; class Appearance extends Task { /** - * Constructor - * - * @param TaskList $task_list Parent task list. + * Constructor. */ - public function __construct( $task_list ) { - parent::__construct( $task_list ); - add_action( 'admin_enqueue_scripts', array( $this, 'add_media_scripts' ) ); - add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_return_notice_script' ) ); + public function __construct() { + if ( ! $this->is_complete() ) { + add_action( 'load-theme-install.php', array( $this, 'mark_actioned' ) ); + } } /** @@ -39,13 +37,7 @@ class Appearance extends Task { * @return string */ public function get_title() { - if ( $this->get_parent_option( 'use_completed_title' ) === true ) { - if ( $this->is_complete() ) { - return __( 'You personalized your store', 'woocommerce' ); - } - return __( 'Personalize your store', 'woocommerce' ); - } - return __( 'Personalize my store', 'woocommerce' ); + return __( 'Choose your theme', 'woocommerce' ); } /** @@ -55,7 +47,7 @@ class Appearance extends Task { */ public function get_content() { return __( - 'Add your logo, create a homepage, and start designing your store.', + "Choose a theme that best fits your brand's look and feel, then make it your own. Change the colors, add your logo, and create pages.", 'woocommerce' ); } @@ -70,68 +62,11 @@ class Appearance extends Task { } /** - * Addtional data. + * Action label. * - * @return array + * @return string */ - public function get_additional_data() { - return array( - 'has_homepage' => self::has_homepage(), - 'has_products' => Products::has_products(), - 'stylesheet' => get_option( 'stylesheet' ), - 'theme_mods' => get_theme_mods(), - 'support_custom_logo' => false !== get_theme_support( 'custom-logo' ), - ); - } - - /** - * Add media scripts for image uploader. - */ - public function add_media_scripts() { - if ( ! PageController::is_admin_page() || ! $this->can_view() ) { - return; - } - - wp_enqueue_media(); - } - - - /** - * Adds a return to task list notice when completing the task. - * - * @param string $hook Page hook. - */ - public function possibly_add_return_notice_script( $hook ) { - global $post; - - if ( $hook !== 'post.php' || $post->post_type !== 'page' ) { - return; - } - - if ( $this->is_complete() || ! $this->is_active() ) { - return; - } - - WCAdminAssets::register_script( 'wp-admin-scripts', 'onboarding-homepage-notice', true ); - } - - /** - * Check if the site has a homepage set up. - */ - public static function has_homepage() { - if ( get_option( 'classic-editor-replace' ) === 'classic' ) { - return true; - } - - $homepage_id = get_option( 'woocommerce_onboarding_homepage_post_id', false ); - - if ( ! $homepage_id ) { - return false; - } - - $post = get_post( $homepage_id ); - $completed = $post && $post->post_status === 'publish'; - - return $completed; + public function get_action_label() { + return __( 'Choose theme', 'woocommerce' ); } }