From 874ef001d125a0e79266fecfd80a74e7bad8d210 Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 3 Oct 2024 20:28:13 +0400 Subject: [PATCH 01/69] Save WIP. --- .../connect-mc/connect-mc.js | 138 ++++++++++++++++++ .../connect-mc/connect-mc.scss | 0 .../connect-mc/index.js | 1 + .../connected-google-combo-account-card.js | 56 ++++--- js/src/hooks/useAutoCreateAdsMCAccounts.js | 2 +- .../hooks/useAutoCreateAdsMCAccounts.test.js | 29 ++-- js/src/setup-mc/setup-stepper/index.js | 10 +- 7 files changed, 189 insertions(+), 47 deletions(-) create mode 100644 js/src/components/google-combo-account-card/connect-mc/connect-mc.js create mode 100644 js/src/components/google-combo-account-card/connect-mc/connect-mc.scss create mode 100644 js/src/components/google-combo-account-card/connect-mc/index.js diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js new file mode 100644 index 0000000000..845a5bcac7 --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -0,0 +1,138 @@ +/** + * External dependencies + */ +import { CardDivider } from '@wordpress/components'; +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import MerchantCenterSelectControl from '.~/components/merchant-center-select-control'; +import AppButton from '.~/components/app-button'; +import Section from '.~/wcdl/section'; +import Subsection from '.~/wcdl/subsection'; +import ContentButtonLayout from '.~/components/content-button-layout'; +import SwitchUrlCard from '.~/components/google-mc-account-card/switch-url-card'; +import ReclaimUrlCard from '.~/components/google-mc-account-card/reclaim-url-card'; +import AccountCard, { APPEARANCE } from '.~/components/account-card'; +import CreateAccountButton from '.~/components/google-mc-account-card/create-account-button'; +import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; +import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; +import CreatingCard from '.~/components/google-mc-account-card/creating-card'; +import './connect-mc.scss'; + +/** + * Clicking on the button to connect an existing Google Merchant Center account. + * + * @event gla_mc_account_connect_button_click + * @property {number} id The account ID to be connected. + */ + +/** + * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. + * + * @event gla_mc_account_switch_account_button_click + * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. + */ + +/** + * @fires gla_mc_account_connect_button_click + */ +const ConnectMC = () => { + const [ value, setValue ] = useState(); + const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); + const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + + if ( resultConnectMC.response?.status === 409 ) { + return ( + + ); + } + + if ( + resultConnectMC.response?.status === 403 || + resultCreateAccount.response?.status === 403 + ) { + return ( + { + resultConnectMC.reset(); + resultCreateAccount.reset(); + } } + /> + ); + } + + if ( + resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 + ) { + return ( + + ); + } + + return ( + + + + + + { __( 'Connect', 'google-listings-and-ads' ) } + + + + + + { __( + 'Or, create a new Merchant Center account', + 'google-listings-and-ads' + ) } + + + + ); +}; + +export default ConnectMC; diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.scss b/js/src/components/google-combo-account-card/connect-mc/connect-mc.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/components/google-combo-account-card/connect-mc/index.js b/js/src/components/google-combo-account-card/connect-mc/index.js new file mode 100644 index 0000000000..beaa2a40a4 --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-mc/index.js @@ -0,0 +1 @@ +export { default } from './connect-mc'; diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index d58944cd63..8d45ce3bf3 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -2,6 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { CardDivider } from '@wordpress/components'; /** * Internal dependencies @@ -13,6 +14,7 @@ import AppSpinner from '../app-spinner'; import useAutoCreateAdsMCAccounts from '../../hooks/useAutoCreateAdsMCAccounts'; import LoadingLabel from '../loading-label/loading-label'; import AccountCreationDescription from './account-creation-description'; +import ConnectMC from './connect-mc'; /** * Clicking on the "connect to a different Google account" button. @@ -46,10 +48,18 @@ const ConnectedGoogleComboAccountCard = () => { accountsCreated, } = useAutoCreateAdsMCAccounts(); + // if ( + // ! accountsCreated && + // ( ! hasFinishedResolutionForCurrentAdsAccount || + // ! hasFinishedResolutionForCurrentMCAccount || + // ! accountCreationChecksResolved ) + // ) { + // return } />; + // } + if ( ! accountsCreated && - ( ! hasFinishedResolutionForCurrentAdsAccount || - ! hasFinishedResolutionForCurrentMCAccount || + ( ! hasFinishedResolutionForCurrentMCAccount || ! accountCreationChecksResolved ) ) { return } />; @@ -83,25 +93,29 @@ const ConnectedGoogleComboAccountCard = () => { }; return ( - - } - helper={ getHelper() } - indicator={ getIndicator() } - /> +
+ + } + helper={ getHelper() } + indicator={ getIndicator() } + /> + + +
); }; diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index 4a1ea0932a..de30d2be3c 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -81,7 +81,7 @@ const useAutoCreateAdsMCAccounts = () => { }, [ createMCAccount, createAdsAccount ] ); const accountCreationChecksResolved = - initHasExistingAdsAccountsRef.current !== null && + // initHasExistingAdsAccountsRef.current !== null && initHasExistingMCAccountsRef.current !== null; const shouldCreateAdsAccount = diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.test.js b/js/src/hooks/useAutoCreateAdsMCAccounts.test.js index 152bd20f1e..2fdc806d34 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.test.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.test.js @@ -1,4 +1,3 @@ -/* eslint-disable testing-library/no-unnecessary-act */ /** * External dependencies */ @@ -81,13 +80,12 @@ describe( 'useAutoCreateAdsMCAccounts hook', () => { { loading: false }, ] ); - await act( async () => { - rerender(); // Trigger the effect that begins account creation - } ); + rerender(); expect( result.current.isCreatingAdsAccount ).toBe( false ); expect( result.current.isCreatingMCAccount ).toBe( false ); + // eslint-disable-next-line testing-library/no-unnecessary-act await act( async () => { rerender(); } ); @@ -119,10 +117,8 @@ describe( 'useAutoCreateAdsMCAccounts hook', () => { expect( result.current.isCreatingAdsAccount ).toBe( false ); expect( result.current.isCreatingMCAccount ).toBe( false ); - // Trigger the effect that starts account creation - await act( async () => { - rerender(); // Simulate the effect firing - } ); + // Trigger the effect that starts account creation. + rerender(); // Step 2: At this point, MC account creation should have started expect( result.current.isCreatingMCAccount ).toBe( true ); @@ -136,10 +132,8 @@ describe( 'useAutoCreateAdsMCAccounts hook', () => { { response: { status: 200 }, loading: false }, // Now account creation is complete ] ); - // Trigger a rerender to simulate the async function resolving - await act( async () => { - rerender(); // Re-render after response has been updated - } ); + // Trigger a rerender to simulate the async function resolving. + rerender(); // Step 4: Final assertions after account creation has completed expect( result.current.isCreatingAdsAccount ).toBe( false ); @@ -170,10 +164,7 @@ describe( 'useAutoCreateAdsMCAccounts hook', () => { expect( result.current.isCreatingAdsAccount ).toBe( false ); expect( result.current.isCreatingMCAccount ).toBe( false ); - // Trigger the effect that starts account creation - await act( async () => { - rerender(); // Simulate the effect firing - } ); + rerender(); // Simulate the effect firing. // Step 2: At this point, Ads account creation should have started expect( result.current.isCreatingAdsAccount ).toBe( true ); @@ -187,10 +178,8 @@ describe( 'useAutoCreateAdsMCAccounts hook', () => { { response: { status: 200 }, loading: false }, // Now Ads account creation is complete ] ); - // Trigger a rerender to simulate the async function resolving - await act( async () => { - rerender(); // Re-render after response has been updated - } ); + // Trigger a rerender to simulate the async function resolving. + rerender(); // Step 4: Final assertions after Ads account creation has completed expect( result.current.accountsCreated ).toBe( true ); // The account has been created diff --git a/js/src/setup-mc/setup-stepper/index.js b/js/src/setup-mc/setup-stepper/index.js index 2c35a06064..05cdb1d310 100644 --- a/js/src/setup-mc/setup-stepper/index.js +++ b/js/src/setup-mc/setup-stepper/index.js @@ -26,12 +26,12 @@ const SetupStepper = () => { const { status, step } = mcSetup; - if ( status === 'complete' ) { - getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); - return null; - } + // if ( status === 'complete' ) { + // getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); + // return null; + // } - return ; + return ; }; export default SetupStepper; From 442863972d9ae9422f65e96d9d670531ba8db433 Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 3 Oct 2024 21:51:43 +0400 Subject: [PATCH 02/69] Extract DisconnectAccount button. --- .../connect-mc/connect-mc.js | 78 ++++++++++------- .../connect-mc/connect-mc.scss | 0 .../connected-google-combo-account-card.js | 32 ++++--- .../connected-google-combo-account-card.scss | 24 +++++ .../connected-google-mc-account-card.js | 65 +------------- .../disconnect-account-button.js | 87 +++++++++++++++++++ 6 files changed, 181 insertions(+), 105 deletions(-) delete mode 100644 js/src/components/google-combo-account-card/connect-mc/connect-mc.scss create mode 100644 js/src/components/google-mc-account-card/disconnect-account-button.js diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 845a5bcac7..389e2ee186 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import { CardDivider } from '@wordpress/components'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -11,16 +10,17 @@ import { __ } from '@wordpress/i18n'; import MerchantCenterSelectControl from '.~/components/merchant-center-select-control'; import AppButton from '.~/components/app-button'; import Section from '.~/wcdl/section'; -import Subsection from '.~/wcdl/subsection'; import ContentButtonLayout from '.~/components/content-button-layout'; import SwitchUrlCard from '.~/components/google-mc-account-card/switch-url-card'; import ReclaimUrlCard from '.~/components/google-mc-account-card/reclaim-url-card'; -import AccountCard, { APPEARANCE } from '.~/components/account-card'; +import AccountCard from '.~/components/account-card'; import CreateAccountButton from '.~/components/google-mc-account-card/create-account-button'; import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; import CreatingCard from '.~/components/google-mc-account-card/creating-card'; -import './connect-mc.scss'; +import ConnectedIconLabel from '.~/components/connected-icon-label'; +import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; +import DisconnectAccountButton from '.~/components/google-mc-account-card/disconnect-account-button'; /** * Clicking on the button to connect an existing Google Merchant Center account. @@ -40,10 +40,19 @@ import './connect-mc.scss'; * @fires gla_mc_account_connect_button_click */ const ConnectMC = () => { + const { googleMCAccount } = useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + // MC is ready when we have a connection. + // The `link_ads` step will be resolved when the Ads account is connected + // since these can be connected in any order. + const isConnected = + googleMCAccount?.status === 'connected' || + ( googleMCAccount?.status === 'incomplete' && + googleMCAccount?.step === 'link_ads' ); + if ( resultConnectMC.response?.status === 409 ) { return ( { return ( - + - - { __( 'Connect', 'google-listings-and-ads' ) } - + + { isConnected && ( + + ) } + + { ! isConnected && ( + + { __( 'Connect', 'google-listings-and-ads' ) } + + ) } - - - { __( - 'Or, create a new Merchant Center account', - 'google-listings-and-ads' - ) } - + + { isConnected && } + + { ! isConnected && ( + + { __( + 'Or, create a new Merchant Center account', + 'google-listings-and-ads' + ) } + + ) } ); diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.scss b/js/src/components/google-combo-account-card/connect-mc/connect-mc.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 61f2631cec..6270e4decd 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -69,20 +69,24 @@ const ConnectedGoogleComboAccountCard = () => { }; return ( - - } - helper={ getHelper() } - indicator={ getIndicator() } - /> +
+ + } + helper={ getHelper() } + indicator={ getIndicator() } + /> + + +
); }; diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss index 991927082a..d1f80196f3 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss @@ -8,3 +8,27 @@ margin: 0; } } + +.gla-google-combo-service-connected-icon-label { + width: auto; +} + +.gla-google-combo-service-account-card { + padding: var(--large-gap); + + > div { + display: flex; + flex-direction: column; + gap: calc(var(--main-gap) / 2); + } + + .wcdl-section-card-body, + .gla-google-combo-service-account-card__body { + padding: 0; + } + + .gla-google-combo-service-account-card__footer { + border: 0; + padding: 0; + } +} diff --git a/js/src/components/google-mc-account-card/connected-google-mc-account-card.js b/js/src/components/google-mc-account-card/connected-google-mc-account-card.js index d17820903f..c4f67defd4 100644 --- a/js/src/components/google-mc-account-card/connected-google-mc-account-card.js +++ b/js/src/components/google-mc-account-card/connected-google-mc-account-card.js @@ -21,22 +21,16 @@ import useApiFetchCallback from '.~/hooks/useApiFetchCallback'; import { useAppDispatch } from '.~/data'; import EnableNewProductSyncButton from '.~/components/enable-new-product-sync-button'; import AppNotice from '.~/components/app-notice'; +import DisconnectAccountButton from './disconnect-account-button'; import DisconnectModal, { API_DATA_FETCH_FEATURE, } from '.~/settings/disconnect-modal'; import { getSettingsUrl } from '.~/utils/urls'; -/** - * Clicking on the "connect to a different Google Merchant Center account" button. - * - * @event gla_mc_account_connect_different_account_button_click - */ - /** * Renders a Google Merchant Center account card UI with connected account information. * It also provides a switch button that lets user connect with another account. * - * @fires gla_mc_account_connect_different_account_button_click * @param {Object} props React props. * @param {{ id: number }} props.googleMCAccount A data payload object containing the user's Google Merchant Center account ID. * @param {boolean} [props.hideAccountSwitch=false] Indicate whether hide the account switch block at the card footer. @@ -50,12 +44,6 @@ const ConnectedGoogleMCAccountCard = ( { const { createNotice, removeNotice } = useDispatchCoreNotices(); const { invalidateResolution } = useAppDispatch(); - const [ fetchGoogleMCDisconnect, { loading: loadingGoogleMCDisconnect } ] = - useApiFetchCallback( { - path: `${ API_NAMESPACE }/mc/connection`, - method: 'DELETE', - } ); - const [ fetchDisableNotifications, { loading: loadingDisableNotifications }, @@ -74,43 +62,6 @@ const ConnectedGoogleMCAccountCard = ( { const domain = new URL( getSetting( 'homeUrl' ) ).host; - /** - * Event handler to switch GMC account. Upon click, it will: - * - * 1. Display a notice to indicate disconnection in progress, and advise users to wait. - * 2. Call API to disconnect the current connected GMC account. - * 3. Call API to refetch list of GMC accounts. - * Users may have just created a new account, - * and we want that new account to show up in the list. - * 4. Call API to refetch GMC account connection status. - * 5. If there is an error in the above API calls, display an error notice. - */ - const handleSwitch = async () => { - const { notice } = await createNotice( - 'info', - __( - 'Disconnecting your Google Merchant Center account, please wait…', - 'google-listings-and-ads' - ) - ); - - try { - await fetchGoogleMCDisconnect(); - invalidateResolution( 'getExistingGoogleMCAccounts', [] ); - invalidateResolution( 'getGoogleMCAccount', [] ); - } catch ( error ) { - createNotice( - 'error', - __( - 'Unable to disconnect your Google Merchant Center account. Please try again later.', - 'google-listings-and-ads' - ) - ); - } - - removeNotice( notice.id ); - }; - const disableNotifications = async () => { const { notice } = await createNotice( 'info', @@ -204,18 +155,8 @@ const ConnectedGoogleMCAccountCard = ( { { showFooter && ( - { ! hideAccountSwitch && ( - - ) } + { ! hideAccountSwitch && } + { showDisconnectNotificationsButton && ( { + const { createNotice, removeNotice } = useDispatchCoreNotices(); + const { invalidateResolution } = useAppDispatch(); + + const [ fetchGoogleMCDisconnect, { loading: loadingGoogleMCDisconnect } ] = + useApiFetchCallback( { + path: `${ API_NAMESPACE }/mc/connection`, + method: 'DELETE', + } ); + + /** + * Event handler to switch GMC account. Upon click, it will: + * + * 1. Display a notice to indicate disconnection in progress, and advise users to wait. + * 2. Call API to disconnect the current connected GMC account. + * 3. Call API to refetch list of GMC accounts. + * Users may have just created a new account, + * and we want that new account to show up in the list. + * 4. Call API to refetch GMC account connection status. + * 5. If there is an error in the above API calls, display an error notice. + */ + const handleSwitch = async () => { + const { notice } = await createNotice( + 'info', + __( + 'Disconnecting your Google Merchant Center account, please wait…', + 'google-listings-and-ads' + ) + ); + + try { + await fetchGoogleMCDisconnect(); + invalidateResolution( 'getExistingGoogleMCAccounts', [] ); + invalidateResolution( 'getGoogleMCAccount', [] ); + } catch ( error ) { + createNotice( + 'error', + __( + 'Unable to disconnect your Google Merchant Center account. Please try again later.', + 'google-listings-and-ads' + ) + ); + } + + removeNotice( notice.id ); + }; + + return ( + + ); +}; + +export default DisconnectAccountButton; From bebfaed03ae569d9ef898fba0faa88740d118a3f Mon Sep 17 00:00:00 2001 From: asvinb Date: Fri, 4 Oct 2024 12:15:28 +0400 Subject: [PATCH 03/69] Add ConnectAccountCard component. --- .../connect-account-card.js | 34 ++++++++++++++ .../connect-account-card.scss | 19 ++++++++ .../connect-mc/connect-mc.js | 45 +++++++++---------- .../connected-google-combo-account-card.scss | 20 --------- 4 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 js/src/components/google-combo-account-card/connect-account-card.js create mode 100644 js/src/components/google-combo-account-card/connect-account-card.scss diff --git a/js/src/components/google-combo-account-card/connect-account-card.js b/js/src/components/google-combo-account-card/connect-account-card.js new file mode 100644 index 0000000000..b1a44345e1 --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-account-card.js @@ -0,0 +1,34 @@ +/** + * Internal dependencies + */ +import Section from '.~/wcdl/section'; +import AccountCard from '.~/components/account-card'; +import './connect-account-card.scss'; + +/** + * ConnectAccountCard component renders an account card with a title, helper text, body, and footer sections. + * + * @param {Object} props The component properties. + * @param {string} props.title The title of the account card. + * @param {string} props.helperText The helper text for the account card. + * @param {JSX.Element} props.body The content for the body of the account card. + * @param {JSX.Element} props.footer The content for the footer of the account card. + */ +const ConnectAccountCard = ( { title, helperText, body, footer } ) => { + return ( + + + { body } + + + { footer } + + + ); +}; + +export default ConnectAccountCard; diff --git a/js/src/components/google-combo-account-card/connect-account-card.scss b/js/src/components/google-combo-account-card/connect-account-card.scss new file mode 100644 index 0000000000..de33c405e3 --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-account-card.scss @@ -0,0 +1,19 @@ +.gla-google-combo-connect-account-card { + padding: var(--large-gap); + + > div { + display: flex; + flex-direction: column; + gap: calc(var(--main-gap) / 2); + } + + .wcdl-section-card-body, + .gla-google-combo-connect-account-card__body { + padding: 0; + } + + .gla-google-combo-connect-account-card__footer { + border: 0; + padding: 0; + } +} diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 389e2ee186..259da8d702 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -9,11 +9,9 @@ import { __ } from '@wordpress/i18n'; */ import MerchantCenterSelectControl from '.~/components/merchant-center-select-control'; import AppButton from '.~/components/app-button'; -import Section from '.~/wcdl/section'; import ContentButtonLayout from '.~/components/content-button-layout'; import SwitchUrlCard from '.~/components/google-mc-account-card/switch-url-card'; import ReclaimUrlCard from '.~/components/google-mc-account-card/reclaim-url-card'; -import AccountCard from '.~/components/account-card'; import CreateAccountButton from '.~/components/google-mc-account-card/create-account-button'; import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; @@ -21,6 +19,7 @@ import CreatingCard from '.~/components/google-mc-account-card/creating-card'; import ConnectedIconLabel from '.~/components/connected-icon-label'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import DisconnectAccountButton from '.~/components/google-mc-account-card/disconnect-account-button'; +import ConnectAccountCard from '../connect-account-card'; /** * Clicking on the button to connect an existing Google Merchant Center account. @@ -99,8 +98,7 @@ const ConnectMC = () => { } return ( - { 'Required to sync products so they show on Google.', 'google-listings-and-ads' ) } - > - + body={ { ) } - - - { isConnected && } + } + footer={ + <> + { isConnected && } - { ! isConnected && ( - - { __( - 'Or, create a new Merchant Center account', - 'google-listings-and-ads' - ) } - - ) } - -
+ { ! isConnected && ( + + { __( + 'Or, create a new Merchant Center account', + 'google-listings-and-ads' + ) } + + ) } + + } + /> ); }; diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss index d1f80196f3..25fd917a68 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss @@ -12,23 +12,3 @@ .gla-google-combo-service-connected-icon-label { width: auto; } - -.gla-google-combo-service-account-card { - padding: var(--large-gap); - - > div { - display: flex; - flex-direction: column; - gap: calc(var(--main-gap) / 2); - } - - .wcdl-section-card-body, - .gla-google-combo-service-account-card__body { - padding: 0; - } - - .gla-google-combo-service-account-card__footer { - border: 0; - padding: 0; - } -} From 872787ee4d2c71e90c66b796343a191c4386ec2b Mon Sep 17 00:00:00 2001 From: asvinb Date: Fri, 4 Oct 2024 13:34:40 +0400 Subject: [PATCH 04/69] Add ConnectMCBody and ConnectMCFooter component. --- .../connect-mc/connect-mc-body.js | 71 +++++++++++++++++++ .../connect-mc/connect-mc-footer.js | 47 ++++++++++++ .../connect-mc/connect-mc.js | 69 ++++-------------- 3 files changed, 132 insertions(+), 55 deletions(-) create mode 100644 js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js create mode 100644 js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js new file mode 100644 index 0000000000..4d8d6a53b5 --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js @@ -0,0 +1,71 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import MerchantCenterSelectControl from '.~/components/merchant-center-select-control'; +import AppButton from '.~/components/app-button'; +import ContentButtonLayout from '.~/components/content-button-layout'; +import ConnectedIconLabel from '.~/components/connected-icon-label'; + +/** + * Clicking on the button to connect an existing Google Merchant Center account. + * + * @event gla_mc_account_connect_button_click + * @property {number} id The account ID to be connected. + */ + +/** + * ConnectMCBody component. + * + * This component renders the body section for the Merchant Center connection. + * It displays a selection control for choosing an account, and conditionally renders + * a connected status icon or a button to connect to the selected Merchant Center account. + * + * @param {Object} props + * @param {string} props.value The selected Merchant Center account ID. + * @param {Function} props.setValue Callback to update the selected account value. + * @param {boolean} props.isConnected Whether the Merchant Center account is connected. + * @param {Function} props.handleConnectMC Callback function to handle the connection process. + * @param {Object} props.resultConnectMC The result of the connection request, used to handle loading state. + * + * @fires gla_mc_account_connect_button_click + */ +const ConnectMCBody = ( { + value, + setValue, + isConnected, + handleConnectMC, + resultConnectMC, +} ) => { + return ( + + + + { isConnected && ( + + ) } + + { ! isConnected && ( + + { __( 'Connect', 'google-listings-and-ads' ) } + + ) } + + ); +}; + +export default ConnectMCBody; diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js new file mode 100644 index 0000000000..3fdd7a8d7f --- /dev/null +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import CreateAccountButton from '.~/components/google-mc-account-card/create-account-button'; +import DisconnectAccountButton from '.~/components/google-mc-account-card/disconnect-account-button'; + +/** + * ConnectMCFooter component. + * + * This component renders the footer for the Merchant Center connection section. + * It conditionally renders either a button to disconnect the account if already + * connected, or a button to create a new Merchant Center account. + * + * @param {Object} props + * @param {boolean} props.isConnected Whether the Merchant Center account is connected. + * @param {Object} props.resultConnectMC The result of the connection request, used to handle loading state. + * @param {Function} props.handleCreateAccount Callback function for creating a new Merchant Center account. + */ +const ConnectMCFooter = ( { + isConnected, + resultConnectMC, + handleCreateAccount, +} ) => { + if ( isConnected ) { + return ; + } + + return ( + + { __( + 'Or, create a new Merchant Center account', + 'google-listings-and-ads' + ) } + + ); +}; + +export default ConnectMCFooter; diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 259da8d702..0c208a3faa 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -7,26 +7,15 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import MerchantCenterSelectControl from '.~/components/merchant-center-select-control'; -import AppButton from '.~/components/app-button'; -import ContentButtonLayout from '.~/components/content-button-layout'; import SwitchUrlCard from '.~/components/google-mc-account-card/switch-url-card'; import ReclaimUrlCard from '.~/components/google-mc-account-card/reclaim-url-card'; -import CreateAccountButton from '.~/components/google-mc-account-card/create-account-button'; import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; import CreatingCard from '.~/components/google-mc-account-card/creating-card'; -import ConnectedIconLabel from '.~/components/connected-icon-label'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; -import DisconnectAccountButton from '.~/components/google-mc-account-card/disconnect-account-button'; import ConnectAccountCard from '../connect-account-card'; - -/** - * Clicking on the button to connect an existing Google Merchant Center account. - * - * @event gla_mc_account_connect_button_click - * @property {number} id The account ID to be connected. - */ +import ConnectMCBody from './connect-mc-body'; +import ConnectMCFooter from './connect-mc-footer'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -35,9 +24,6 @@ import ConnectAccountCard from '../connect-account-card'; * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. */ -/** - * @fires gla_mc_account_connect_button_click - */ const ConnectMC = () => { const { googleMCAccount } = useGoogleMCAccount(); const [ value, setValue ] = useState(); @@ -108,47 +94,20 @@ const ConnectMC = () => { 'google-listings-and-ads' ) } body={ - - - - { isConnected && ( - - ) } - - { ! isConnected && ( - - { __( 'Connect', 'google-listings-and-ads' ) } - - ) } - + } footer={ - <> - { isConnected && } - - { ! isConnected && ( - - { __( - 'Or, create a new Merchant Center account', - 'google-listings-and-ads' - ) } - - ) } - + } /> ); From 9475ec26d0f032f8a77947e756b767aa5c454f4c Mon Sep 17 00:00:00 2001 From: asvinb Date: Mon, 7 Oct 2024 15:46:41 +0400 Subject: [PATCH 05/69] Save WIP. --- .../connect-mc/connect-mc-body.js | 25 ++++++++++++++++--- .../connect-mc/connect-mc.js | 2 +- .../connected-google-combo-account-card.scss | 4 +++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js index 4d8d6a53b5..8cdda78d36 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js @@ -10,6 +10,7 @@ import MerchantCenterSelectControl from '.~/components/merchant-center-select-co import AppButton from '.~/components/app-button'; import ContentButtonLayout from '.~/components/content-button-layout'; import ConnectedIconLabel from '.~/components/connected-icon-label'; +import LoadingLabel from '.~/components/loading-label'; /** * Clicking on the button to connect an existing Google Merchant Center account. @@ -29,8 +30,8 @@ import ConnectedIconLabel from '.~/components/connected-icon-label'; * @param {string} props.value The selected Merchant Center account ID. * @param {Function} props.setValue Callback to update the selected account value. * @param {boolean} props.isConnected Whether the Merchant Center account is connected. + * @param {boolean} props.isConnecting Whether the Merchant Center account is being connected. * @param {Function} props.handleConnectMC Callback function to handle the connection process. - * @param {Object} props.resultConnectMC The result of the connection request, used to handle loading state. * * @fires gla_mc_account_connect_button_click */ @@ -38,24 +39,40 @@ const ConnectMCBody = ( { value, setValue, isConnected, + isConnecting, handleConnectMC, - resultConnectMC, } ) => { + let selectControlProps = {}; + if ( isConnected ) { + selectControlProps = { + suffix: ' ', + tabIndex: '-1', + readOnly: true, + className: 'gla-google-combo-service-select-control--connected', + }; + } + return ( { isConnected && ( ) } - { ! isConnected && ( + { isConnecting && ( + + ) } + + { ! isConnected && ! isConnecting && ( { value={ value } setValue={ setValue } isConnected={ isConnected } - resultConnectMC={ resultConnectMC } + isConnecting={ resultConnectMC.loading } handleConnectMC={ handleConnectMC } /> } diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss index 25fd917a68..bdef941166 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss @@ -12,3 +12,7 @@ .gla-google-combo-service-connected-icon-label { width: auto; } + +.gla-google-combo-service-select-control--connected { + pointer-events: none; +} From 396523427ee43060d485d7b54a081029bf2421db Mon Sep 17 00:00:00 2001 From: asvinb Date: Mon, 7 Oct 2024 17:37:12 +0400 Subject: [PATCH 06/69] Check for non connected state. --- .../connect-mc/connect-mc.js | 20 +++++++++++++------ .../connected-google-combo-account-card.js | 1 - 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 607b37dd5e..8a75264d02 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -16,6 +16,7 @@ import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectAccountCard from '../connect-account-card'; import ConnectMCBody from './connect-mc-body'; import ConnectMCFooter from './connect-mc-footer'; +import SpinnerCard from '.~/components/spinner-card'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -25,7 +26,7 @@ import ConnectMCFooter from './connect-mc-footer'; */ const ConnectMC = () => { - const { googleMCAccount } = useGoogleMCAccount(); + const { googleMCAccount, hasFinishedResolution } = useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); @@ -34,11 +35,12 @@ const ConnectMC = () => { // The `link_ads` step will be resolved when the Ads account is connected // since these can be connected in any order. const isConnected = + googleMCAccount?.id || googleMCAccount?.status === 'connected' || ( googleMCAccount?.status === 'incomplete' && googleMCAccount?.step === 'link_ads' ); - if ( resultConnectMC.response?.status === 409 ) { + if ( ! isConnected && resultConnectMC.response?.status === 409 ) { return ( { } if ( - resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 + ! isConnected && + ( resultConnectMC.response?.status === 403 || + resultCreateAccount.response?.status === 403 ) ) { return ( { } if ( - resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 + ! isConnected && + ( resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 ) ) { return ( { ); } + if ( ! hasFinishedResolution ) { + return ; + } + return ( Date: Mon, 7 Oct 2024 17:42:19 +0400 Subject: [PATCH 07/69] Add preConditionReady check. --- .../google-combo-account-card/connect-account-card.js | 10 +++++++++- .../google-combo-account-card/connect-mc/connect-mc.js | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-account-card.js b/js/src/components/google-combo-account-card/connect-account-card.js index b1a44345e1..439869853a 100644 --- a/js/src/components/google-combo-account-card/connect-account-card.js +++ b/js/src/components/google-combo-account-card/connect-account-card.js @@ -13,13 +13,21 @@ import './connect-account-card.scss'; * @param {string} props.helperText The helper text for the account card. * @param {JSX.Element} props.body The content for the body of the account card. * @param {JSX.Element} props.footer The content for the footer of the account card. + * @param {boolean} [props.disabled=false] Whether display the Card in disabled style. */ -const ConnectAccountCard = ( { title, helperText, body, footer } ) => { +const ConnectAccountCard = ( { + title, + helperText, + body, + footer, + disabled = false, +} ) => { return ( { body } diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 8a75264d02..63aeec0858 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -26,7 +26,8 @@ import SpinnerCard from '.~/components/spinner-card'; */ const ConnectMC = () => { - const { googleMCAccount, hasFinishedResolution } = useGoogleMCAccount(); + const { googleMCAccount, hasFinishedResolution, isPreconditionReady } = + useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); @@ -117,6 +118,7 @@ const ConnectMC = () => { handleCreateAccount={ handleCreateAccount } /> } + disabled={ ! isPreconditionReady } /> ); }; From 8b850fd1bae2b154c6dc45cce4f552d083858049 Mon Sep 17 00:00:00 2001 From: asvinb Date: Mon, 7 Oct 2024 17:51:29 +0400 Subject: [PATCH 08/69] Revert dev temp changes. --- js/src/hooks/useAutoCreateAdsMCAccounts.js | 2 +- js/src/setup-mc/setup-stepper/index.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index de30d2be3c..4a1ea0932a 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -81,7 +81,7 @@ const useAutoCreateAdsMCAccounts = () => { }, [ createMCAccount, createAdsAccount ] ); const accountCreationChecksResolved = - // initHasExistingAdsAccountsRef.current !== null && + initHasExistingAdsAccountsRef.current !== null && initHasExistingMCAccountsRef.current !== null; const shouldCreateAdsAccount = diff --git a/js/src/setup-mc/setup-stepper/index.js b/js/src/setup-mc/setup-stepper/index.js index 05cdb1d310..2c35a06064 100644 --- a/js/src/setup-mc/setup-stepper/index.js +++ b/js/src/setup-mc/setup-stepper/index.js @@ -26,12 +26,12 @@ const SetupStepper = () => { const { status, step } = mcSetup; - // if ( status === 'complete' ) { - // getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); - // return null; - // } + if ( status === 'complete' ) { + getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); + return null; + } - return ; + return ; }; export default SetupStepper; From 176a4a8c870846c71a12eb3eb7e14e7d95303d1b Mon Sep 17 00:00:00 2001 From: asvinb Date: Mon, 7 Oct 2024 20:35:15 +0400 Subject: [PATCH 09/69] Save E2E tests, --- .../connect-account-card.js | 12 +++- .../connect-mc/connect-mc.js | 1 + .../specs/setup-mc/step-1-accounts.test.js | 72 +++++++++++++------ .../pages/setup-mc/step-1-set-up-accounts.js | 11 +-- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-account-card.js b/js/src/components/google-combo-account-card/connect-account-card.js index 439869853a..ab28b40235 100644 --- a/js/src/components/google-combo-account-card/connect-account-card.js +++ b/js/src/components/google-combo-account-card/connect-account-card.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classNames from 'classnames'; + /** * Internal dependencies */ @@ -14,6 +19,7 @@ import './connect-account-card.scss'; * @param {JSX.Element} props.body The content for the body of the account card. * @param {JSX.Element} props.footer The content for the footer of the account card. * @param {boolean} [props.disabled=false] Whether display the Card in disabled style. + * @param {string} [props.className] Additional class names to apply to the card. */ const ConnectAccountCard = ( { title, @@ -21,10 +27,14 @@ const ConnectAccountCard = ( { body, footer, disabled = false, + className, } ) => { return ( { return ( { await setupAdsAccountPage.fulfillAdsAccounts( [ [], - { - id: 78787878, - name: 'gla', - }, + [ + { + id: 78787878, + name: 'gla', + }, + ], ], 200, [ 'GET' ] @@ -254,12 +256,14 @@ test.describe( 'Set up accounts', () => { await setupAdsAccountPage.fulfillMCAccounts( [ [], - { - id: 5432178, - name: null, - subaccount: null, - domain: null, - }, + [ + { + id: 5432178, + name: null, + subaccount: null, + domain: null, + }, + ], ], 200, 'GET' @@ -339,10 +343,12 @@ test.describe( 'Set up accounts', () => { await setupAdsAccountPage.fulfillAdsAccounts( [ [], - { - id: 78787878, - name: 'gla', - }, + [ + { + id: 78787878, + name: 'gla', + }, + ], ], 200, [ 'GET' ] @@ -351,12 +357,14 @@ test.describe( 'Set up accounts', () => { await setupAdsAccountPage.fulfillMCAccounts( [ [], - { - id: 5432178, - name: null, - subaccount: null, - domain: null, - }, + [ + { + id: 5432178, + name: null, + subaccount: null, + domain: null, + }, + ], ], 200, 'GET' @@ -407,6 +415,30 @@ test.describe( 'Set up accounts', () => { } ); } ); + test.describe( 'Google Merchant Center card', () => { + test.beforeAll( async () => { + await setUpAccountsPage.mockJetpackConnected(); + await setUpAccountsPage.mockAdsAccountConnected(); + await setUpAccountsPage.mockMCHasAccounts(); + await setUpAccountsPage.mockMCNotConnected(); + await setUpAccountsPage.mockGoogleConnected(); + await setUpAccountsPage.mockAdsAccountConnected(); + await setUpAccountsPage.goto(); + } ); + + test( 'should be prompted to connect to an existing MC account', async () => { + const googleMCAccountCard = setUpAccountsPage.getMCAccountCard(); + console.log( 'ZOPE', googleMCAccountCard ); + + await expect( + googleMCAccountCard.getByText( + 'Connect to existing Merchant Center account', + { exact: true } + ) + ).toBeVisible(); + } ); + } ); + test.describe( 'Continue button', () => { test.beforeAll( async () => { // Mock Jetpack as connected diff --git a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js index 1876de366c..da5aa6555c 100644 --- a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js +++ b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js @@ -226,7 +226,7 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get account cards. */ getAccountCards( options = {} ) { - return this.page.locator( '.gla-account-card', options ); + return this.page.locator( '.gla-google-combo-account-card', options ); } /** @@ -271,9 +271,12 @@ export default class SetUpAccountsPage extends MockRequests { */ getMCAccountCard() { return this.getAccountCards( { - has: this.page.locator( '.gla-account-card__title', { - hasText: 'Google Merchant Center', - } ), + has: this.page.locator( + '.gla-google-combo-service-account-card--merchant-center', + { + hasText: 'Merchant Center', + } + ), } ).first(); } From e9626f0fbca40657843b3c2fba33669bf4fc1b9c Mon Sep 17 00:00:00 2001 From: asvinb Date: Tue, 8 Oct 2024 11:28:00 +0400 Subject: [PATCH 10/69] Save WIP. --- .../connect-mc/connect-mc.js | 2 +- .../connected-google-combo-account-card.js | 2 +- .../specs/setup-mc/step-1-accounts.test.js | 503 +++++++++++++++++- .../pages/setup-mc/step-1-set-up-accounts.js | 15 +- 4 files changed, 493 insertions(+), 29 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 70a5baf877..ffbb2f2de6 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -94,7 +94,7 @@ const ConnectMC = () => { return ( { }; return ( -
+
{ test.beforeAll( async ( { browser } ) => { page = await browser.newPage(); @@ -415,30 +432,482 @@ test.describe( 'Set up accounts', () => { } ); } ); - test.describe( 'Google Merchant Center card', () => { + test.describe( 'Connect Merchant Center account', () => { + // test.beforeAll( async () => { + // await Promise.all( [ + // // Mock Jetpack as connected. + // setUpAccountsPage.mockJetpackConnected( + // 'Test user', + // 'jetpack@example.com' + // ), + + // // Mock google as connected. + // setUpAccountsPage.mockGoogleConnected( 'google@example.com' ), + + // // Mock Google Ads as connected. + // setUpAccountsPage.fulfillAdsAccounts( [ + // [ + // { + // id: 111111, + // name: 'gla', + // }, + // { + // id: 222222, + // name: 'gla', + // }, + // { + // id: 333333, + // name: 'gla', + // }, + // ], + // ] ), + // setupAdsAccountPage.mockAdsAccountConnected(), + // setUpAccountsPage.fulfillMCAccounts( [ + // [ + // { + // id: 12345, + // subaccount: true, + // name: 'MC Account 1', + // domain: 'https://example.com', + // }, + // { + // id: 23456, + // subaccount: true, + // name: 'MC Account 2', + // domain: 'https://example.com', + // }, + // ], + // ] ), + + // // Mock merchant center as not connected. + // setUpAccountsPage.mockMCNotConnected(), + // ] ); + // } ); test.beforeAll( async () => { - await setUpAccountsPage.mockJetpackConnected(); - await setUpAccountsPage.mockAdsAccountConnected(); - await setUpAccountsPage.mockMCHasAccounts(); - await setUpAccountsPage.mockMCNotConnected(); - await setUpAccountsPage.mockGoogleConnected(); - await setUpAccountsPage.mockAdsAccountConnected(); - await setUpAccountsPage.goto(); + await Promise.all( [ + // Mock Jetpack as connected. + setUpAccountsPage.mockJetpackConnected( + 'Test user', + 'jetpack@example.com' + ), + + // Mock google as connected. + setUpAccountsPage.mockGoogleConnected( 'google@example.com' ), + + // Mock Google Ads as connected. + setUpAccountsPage.mockAdsAccountConnected(), + setUpAccountsPage.mockAdsStatusClaimed(), + + // Mock merchant center as not connected. + setUpAccountsPage.mockMCNotConnected(), + ] ); } ); - test( 'should be prompted to connect to an existing MC account', async () => { - const googleMCAccountCard = setUpAccountsPage.getMCAccountCard(); - console.log( 'ZOPE', googleMCAccountCard ); + // test.describe( 'Merchant Center has no existing accounts', () => { + // test.beforeAll( async () => { + // // Mock merchant center has no accounts + // await setUpAccountsPage.mockAdsAccountsResponse( ADS_ACCOUNTS ); + // await setUpAccountsPage.mockMCHasAccounts(); + // await setUpAccountsPage.goto(); + // } ); + + // test( 'should see their Google email, "Google Merchant Center" title & "Create account" button', async () => { + // const googleDescriptionRow = + // setUpAccountsPage.getGoogleDescriptionRow(); + // await expect( googleDescriptionRow ).toContainText( + // 'google@example.com' + // ); + + // const mcTitleRow = setUpAccountsPage.getMCTitleRow(); + // await expect( mcTitleRow ).toContainText( + // 'Connect to existing Merchant Center account' + // ); + + // const createAccountButton = + // setUpAccountsPage.getMCCreateAccountButtonFromPage(); + // await expect( createAccountButton ).toBeEnabled(); + + // const continueButton = setUpAccountsPage.getContinueButton(); + // await expect( continueButton ).toBeDisabled(); + // } ); + + // test( 'click "Create account" button should see the modal of confirmation of creating account', async () => { + // // Click the create account button + // const createAccountButton = + // setUpAccountsPage.getMCCreateAccountButtonFromPage(); + // await createAccountButton.click(); + // await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + + // const modalHeader = setUpAccountsPage.getModalHeader(); + // await expect( modalHeader ).toContainText( + // 'Create Google Merchant Center Account' + // ); + + // const modalCheckbox = setUpAccountsPage.getModalCheckbox(); + // await expect( modalCheckbox ).toBeEnabled(); + + // const createAccountButtonFromModal = + // setUpAccountsPage.getMCCreateAccountButtonFromModal(); + // await expect( createAccountButtonFromModal ).toBeDisabled(); + + // // Click the checkbox of accepting ToS, the create account button will be enabled. + // await modalCheckbox.click(); + // await expect( createAccountButtonFromModal ).toBeEnabled(); + // } ); + + // test.describe( 'click "Create account" button from the modal', () => { + // test( 'should see Merchant Center "Connected" when the website is not claimed', async ( { + // baseURL, + // } ) => { + // await Promise.all( [ + // // Mock Merchant Center create accounts + // setUpAccountsPage.mockMCCreateAccountWebsiteNotClaimed(), + + // // Mock Merchant Center as connected with ID 12345 + // setUpAccountsPage.mockMCConnected( 12345 ), + // ] ); + + // const createAccountButtonFromModal = + // setUpAccountsPage.getMCCreateAccountButtonFromModal(); + // await createAccountButtonFromModal.click(); + // await page.waitForLoadState( + // LOAD_STATE.DOM_CONTENT_LOADED + // ); + // const mcConnectedLabel = + // setUpAccountsPage.getMCConnectedLabel(); + // await expect( mcConnectedLabel ).toContainText( + // 'Connected' + // ); + + // const host = new URL( baseURL ).host; + // const mcDescriptionRow = + // setUpAccountsPage.getMCDescriptionRow(); + // await expect( mcDescriptionRow ).toContainText( + // `${ host } (12345)` + // ); + // } ); + + // test.describe( 'when the website is already claimed', () => { + // test( 'should see "Reclaim my URL" button, "Switch account" button, and site URL input', async ( { + // baseURL, + // } ) => { + // const host = new URL( baseURL ).host; + + // await Promise.all( [ + // // Mock merchant center has no accounts + // setUpAccountsPage.mockMCHasNoAccounts(), + + // // Mock Merchant Center as not connected + // setUpAccountsPage.mockMCNotConnected(), + // ] ); + + // await page.reload(); + + // // Mock Merchant Center create accounts + // await setUpAccountsPage.mockMCCreateAccountWebsiteClaimed( + // 12345, + // host + // ); + + // // Click "Create account" button from the page. + // const createAccountButton = + // setUpAccountsPage.getMCCreateAccountButtonFromPage(); + // await createAccountButton.click(); + // await page.waitForLoadState( + // LOAD_STATE.DOM_CONTENT_LOADED + // ); + + // // Check the checkbox to accept ToS. + // const modalCheckbox = + // setUpAccountsPage.getModalCheckbox(); + // await modalCheckbox.click(); + + // // Click "Create account" button from the modal. + // const createAccountButtonFromModal = + // setUpAccountsPage.getMCCreateAccountButtonFromModal(); + // await createAccountButtonFromModal.click(); + // await page.waitForLoadState( + // LOAD_STATE.DOM_CONTENT_LOADED + // ); + + // const reclaimButton = + // setUpAccountsPage.getReclaimMyURLButton(); + // await expect( reclaimButton ).toBeVisible(); + + // const switchAccountButton = + // setUpAccountsPage.getSwitchAccountButton(); + // await expect( switchAccountButton ).toBeVisible(); + + // const reclaimingURLInput = + // setUpAccountsPage.getReclaimingURLInput(); + // await expect( reclaimingURLInput ).toHaveValue( + // baseURL + // ); + + // const continueButton = + // setUpAccountsPage.getContinueButton(); + // await expect( continueButton ).toBeDisabled(); + // } ); + + // test( 'click "Reclaim my URL" should send a claim overwrite request and see Merchant Center "Connected"', async ( { + // baseURL, + // } ) => { + // await Promise.all( [ + // // Mock Merchant Center accounts claim overwrite + // setUpAccountsPage.mockMCAccountsClaimOverwrite( + // 12345 + // ), + + // // Mock Merchant Center as connected with ID 12345 + // setUpAccountsPage.mockMCConnected( 12345 ), + // ] ); + + // const reclaimButton = + // setUpAccountsPage.getReclaimMyURLButton(); + // await reclaimButton.click(); + // await page.waitForLoadState( + // LOAD_STATE.DOM_CONTENT_LOADED + // ); + + // const mcConnectedLabel = + // setUpAccountsPage.getMCConnectedLabel(); + // await expect( mcConnectedLabel ).toContainText( + // 'Connected' + // ); + + // const host = new URL( baseURL ).host; + // const mcDescriptionRow = + // setUpAccountsPage.getMCDescriptionRow(); + // await expect( mcDescriptionRow ).toContainText( + // `${ host } (12345)` + // ); + // } ); + // } ); + // } ); + // } ); + + test.describe( 'Merchant Center has existing accounts', () => { + test.beforeAll( async () => { + await Promise.all( [ + setUpAccountsPage.mockAdsAccountsResponse( [ + ADS_ACCOUNTS, + ] ), + + // Mock merchant center as not connected. + setUpAccountsPage.mockMCNotConnected(), + + // Mock merchant center has accounts + setUpAccountsPage.fulfillMCAccounts( [ + [ + { + id: 12345, + subaccount: true, + name: 'MC Account 1', + domain: 'https://example.com', + }, + { + id: 23456, + subaccount: true, + name: 'MC Account 2', + domain: 'https://example.com', + }, + ], + ] ), + ] ); + + await setUpAccountsPage.goto(); + } ); - await expect( - googleMCAccountCard.getByText( - 'Connect to existing Merchant Center account', - { exact: true } - ) - ).toBeVisible(); + test.describe( 'connect to an existing account', () => { + test( 'should see "Select an existing account" title', async () => { + const selectAccountTitle = + setUpAccountsPage.getSelectExistingMCAccountTitle(); + await expect( selectAccountTitle ).toContainText( + 'Select an existing account' + ); + } ); + + test( 'should see "Or, create a new Merchant Center account" text', async () => { + const mcFooter = setUpAccountsPage.getMCCardFooter(); + await expect( mcFooter ).toContainText( + 'Or, create a new Merchant Center account' + ); + } ); + + test( 'should see "Connect" button', async () => { + const connectButton = setUpAccountsPage.getConnectButton(); + await expect( connectButton ).toBeEnabled(); + } ); + + test( 'should see "Continue" button is disabled', async () => { + const continueButton = + setUpAccountsPage.getContinueButton(); + await expect( continueButton ).toBeDisabled(); + } ); + + test( 'select MC Account 2 and click "Connect" button should see Merchant Center "Connected"', async ( { + baseURL, + } ) => { + await Promise.all( [ + // Mock Merchant Center create accounts + setUpAccountsPage.mockMCCreateAccountWebsiteNotClaimed(), + + // Mock Merchant Center as connected with ID 12345 + setUpAccountsPage.mockMCConnected( 23456 ), + ] ); + + // Select MC Account 2 from the options + const mcAccountsSelect = + setUpAccountsPage.getMCAccountsSelect(); + await mcAccountsSelect.selectOption( { + label: 'MC Account 2 ・ https://example.com (23456)', + } ); + + // Click connect button + const connectButton = setUpAccountsPage.getConnectButton(); + await connectButton.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + + const mcConnectedLabel = + setUpAccountsPage.getMCConnectedLabel(); + await expect( mcConnectedLabel ).toContainText( + 'Connected' + ); + + const host = new URL( baseURL ).host; + const mcDescriptionRow = + setUpAccountsPage.getMCDescriptionRow(); + await expect( mcDescriptionRow ).toContainText( + `${ host } (23456)` + ); + } ); + } ); + + test.describe( 'click "Or, create a new Merchant Center account"', () => { + test.beforeAll( async () => { + await Promise.all( [ + // Mock merchant center as not connected. + setUpAccountsPage.mockMCNotConnected(), + + // Mock merchant center has accounts + setUpAccountsPage.fulfillMCAccounts( [ + { + id: 12345, + subaccount: true, + name: 'MC Account 1', + domain: 'https://example.com', + }, + { + id: 23456, + subaccount: true, + name: 'MC Account 2', + domain: 'https://example.com', + }, + ] ), + ] ); + + await setUpAccountsPage.goto(); + } ); + + test( 'should see see a modal to ensure the intention of creating a new account', async () => { + // Click 'Or, create a new Merchant Center account' + const mcFooterButton = + setUpAccountsPage.getMCCardFooterButton(); + await mcFooterButton.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + + const modalHeader = setUpAccountsPage.getModalHeader(); + await expect( modalHeader ).toContainText( + 'Create Google Merchant Center Account' + ); + + const modalCheckbox = setUpAccountsPage.getModalCheckbox(); + await expect( modalCheckbox ).toBeEnabled(); + + const modalPrimaryButton = + setUpAccountsPage.getModalPrimaryButton(); + await expect( modalPrimaryButton ).toContainText( + 'Create account' + ); + await expect( modalPrimaryButton ).toBeDisabled(); + + // Select the checkbox, the button should be enabled. + await modalCheckbox.click(); + await expect( modalPrimaryButton ).toBeEnabled(); + } ); + } ); } ); } ); + // test.describe( 'Google Merchant Center card', () => { + // test.beforeAll( async () => { + // await setUpAccountsPage.mockJetpackConnected(); + // await setUpAccountsPage.mockGoogleConnected(); + + // await setUpAccountsPage.fulfillMCAccounts( [ + // [ + // { + // id: 12345, + // subaccount: true, + // name: 'MC Account 1', + // domain: 'https://example.com', + // }, + // { + // id: 23456, + // subaccount: true, + // name: 'MC Account 2', + // domain: 'https://example.com', + // }, + // ], + // ] ); + // await setUpAccountsPage.fulfillAdsAccounts( [ + // [ + // { + // id: 111111, + // name: 'gla', + // }, + // { + // id: 222222, + // name: 'gla', + // }, + // { + // id: 333333, + // name: 'gla', + // }, + // ], + // ] ); + + // await setUpAccountsPage.mockAdsAccountConnected( 111111 ); + // await setUpAccountsPage.mockMCNotConnected(); + // await setUpAccountsPage.goto(); + // } ); + + // test( 'should be prompted to connect to an existing MC account', async () => { + // const googleMCAccountCard = setUpAccountsPage.getMCAccountCard(); + + // await expect( + // googleMCAccountCard.getByText( + // 'Connect to existing Merchant Center account', + // { exact: true } + // ) + // ).toBeVisible(); + // } ); + + // test( 'should render a connected state after clicking the "Connect" button', async () => { + // await setUpAccountsPage.mockMCConnected( 12345 ); + // const connectButton = setUpAccountsPage.getConnectButton(); + // await connectButton.click(); + // await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + + // await expect( page.getByText( 'Connecting' ) ).toBeVisible(); + // await expect( connectButton ).not.toBeVisible(); + // } ); + // } ); + test.describe( 'Continue button', () => { test.beforeAll( async () => { // Mock Jetpack as connected diff --git a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js index da5aa6555c..4c779e552c 100644 --- a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js +++ b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js @@ -76,7 +76,7 @@ export default class SetUpAccountsPage extends MockRequests { */ getGoogleDescriptionRow() { return this.getGoogleAccountCard().locator( - '.gla-account-card__description' + '.gla-connected-google-combo-account-card__description' ); } @@ -226,7 +226,7 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get account cards. */ getAccountCards( options = {} ) { - return this.page.locator( '.gla-google-combo-account-card', options ); + return this.page.locator( '.gla-google-combo-account-cards', options ); } /** @@ -270,14 +270,9 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get Merchant Center account card. */ getMCAccountCard() { - return this.getAccountCards( { - has: this.page.locator( - '.gla-google-combo-service-account-card--merchant-center', - { - hasText: 'Merchant Center', - } - ), - } ).first(); + return this.getAccountCards().locator( + '.gla-google-combo-account-card__merchant-center' + ); } /** From e86de9bf28120f6950b89631125f0e69d9386093 Mon Sep 17 00:00:00 2001 From: asvinb Date: Tue, 8 Oct 2024 13:51:33 +0400 Subject: [PATCH 11/69] Review class names. --- .../connect-mc/connect-mc-body.js | 1 - .../connect-mc/connect-mc.js | 5 +- .../connected-google-combo-account-card.js | 2 +- .../connected-google-combo-account-card.scss | 8 +- .../specs/setup-mc/step-1-accounts.test.js | 562 ++++++++---------- .../pages/setup-mc/step-1-set-up-accounts.js | 24 +- 6 files changed, 263 insertions(+), 339 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js index 8cdda78d36..52ac1e4f0d 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js @@ -48,7 +48,6 @@ const ConnectMCBody = ( { suffix: ' ', tabIndex: '-1', readOnly: true, - className: 'gla-google-combo-service-select-control--connected', }; } diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index ffbb2f2de6..04225bb507 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -3,6 +3,7 @@ */ import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import classNames from 'classnames'; /** * Internal dependencies @@ -94,7 +95,9 @@ const ConnectMC = () => { return ( {
{ } ); test.describe( 'Connect Merchant Center account', () => { - // test.beforeAll( async () => { - // await Promise.all( [ - // // Mock Jetpack as connected. - // setUpAccountsPage.mockJetpackConnected( - // 'Test user', - // 'jetpack@example.com' - // ), - - // // Mock google as connected. - // setUpAccountsPage.mockGoogleConnected( 'google@example.com' ), - - // // Mock Google Ads as connected. - // setUpAccountsPage.fulfillAdsAccounts( [ - // [ - // { - // id: 111111, - // name: 'gla', - // }, - // { - // id: 222222, - // name: 'gla', - // }, - // { - // id: 333333, - // name: 'gla', - // }, - // ], - // ] ), - // setupAdsAccountPage.mockAdsAccountConnected(), - // setUpAccountsPage.fulfillMCAccounts( [ - // [ - // { - // id: 12345, - // subaccount: true, - // name: 'MC Account 1', - // domain: 'https://example.com', - // }, - // { - // id: 23456, - // subaccount: true, - // name: 'MC Account 2', - // domain: 'https://example.com', - // }, - // ], - // ] ), - - // // Mock merchant center as not connected. - // setUpAccountsPage.mockMCNotConnected(), - // ] ); - // } ); test.beforeAll( async () => { await Promise.all( [ // Mock Jetpack as connected. @@ -503,188 +447,215 @@ test.describe( 'Set up accounts', () => { ] ); } ); - // test.describe( 'Merchant Center has no existing accounts', () => { - // test.beforeAll( async () => { - // // Mock merchant center has no accounts - // await setUpAccountsPage.mockAdsAccountsResponse( ADS_ACCOUNTS ); - // await setUpAccountsPage.mockMCHasAccounts(); - // await setUpAccountsPage.goto(); - // } ); - - // test( 'should see their Google email, "Google Merchant Center" title & "Create account" button', async () => { - // const googleDescriptionRow = - // setUpAccountsPage.getGoogleDescriptionRow(); - // await expect( googleDescriptionRow ).toContainText( - // 'google@example.com' - // ); - - // const mcTitleRow = setUpAccountsPage.getMCTitleRow(); - // await expect( mcTitleRow ).toContainText( - // 'Connect to existing Merchant Center account' - // ); - - // const createAccountButton = - // setUpAccountsPage.getMCCreateAccountButtonFromPage(); - // await expect( createAccountButton ).toBeEnabled(); - - // const continueButton = setUpAccountsPage.getContinueButton(); - // await expect( continueButton ).toBeDisabled(); - // } ); - - // test( 'click "Create account" button should see the modal of confirmation of creating account', async () => { - // // Click the create account button - // const createAccountButton = - // setUpAccountsPage.getMCCreateAccountButtonFromPage(); - // await createAccountButton.click(); - // await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); - - // const modalHeader = setUpAccountsPage.getModalHeader(); - // await expect( modalHeader ).toContainText( - // 'Create Google Merchant Center Account' - // ); - - // const modalCheckbox = setUpAccountsPage.getModalCheckbox(); - // await expect( modalCheckbox ).toBeEnabled(); - - // const createAccountButtonFromModal = - // setUpAccountsPage.getMCCreateAccountButtonFromModal(); - // await expect( createAccountButtonFromModal ).toBeDisabled(); - - // // Click the checkbox of accepting ToS, the create account button will be enabled. - // await modalCheckbox.click(); - // await expect( createAccountButtonFromModal ).toBeEnabled(); - // } ); - - // test.describe( 'click "Create account" button from the modal', () => { - // test( 'should see Merchant Center "Connected" when the website is not claimed', async ( { - // baseURL, - // } ) => { - // await Promise.all( [ - // // Mock Merchant Center create accounts - // setUpAccountsPage.mockMCCreateAccountWebsiteNotClaimed(), - - // // Mock Merchant Center as connected with ID 12345 - // setUpAccountsPage.mockMCConnected( 12345 ), - // ] ); - - // const createAccountButtonFromModal = - // setUpAccountsPage.getMCCreateAccountButtonFromModal(); - // await createAccountButtonFromModal.click(); - // await page.waitForLoadState( - // LOAD_STATE.DOM_CONTENT_LOADED - // ); - // const mcConnectedLabel = - // setUpAccountsPage.getMCConnectedLabel(); - // await expect( mcConnectedLabel ).toContainText( - // 'Connected' - // ); - - // const host = new URL( baseURL ).host; - // const mcDescriptionRow = - // setUpAccountsPage.getMCDescriptionRow(); - // await expect( mcDescriptionRow ).toContainText( - // `${ host } (12345)` - // ); - // } ); - - // test.describe( 'when the website is already claimed', () => { - // test( 'should see "Reclaim my URL" button, "Switch account" button, and site URL input', async ( { - // baseURL, - // } ) => { - // const host = new URL( baseURL ).host; - - // await Promise.all( [ - // // Mock merchant center has no accounts - // setUpAccountsPage.mockMCHasNoAccounts(), - - // // Mock Merchant Center as not connected - // setUpAccountsPage.mockMCNotConnected(), - // ] ); - - // await page.reload(); - - // // Mock Merchant Center create accounts - // await setUpAccountsPage.mockMCCreateAccountWebsiteClaimed( - // 12345, - // host - // ); - - // // Click "Create account" button from the page. - // const createAccountButton = - // setUpAccountsPage.getMCCreateAccountButtonFromPage(); - // await createAccountButton.click(); - // await page.waitForLoadState( - // LOAD_STATE.DOM_CONTENT_LOADED - // ); - - // // Check the checkbox to accept ToS. - // const modalCheckbox = - // setUpAccountsPage.getModalCheckbox(); - // await modalCheckbox.click(); - - // // Click "Create account" button from the modal. - // const createAccountButtonFromModal = - // setUpAccountsPage.getMCCreateAccountButtonFromModal(); - // await createAccountButtonFromModal.click(); - // await page.waitForLoadState( - // LOAD_STATE.DOM_CONTENT_LOADED - // ); - - // const reclaimButton = - // setUpAccountsPage.getReclaimMyURLButton(); - // await expect( reclaimButton ).toBeVisible(); - - // const switchAccountButton = - // setUpAccountsPage.getSwitchAccountButton(); - // await expect( switchAccountButton ).toBeVisible(); - - // const reclaimingURLInput = - // setUpAccountsPage.getReclaimingURLInput(); - // await expect( reclaimingURLInput ).toHaveValue( - // baseURL - // ); - - // const continueButton = - // setUpAccountsPage.getContinueButton(); - // await expect( continueButton ).toBeDisabled(); - // } ); - - // test( 'click "Reclaim my URL" should send a claim overwrite request and see Merchant Center "Connected"', async ( { - // baseURL, - // } ) => { - // await Promise.all( [ - // // Mock Merchant Center accounts claim overwrite - // setUpAccountsPage.mockMCAccountsClaimOverwrite( - // 12345 - // ), - - // // Mock Merchant Center as connected with ID 12345 - // setUpAccountsPage.mockMCConnected( 12345 ), - // ] ); - - // const reclaimButton = - // setUpAccountsPage.getReclaimMyURLButton(); - // await reclaimButton.click(); - // await page.waitForLoadState( - // LOAD_STATE.DOM_CONTENT_LOADED - // ); - - // const mcConnectedLabel = - // setUpAccountsPage.getMCConnectedLabel(); - // await expect( mcConnectedLabel ).toContainText( - // 'Connected' - // ); - - // const host = new URL( baseURL ).host; - // const mcDescriptionRow = - // setUpAccountsPage.getMCDescriptionRow(); - // await expect( mcDescriptionRow ).toContainText( - // `${ host } (12345)` - // ); - // } ); - // } ); - // } ); - // } ); + test.describe( 'Merchant Center has no connected accounts', () => { + test.beforeAll( async () => { + await setUpAccountsPage.mockAdsAccountsResponse( [ + ADS_ACCOUNTS, + ] ); + await setUpAccountsPage.fulfillMCAccounts( [ + [ + { + id: 12345, + subaccount: true, + name: 'MC Account 1', + domain: 'https://example.com', + }, + { + id: 23456, + subaccount: true, + name: 'MC Account 2', + domain: 'https://example.com', + }, + ], + ] ); + await setUpAccountsPage.goto(); + } ); + + test( 'should see their Google email, "Google Merchant Center" title & "Create account" button', async () => { + const googleDescriptionRow = + setUpAccountsPage.getGoogleDescriptionRow(); + await expect( googleDescriptionRow ).toContainText( + 'google@example.com' + ); + + const mcTitleRow = setUpAccountsPage.getMCTitleRow(); + await expect( mcTitleRow ).toContainText( + 'Connect to existing Merchant Center account' + ); + + const mcFooterButton = + setUpAccountsPage.getMCCardFooterButton(); + await expect( mcFooterButton ).toBeEnabled(); + + const continueButton = setUpAccountsPage.getContinueButton(); + await expect( continueButton ).toBeDisabled(); + } ); + + test( 'click "Create account" button should see the modal of confirmation of creating account', async () => { + // Click the create account button + const createAccountButton = + setUpAccountsPage.getMCCreateAccountButtonFromPage(); + await createAccountButton.click(); + await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); + + const modalHeader = setUpAccountsPage.getModalHeader(); + await expect( modalHeader ).toContainText( + 'Create Google Merchant Center Account' + ); + + const modalCheckbox = setUpAccountsPage.getModalCheckbox(); + await expect( modalCheckbox ).toBeEnabled(); + + const createAccountButtonFromModal = + setUpAccountsPage.getMCCreateAccountButtonFromModal(); + await expect( createAccountButtonFromModal ).toBeDisabled(); + + // Click the checkbox of accepting ToS, the create account button will be enabled. + await modalCheckbox.click(); + await expect( createAccountButtonFromModal ).toBeEnabled(); + } ); + + test.describe( 'click "Create account" button from the modal', () => { + test( 'should see Merchant Center "Connected" when the website is not claimed', async () => { + await Promise.all( [ + // Mock Merchant Center create accounts + setUpAccountsPage.mockMCCreateAccountWebsiteNotClaimed(), + + // Mock Merchant Center as connected with ID 12345 + setUpAccountsPage.mockMCConnected( 12345 ), + ] ); + + const createAccountButtonFromModal = + setUpAccountsPage.getMCCreateAccountButtonFromModal(); + await createAccountButtonFromModal.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + const mcConnectedLabel = + setUpAccountsPage.getMCConnectedLabel(); + await expect( mcConnectedLabel ).toContainText( + 'Connected' + ); + + const mcDescriptionRow = + setUpAccountsPage.getMCDescriptionRow(); + await expect( mcDescriptionRow ).toContainText( + 'Merchant Center ID: 12345' + ); + } ); + + test.describe( 'when the website is already claimed', () => { + test( 'should see "Reclaim my URL" button, "Switch account" button, and site URL input', async ( { + baseURL, + } ) => { + const host = new URL( baseURL ).host; + + await Promise.all( [ + setUpAccountsPage.mockAdsAccountsResponse( [ + ADS_ACCOUNTS, + ] ), + setUpAccountsPage.fulfillMCAccounts( [ + [ + { + id: 12345, + subaccount: true, + name: 'MC Account 1', + domain: 'https://example.com', + }, + { + id: 23456, + subaccount: true, + name: 'MC Account 2', + domain: 'https://example.com', + }, + ], + ] ), + + // Mock Merchant Center as not connected + setUpAccountsPage.mockMCNotConnected(), + ] ); + + await page.reload(); + + // Mock Merchant Center create accounts + await setUpAccountsPage.mockMCCreateAccountWebsiteClaimed( + 12345, + host + ); + + // Click "Create account" button from the page. + const createAccountButton = + setUpAccountsPage.getMCCreateAccountButtonFromPage(); + await createAccountButton.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + + // Check the checkbox to accept ToS. + const modalCheckbox = + setUpAccountsPage.getModalCheckbox(); + await modalCheckbox.click(); + + // Click "Create account" button from the modal. + const createAccountButtonFromModal = + setUpAccountsPage.getMCCreateAccountButtonFromModal(); + await createAccountButtonFromModal.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + + const reclaimButton = + setUpAccountsPage.getReclaimMyURLButton(); + await expect( reclaimButton ).toBeVisible(); + + const switchAccountButton = + setUpAccountsPage.getSwitchAccountButton(); + await expect( switchAccountButton ).toBeVisible(); + + const reclaimingURLInput = + setUpAccountsPage.getReclaimingURLInput(); + await expect( reclaimingURLInput ).toHaveValue( + baseURL + ); + + const continueButton = + setUpAccountsPage.getContinueButton(); + await expect( continueButton ).toBeDisabled(); + } ); + + test( 'click "Reclaim my URL" should send a claim overwrite request and see Merchant Center "Connected"', async () => { + await Promise.all( [ + // Mock Merchant Center accounts claim overwrite + setUpAccountsPage.mockMCAccountsClaimOverwrite( + 12345 + ), + + // Mock Merchant Center as connected with ID 12345 + setUpAccountsPage.mockMCConnected( 12345 ), + ] ); + + const reclaimButton = + setUpAccountsPage.getReclaimMyURLButton(); + await reclaimButton.click(); + await page.waitForLoadState( + LOAD_STATE.DOM_CONTENT_LOADED + ); + + const mcConnectedLabel = + setUpAccountsPage.getMCConnectedLabel(); + await expect( mcConnectedLabel ).toContainText( + 'Connected' + ); + + const mcDescriptionRow = + setUpAccountsPage.getMCDescriptionRow(); + await expect( mcDescriptionRow ).toContainText( + 'Merchant Center ID: 12345' + ); + } ); + } ); + } ); + } ); test.describe( 'Merchant Center has existing accounts', () => { test.beforeAll( async () => { @@ -723,7 +694,7 @@ test.describe( 'Set up accounts', () => { const selectAccountTitle = setUpAccountsPage.getSelectExistingMCAccountTitle(); await expect( selectAccountTitle ).toContainText( - 'Select an existing account' + 'Connect to existing Merchant Center account' ); } ); @@ -745,9 +716,7 @@ test.describe( 'Set up accounts', () => { await expect( continueButton ).toBeDisabled(); } ); - test( 'select MC Account 2 and click "Connect" button should see Merchant Center "Connected"', async ( { - baseURL, - } ) => { + test( 'select MC Account 2 and click "Connect" button should see Merchant Center "Connected"', async () => { await Promise.all( [ // Mock Merchant Center create accounts setUpAccountsPage.mockMCCreateAccountWebsiteNotClaimed(), @@ -776,11 +745,10 @@ test.describe( 'Set up accounts', () => { 'Connected' ); - const host = new URL( baseURL ).host; const mcDescriptionRow = setUpAccountsPage.getMCDescriptionRow(); await expect( mcDescriptionRow ).toContainText( - `${ host } (23456)` + `Merchant Center ID: 23456` ); } ); } ); @@ -788,23 +756,40 @@ test.describe( 'Set up accounts', () => { test.describe( 'click "Or, create a new Merchant Center account"', () => { test.beforeAll( async () => { await Promise.all( [ + // Mock Jetpack as connected. + setUpAccountsPage.mockJetpackConnected( + 'Test user', + 'jetpack@example.com' + ), + + // Mock google as connected. + setUpAccountsPage.mockGoogleConnected( + 'google@example.com' + ), + + // Mock Google Ads as connected. + setUpAccountsPage.mockAdsAccountConnected(), + setUpAccountsPage.mockAdsStatusClaimed(), + // Mock merchant center as not connected. setUpAccountsPage.mockMCNotConnected(), // Mock merchant center has accounts setUpAccountsPage.fulfillMCAccounts( [ - { - id: 12345, - subaccount: true, - name: 'MC Account 1', - domain: 'https://example.com', - }, - { - id: 23456, - subaccount: true, - name: 'MC Account 2', - domain: 'https://example.com', - }, + [ + { + id: 12345, + subaccount: true, + name: 'MC Account 1', + domain: 'https://example.com', + }, + { + id: 23456, + subaccount: true, + name: 'MC Account 2', + domain: 'https://example.com', + }, + ], ] ), ] ); @@ -843,71 +828,6 @@ test.describe( 'Set up accounts', () => { } ); } ); - // test.describe( 'Google Merchant Center card', () => { - // test.beforeAll( async () => { - // await setUpAccountsPage.mockJetpackConnected(); - // await setUpAccountsPage.mockGoogleConnected(); - - // await setUpAccountsPage.fulfillMCAccounts( [ - // [ - // { - // id: 12345, - // subaccount: true, - // name: 'MC Account 1', - // domain: 'https://example.com', - // }, - // { - // id: 23456, - // subaccount: true, - // name: 'MC Account 2', - // domain: 'https://example.com', - // }, - // ], - // ] ); - // await setUpAccountsPage.fulfillAdsAccounts( [ - // [ - // { - // id: 111111, - // name: 'gla', - // }, - // { - // id: 222222, - // name: 'gla', - // }, - // { - // id: 333333, - // name: 'gla', - // }, - // ], - // ] ); - - // await setUpAccountsPage.mockAdsAccountConnected( 111111 ); - // await setUpAccountsPage.mockMCNotConnected(); - // await setUpAccountsPage.goto(); - // } ); - - // test( 'should be prompted to connect to an existing MC account', async () => { - // const googleMCAccountCard = setUpAccountsPage.getMCAccountCard(); - - // await expect( - // googleMCAccountCard.getByText( - // 'Connect to existing Merchant Center account', - // { exact: true } - // ) - // ).toBeVisible(); - // } ); - - // test( 'should render a connected state after clicking the "Connect" button', async () => { - // await setUpAccountsPage.mockMCConnected( 12345 ); - // const connectButton = setUpAccountsPage.getConnectButton(); - // await connectButton.click(); - // await page.waitForLoadState( LOAD_STATE.DOM_CONTENT_LOADED ); - - // await expect( page.getByText( 'Connecting' ) ).toBeVisible(); - // await expect( connectButton ).not.toBeVisible(); - // } ); - // } ); - test.describe( 'Continue button', () => { test.beforeAll( async () => { // Mock Jetpack as connected diff --git a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js index 4c779e552c..51bcea710d 100644 --- a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js +++ b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js @@ -55,8 +55,8 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get MC "Create account" button from the page. */ getMCCreateAccountButtonFromPage() { - const button = this.getCreateAccountButton(); - return button.locator( ':scope.is-secondary' ).nth( 1 ); + const button = this.getMCCardFooterButton(); + return button; } /** @@ -86,9 +86,9 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get Merchant Center description row. */ getMCDescriptionRow() { - return this.getMCAccountCard().locator( - '.gla-account-card__description' - ); + return this.getGoogleDescriptionRow().locator( 'p', { + hasText: 'Merchant Center ID', + } ); } /** @@ -193,9 +193,7 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get select existing Merchant Center account title. */ getSelectExistingMCAccountTitle() { - return this.getMCAccountCard() - .locator( '.wcdl-subsection-title' ) - .nth( 1 ); + return this.getMCAccountCard().locator( '.gla-account-card__title' ); } /** @@ -226,7 +224,7 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get account cards. */ getAccountCards( options = {} ) { - return this.page.locator( '.gla-google-combo-account-cards', options ); + return this.page.locator( '.gla-google-combo-account-card', options ); } /** @@ -235,7 +233,9 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get WordPress account card. */ getWPAccountCard() { - return this.getAccountCards( { hasText: 'WordPress.com' } ).first(); + return this.page.locator( '.gla-account-card', { + hasText: 'WordPress.com', + } ); } /** @@ -281,7 +281,9 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get Merchant Center card footer. */ getMCCardFooter() { - return this.getMCAccountCard().locator( '.wcdl-section-card-footer' ); + return this.getMCAccountCard().locator( + '.gla-google-combo-connect-account-card__footer' + ); } /** From 75723e2a81dd9162eb92da8a475aa65e864cbced Mon Sep 17 00:00:00 2001 From: asvinb Date: Tue, 8 Oct 2024 14:22:13 +0400 Subject: [PATCH 12/69] Fix e2e tests. --- .../connect-google-combo-account-card.js | 2 +- .../specs/setup-mc/step-1-accounts.test.js | 21 +++++++++++++++++++ .../pages/setup-mc/step-1-set-up-accounts.js | 4 +--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-google-combo-account-card.js b/js/src/components/google-combo-account-card/connect-google-combo-account-card.js index 2537700494..c5611f7571 100644 --- a/js/src/components/google-combo-account-card/connect-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connect-google-combo-account-card.js @@ -33,7 +33,7 @@ const ConnectGoogleComboAccountCard = ( { disabled } ) => { return ( { const host = new URL( baseURL ).host; await Promise.all( [ + // Mock Jetpack as connected. + setUpAccountsPage.mockJetpackConnected( + 'Test user', + 'jetpack@example.com' + ), + + // Mock google as connected. + setUpAccountsPage.mockGoogleConnected( + 'google@example.com' + ), setUpAccountsPage.mockAdsAccountsResponse( [ ADS_ACCOUNTS, ] ), @@ -660,6 +670,17 @@ test.describe( 'Set up accounts', () => { test.describe( 'Merchant Center has existing accounts', () => { test.beforeAll( async () => { await Promise.all( [ + // Mock Jetpack as connected. + setUpAccountsPage.mockJetpackConnected( + 'Test user', + 'jetpack@example.com' + ), + + // Mock google as connected. + setUpAccountsPage.mockGoogleConnected( + 'google@example.com' + ), + setUpAccountsPage.mockAdsAccountsResponse( [ ADS_ACCOUNTS, ] ), diff --git a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js index 51bcea710d..a8c2341db8 100644 --- a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js +++ b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js @@ -270,9 +270,7 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get Merchant Center account card. */ getMCAccountCard() { - return this.getAccountCards().locator( - '.gla-google-combo-account-card__merchant-center' - ); + return this.page.locator( '.gla-google-combo-account-card--mc' ); } /** From 406f028c802bbb44592947e51cdd3c447c31242b Mon Sep 17 00:00:00 2001 From: asvinb Date: Tue, 8 Oct 2024 16:21:25 +0400 Subject: [PATCH 13/69] Use mock functions available. --- .../specs/setup-mc/step-1-accounts.test.js | 82 ++----------------- 1 file changed, 9 insertions(+), 73 deletions(-) diff --git a/tests/e2e/specs/setup-mc/step-1-accounts.test.js b/tests/e2e/specs/setup-mc/step-1-accounts.test.js index 12db88825a..5f416438e8 100644 --- a/tests/e2e/specs/setup-mc/step-1-accounts.test.js +++ b/tests/e2e/specs/setup-mc/step-1-accounts.test.js @@ -473,25 +473,8 @@ test.describe( 'Set up accounts', () => { test.describe( 'Merchant Center has no connected accounts', () => { test.beforeAll( async () => { - await setUpAccountsPage.mockAdsAccountsResponse( [ - ADS_ACCOUNTS, - ] ); - await setUpAccountsPage.fulfillMCAccounts( [ - [ - { - id: 12345, - subaccount: true, - name: 'MC Account 1', - domain: 'https://example.com', - }, - { - id: 23456, - subaccount: true, - name: 'MC Account 2', - domain: 'https://example.com', - }, - ], - ] ); + await setUpAccountsPage.mockAdsAccountsResponse( ADS_ACCOUNTS ); + await setUpAccountsPage.mockMCHasAccounts(); await setUpAccountsPage.goto(); } ); @@ -585,25 +568,10 @@ test.describe( 'Set up accounts', () => { setUpAccountsPage.mockGoogleConnected( 'google@example.com' ), - setUpAccountsPage.mockAdsAccountsResponse( [ - ADS_ACCOUNTS, - ] ), - setUpAccountsPage.fulfillMCAccounts( [ - [ - { - id: 12345, - subaccount: true, - name: 'MC Account 1', - domain: 'https://example.com', - }, - { - id: 23456, - subaccount: true, - name: 'MC Account 2', - domain: 'https://example.com', - }, - ], - ] ), + setUpAccountsPage.mockAdsAccountsResponse( + ADS_ACCOUNTS + ), + setUpAccountsPage.mockMCHasAccounts(), // Mock Merchant Center as not connected setUpAccountsPage.mockMCNotConnected(), @@ -705,30 +673,13 @@ test.describe( 'Set up accounts', () => { 'google@example.com' ), - setUpAccountsPage.mockAdsAccountsResponse( [ - ADS_ACCOUNTS, - ] ), + setUpAccountsPage.mockAdsAccountsResponse( ADS_ACCOUNTS ), // Mock merchant center as not connected. setUpAccountsPage.mockMCNotConnected(), // Mock merchant center has accounts - setUpAccountsPage.fulfillMCAccounts( [ - [ - { - id: 12345, - subaccount: true, - name: 'MC Account 1', - domain: 'https://example.com', - }, - { - id: 23456, - subaccount: true, - name: 'MC Account 2', - domain: 'https://example.com', - }, - ], - ] ), + setUpAccountsPage.mockMCHasAccounts(), ] ); await setUpAccountsPage.goto(); @@ -820,22 +771,7 @@ test.describe( 'Set up accounts', () => { setUpAccountsPage.mockMCNotConnected(), // Mock merchant center has accounts - setUpAccountsPage.fulfillMCAccounts( [ - [ - { - id: 12345, - subaccount: true, - name: 'MC Account 1', - domain: 'https://example.com', - }, - { - id: 23456, - subaccount: true, - name: 'MC Account 2', - domain: 'https://example.com', - }, - ], - ] ), + setUpAccountsPage.mockMCHasAccounts(), ] ); await setUpAccountsPage.goto(); From acedda6b42794b46f70760f2f24ca00601e4b73e Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 9 Oct 2024 17:51:13 +0400 Subject: [PATCH 14/69] Address CR feedback. --- .../connect-mc/connect-mc.js | 62 ++++------------ .../connected-google-combo-account-card.js | 32 ++++---- .../account-connection-status.js | 74 +++++++++++++++++++ .../connect-mc/index.js | 43 ++--------- .../pages/setup-mc/step-1-set-up-accounts.js | 12 +-- 5 files changed, 117 insertions(+), 106 deletions(-) create mode 100644 js/src/components/google-mc-account-card/account-connection-status.js diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 04225bb507..2e9d01a56e 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -1,23 +1,21 @@ /** * External dependencies */ -import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { useState } from '@wordpress/element'; import classNames from 'classnames'; /** * Internal dependencies */ -import SwitchUrlCard from '.~/components/google-mc-account-card/switch-url-card'; -import ReclaimUrlCard from '.~/components/google-mc-account-card/reclaim-url-card'; import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; -import CreatingCard from '.~/components/google-mc-account-card/creating-card'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectAccountCard from '../connect-account-card'; import ConnectMCBody from './connect-mc-body'; import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; +import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -33,6 +31,10 @@ const ConnectMC = () => { const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + if ( ! hasFinishedResolution ) { + return ; + } + // MC is ready when we have a connection. // The `link_ads` step will be resolved when the Ads account is connected // since these can be connected in any order. @@ -42,57 +44,23 @@ const ConnectMC = () => { ( googleMCAccount?.status === 'incomplete' && googleMCAccount?.step === 'link_ads' ); - if ( ! isConnected && resultConnectMC.response?.status === 409 ) { - return ( - - ); - } - if ( - ! isConnected && - ( resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 ) + ( resultConnectMC.response?.status === 409 || + resultConnectMC.response?.status === 403 || + resultCreateAccount.response?.status === 403 || + resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 ) && + ! isConnected ) { return ( - { - resultConnectMC.reset(); - resultCreateAccount.reset(); - } } - /> - ); - } - - if ( - ! isConnected && - ( resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 ) - ) { - return ( - ); } - if ( ! hasFinishedResolution ) { - return ; - } - return ( { }; return ( -
- - } - helper={ getHelper() } - indicator={ getIndicator() } - /> - + + } + helper={ getHelper() } + indicator={ getIndicator() } + > -
+
); }; diff --git a/js/src/components/google-mc-account-card/account-connection-status.js b/js/src/components/google-mc-account-card/account-connection-status.js new file mode 100644 index 0000000000..c4e6009dfb --- /dev/null +++ b/js/src/components/google-mc-account-card/account-connection-status.js @@ -0,0 +1,74 @@ +/** + * Internal dependencies + */ +import SwitchUrlCard from './switch-url-card'; +import ReclaimUrlCard from './reclaim-url-card'; +import CreatingCard from './creating-card'; + +/** + * Displays different status cards based on account connection results. + * + * This component handles the display of: + * - A switch URL card. + * - A reclaim URL card. + * - A creating card when the account is being created. + * + * @param {Object} props - The component props. + * @param {Object} props.resultConnectMC - The result object for connecting the MC account. + * @param {Object} props.resultCreateAccount - The result object for creating a new account. + * @param {Function} props.onRetry - The function to call when the user wants to retry account creation. + */ +const AccountConnectionStatus = ( { + resultConnectMC, + resultCreateAccount, + onRetry, +} ) => { + if ( resultConnectMC.response?.status === 409 ) { + return ( + + ); + } + + if ( + resultConnectMC.response?.status === 403 || + resultCreateAccount.response?.status === 403 + ) { + return ( + { + resultConnectMC.reset(); + resultCreateAccount.reset(); + } } + /> + ); + } + + if ( + resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 + ) { + return ( + + ); + } + + return null; +}; + +export default AccountConnectionStatus; diff --git a/js/src/components/google-mc-account-card/connect-mc/index.js b/js/src/components/google-mc-account-card/connect-mc/index.js index a47ccfa5fc..9529505f0e 100644 --- a/js/src/components/google-mc-account-card/connect-mc/index.js +++ b/js/src/components/google-mc-account-card/connect-mc/index.js @@ -13,13 +13,11 @@ import AppButton from '.~/components/app-button'; import Section from '.~/wcdl/section'; import Subsection from '.~/wcdl/subsection'; import ContentButtonLayout from '.~/components/content-button-layout'; -import SwitchUrlCard from '../switch-url-card'; -import ReclaimUrlCard from '../reclaim-url-card'; import AccountCard, { APPEARANCE } from '.~/components/account-card'; import CreateAccountButton from '../create-account-button'; import useConnectMCAccount from '../useConnectMCAccount'; import useCreateMCAccount from '../useCreateMCAccount'; -import CreatingCard from '../creating-card'; +import AccountConnectionStatus from '../account-connection-status'; import './index.scss'; /** @@ -44,46 +42,17 @@ const ConnectMC = () => { const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); - if ( resultConnectMC.response?.status === 409 ) { - return ( - - ); - } - if ( + resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 - ) { - return ( - { - resultConnectMC.reset(); - resultCreateAccount.reset(); - } } - /> - ); - } - - if ( + resultCreateAccount.response?.status === 403 || resultCreateAccount.loading || resultCreateAccount.response?.status === 503 ) { return ( - ); diff --git a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js index a8c2341db8..e2a6a9ff6b 100644 --- a/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js +++ b/tests/e2e/utils/pages/setup-mc/step-1-set-up-accounts.js @@ -244,11 +244,13 @@ export default class SetUpAccountsPage extends MockRequests { * @return {import('@playwright/test').Locator} Get Google account card. */ getGoogleAccountCard() { - return this.getAccountCards( { - has: this.page.locator( '.gla-account-card__title', { - hasText: 'Google', - } ), - } ).first(); + return this.page + .locator( '.components-card-body', { + has: this.page.locator( '.gla-account-card__title', { + hasText: 'Google', + } ), + } ) + .first(); } /** From 13d8d2b2bf89ffdb0e224e6ae045a7df21f47429 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 9 Oct 2024 17:53:00 +0400 Subject: [PATCH 15/69] Cast googleMCAccount?.id to a boolean. --- .../google-combo-account-card/connect-mc/connect-mc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 2e9d01a56e..ffee4b6171 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -39,7 +39,7 @@ const ConnectMC = () => { // The `link_ads` step will be resolved when the Ads account is connected // since these can be connected in any order. const isConnected = - googleMCAccount?.id || + !! googleMCAccount?.id || googleMCAccount?.status === 'connected' || ( googleMCAccount?.status === 'incomplete' && googleMCAccount?.step === 'link_ads' ); From 9e8649b508105ded3ef4ad43a880b1f4a26bc1da Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 9 Oct 2024 21:14:33 +0400 Subject: [PATCH 16/69] Add description when connecting extra account. --- .../account-creation-description/index.js | 21 ++++++++++++++++ .../connect-mc/connect-mc.js | 24 ++++++++++++------- .../connected-google-combo-account-card.js | 13 ++++++++-- js/src/hooks/useAutoCreateAdsMCAccounts.js | 1 + 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/js/src/components/google-combo-account-card/account-creation-description/index.js b/js/src/components/google-combo-account-card/account-creation-description/index.js index bb5a7ec23d..78b1d51f57 100644 --- a/js/src/components/google-combo-account-card/account-creation-description/index.js +++ b/js/src/components/google-combo-account-card/account-creation-description/index.js @@ -19,12 +19,14 @@ import AccountInfo from './account-info'; * @param {boolean} props.isCreatingBothAccounts Whether both, MC and Ads accounts are being created. * @param {boolean} props.isCreatingMCAccount Whether Merchant Center account is being created. * @param {boolean} props.isCreatingAdsAccount Whether Google Ads account is being created. + * @param {boolean} props.hasExistingMCAccounts Whether there are existing MC accounts. */ const AccountCreationDescription = ( { accountsCreated, isCreatingBothAccounts, isCreatingMCAccount, isCreatingAdsAccount, + hasExistingMCAccounts, } ) => { const { google } = useGoogleAccount(); const { @@ -76,6 +78,25 @@ const AccountCreationDescription = ( { ); } else if ( isCreatingMCAccount ) { + if ( hasExistingMCAccounts ) { + return ( + <> +

+ { __( + 'Creating a new Google Merchant Center account', + 'google-listings-and-ads' + ) } +

+ + { __( + 'This may take a few minutes, please wait a moment…', + 'google-listings-and-ads' + ) } + + + ); + } + return ( <>

diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index ffee4b6171..075084a7dd 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -2,8 +2,9 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; +import { useState, useEffect } from '@wordpress/element'; import classNames from 'classnames'; +import { noop } from 'lodash'; /** * Internal dependencies @@ -24,13 +25,17 @@ import AccountConnectionStatus from '.~/components/google-mc-account-card/accoun * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. */ -const ConnectMC = () => { +const ConnectMC = ( { onCreateAccountLoading = noop } ) => { const { googleMCAccount, hasFinishedResolution, isPreconditionReady } = useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + useEffect( () => { + onCreateAccountLoading( resultCreateAccount?.loading ); + }, [ resultCreateAccount, onCreateAccountLoading ] ); + if ( ! hasFinishedResolution ) { return ; } @@ -43,14 +48,17 @@ const ConnectMC = () => { googleMCAccount?.status === 'connected' || ( googleMCAccount?.status === 'incomplete' && googleMCAccount?.step === 'link_ads' ); + const shouldClaimAccount = + googleMCAccount?.status === 'incomplete' && + googleMCAccount?.step === 'claim'; if ( - ( resultConnectMC.response?.status === 409 || - resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 || - resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 ) && - ! isConnected + resultConnectMC.response?.status === 409 || + resultConnectMC.response?.status === 403 || + resultCreateAccount.response?.status === 403 || + resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 || + shouldClaimAccount ) { return ( { isCreatingMCAccount, accountCreationChecksResolved, accountsCreated, + hasExistingMCAccounts, } = useAutoCreateAdsMCAccounts(); + const [ isManuallyCreatingMCAccount, setIsManuallyCreatingMCAccount ] = + useState( false ); if ( ! accountCreationChecksResolved || @@ -115,16 +119,21 @@ const ConnectedGoogleComboAccountCard = () => { className="gla-google-combo-account-card gla-google-combo-account-card--connected" description={ } helper={ getHelper() } indicator={ getIndicator() } > - + ); }; diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index ab9951a2dc..27b35b0671 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -191,6 +191,7 @@ const useAutoCreateAdsMCAccounts = () => { return { accountCreationChecksResolved, + hasExistingMCAccounts: initHasExistingMCAccountsRef.current, isCreatingAdsAccount: isCreatingAdsAccountsRef.current, isCreatingMCAccount: isCreatingMCAccountsRef.current, isCreatingBothAccounts: isCreatingBothAccountsRef.current, From 29810677ca7381e98321a62214e49eab7f101a53 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 9 Oct 2024 21:46:20 +0400 Subject: [PATCH 17/69] Fix card when reclaiming URL. --- ...dex.js => account-creation-description.js} | 50 +++++++++++-------- .../account-info.js | 16 ------ .../connect-mc/connect-mc-body.js | 1 + .../connect-mc/connect-mc.js | 17 +++---- .../connected-google-combo-account-card.js | 11 ++-- .../connected-google-combo-account-card.scss | 8 +-- 6 files changed, 49 insertions(+), 54 deletions(-) rename js/src/components/google-combo-account-card/{account-creation-description/index.js => account-creation-description.js} (80%) delete mode 100644 js/src/components/google-combo-account-card/account-creation-description/account-info.js diff --git a/js/src/components/google-combo-account-card/account-creation-description/index.js b/js/src/components/google-combo-account-card/account-creation-description.js similarity index 80% rename from js/src/components/google-combo-account-card/account-creation-description/index.js rename to js/src/components/google-combo-account-card/account-creation-description.js index 78b1d51f57..63d37eaa58 100644 --- a/js/src/components/google-combo-account-card/account-creation-description/index.js +++ b/js/src/components/google-combo-account-card/account-creation-description.js @@ -9,7 +9,6 @@ import { __, sprintf } from '@wordpress/i18n'; import useGoogleAccount from '.~/hooks/useGoogleAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; -import AccountInfo from './account-info'; /** * Renders the description for the account creation card. @@ -20,6 +19,8 @@ import AccountInfo from './account-info'; * @param {boolean} props.isCreatingMCAccount Whether Merchant Center account is being created. * @param {boolean} props.isCreatingAdsAccount Whether Google Ads account is being created. * @param {boolean} props.hasExistingMCAccounts Whether there are existing MC accounts. + * @param {boolean} props.isGoogleAdsAccountConnected Whether Google Ads account is connected. + * @param {boolean} props.isGoogleMCAccountConnected Whether Merchant Center account is connected. */ const AccountCreationDescription = ( { accountsCreated, @@ -27,6 +28,8 @@ const AccountCreationDescription = ( { isCreatingMCAccount, isCreatingAdsAccount, hasExistingMCAccounts, + isGoogleAdsAccountConnected, + isGoogleMCAccountConnected, } ) => { const { google } = useGoogleAccount(); const { @@ -119,25 +122,32 @@ const AccountCreationDescription = ( { return ( <>

{ google?.email }

- - + + { isGoogleMCAccountConnected && ( +

+ { sprintf( + // Translators: %s is the Merchant Center ID + __( + 'Merchant Center ID: %s', + 'google-listings-and-ads' + ), + googleMCAccount.id + ) } +

+ ) } + + { isGoogleAdsAccountConnected && ( +

+ { sprintf( + // Translators: %s is the Google Ads ID + __( + 'Google Ads ID: %s', + 'google-listings-and-ads' + ), + googleAdsAccount.id + ) } +

+ ) } ); }; diff --git a/js/src/components/google-combo-account-card/account-creation-description/account-info.js b/js/src/components/google-combo-account-card/account-creation-description/account-info.js deleted file mode 100644 index 673c16a1d4..0000000000 --- a/js/src/components/google-combo-account-card/account-creation-description/account-info.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Display account info. - * - * @param {Object} props Props. - * @param {Object} props.account Account object. - * @param {string} props.text Text to display. - */ -const AccountInfo = ( { account, text } ) => { - if ( ! account?.id ) { - return null; - } - - return

{ text }

; -}; - -export default AccountInfo; diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js index 52ac1e4f0d..d4106691c4 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js @@ -48,6 +48,7 @@ const ConnectMCBody = ( { suffix: ' ', tabIndex: '-1', readOnly: true, + className: 'gla-google-combo-service-connected-select-control', }; } diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 075084a7dd..0cf0df746b 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -17,6 +17,7 @@ import ConnectMCBody from './connect-mc-body'; import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; +import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -40,25 +41,21 @@ const ConnectMC = ( { onCreateAccountLoading = noop } ) => { return ; } - // MC is ready when we have a connection. + // MC is ready when we have a connection and preconditions are met. // The `link_ads` step will be resolved when the Ads account is connected // since these can be connected in any order. const isConnected = - !! googleMCAccount?.id || - googleMCAccount?.status === 'connected' || - ( googleMCAccount?.status === 'incomplete' && - googleMCAccount?.step === 'link_ads' ); - const shouldClaimAccount = - googleMCAccount?.status === 'incomplete' && - googleMCAccount?.step === 'claim'; + isPreconditionReady && + ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || + ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && + googleMCAccount?.step === 'link_ads' ) ); if ( resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || resultCreateAccount.response?.status === 403 || resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 || - shouldClaimAccount + resultCreateAccount.response?.status === 503 ) { return ( { const { googleMCAccount, + isPreconditionReady, hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount, } = useGoogleMCAccount(); @@ -73,10 +74,10 @@ const ConnectedGoogleComboAccountCard = () => { ) ); const isGoogleMCAccountConnected = - googleMCAccount?.id || - googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || - ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && - [ 'link_ads', 'claim' ].includes( googleMCAccount?.step ) ); + isPreconditionReady && + ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || + ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && + googleMCAccount?.step === 'link_ads' ) ); const getHelper = () => { if ( isCreatingBothAccounts ) { @@ -126,6 +127,8 @@ const ConnectedGoogleComboAccountCard = () => { isCreatingMCAccount || isManuallyCreatingMCAccount } accountsCreated={ accountsCreated } + isGoogleMCAccountConnected={ isGoogleMCAccountConnected } + isGoogleAdsAccountConnected={ isGoogleAdsAccountConnected } /> } helper={ getHelper() } diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss index d58c7e7228..4d7ade391b 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.scss @@ -7,12 +7,12 @@ .gla-account-card__description p { margin: 0; } - - .components-select-control__input { - pointer-events: none; - } } .gla-google-combo-service-connected-icon-label { width: auto; } + +.gla-google-combo-service-connected-select-control { + pointer-events: none; +} From e03f3c3a4a1208e8ca1816c72b453283e7c82647 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 9 Oct 2024 22:35:42 +0400 Subject: [PATCH 18/69] Fix E2E tests. --- .../specs/setup-mc/step-1-accounts.test.js | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/tests/e2e/specs/setup-mc/step-1-accounts.test.js b/tests/e2e/specs/setup-mc/step-1-accounts.test.js index 1567073068..569f296b10 100644 --- a/tests/e2e/specs/setup-mc/step-1-accounts.test.js +++ b/tests/e2e/specs/setup-mc/step-1-accounts.test.js @@ -326,15 +326,6 @@ test.describe( 'Set up accounts', () => { await setUpAccountsPage.mockJetpackConnected(); await setUpAccountsPage.mockGoogleConnected(); - await setUpAccountsPage.fulfillMCConnection( { - id: 5432178, - name: null, - subaccount: null, - domain: null, - status: 'incomplete', - step: 'claim', - } ); - await setUpAccountsPage.fulfillAdsConnection( { id: 78787878, currency: 'USD', @@ -344,6 +335,9 @@ test.describe( 'Set up accounts', () => { symbol: '$', } ); + await setupAdsAccountPage.mockMCHasAccounts(); + await setUpAccountsPage.mockMCConnected(); + await setUpAccountsPage.goto(); } ); @@ -360,26 +354,12 @@ test.describe( 'Set up accounts', () => { [ 'POST' ] ); - await setupAdsAccountPage.fulfillMCAccounts( - { - id: 5432178, - name: null, - subaccount: null, - domain: null, - }, - 200, - [ 'POST' ] - ); - const googleAccountCard = setUpAccountsPage.getGoogleAccountCard(); await expect( - googleAccountCard.getByText( - 'Merchant Center ID: 5432178', - { - exact: true, - } - ) + googleAccountCard.getByText( 'Merchant Center ID: 1234', { + exact: true, + } ) ).toBeVisible(); await expect( From 3b096ff8b9e179923278da28830d43cf71328fcc Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 13:35:03 +0400 Subject: [PATCH 19/69] Add isConnected property to useGoogleMCAccount hook. --- .../connect-mc/connect-mc.js | 12 +----------- .../connected-google-combo-account-card.js | 9 +-------- js/src/hooks/useGoogleMCAccount.js | 15 ++++++++++++++- .../setup-stepper/setup-accounts/index.js | 11 +---------- 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 0cf0df746b..356dcd4703 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -17,7 +17,6 @@ import ConnectMCBody from './connect-mc-body'; import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; -import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -27,7 +26,7 @@ import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; */ const ConnectMC = ( { onCreateAccountLoading = noop } ) => { - const { googleMCAccount, hasFinishedResolution, isPreconditionReady } = + const { hasFinishedResolution, isConnected, isPreconditionReady } = useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); @@ -41,15 +40,6 @@ const ConnectMC = ( { onCreateAccountLoading = noop } ) => { return ; } - // MC is ready when we have a connection and preconditions are met. - // The `link_ads` step will be resolved when the Ads account is connected - // since these can be connected in any order. - const isConnected = - isPreconditionReady && - ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || - ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && - googleMCAccount?.step === 'link_ads' ) ); - if ( resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 08b0af2b53..c96d3dc428 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -41,8 +41,7 @@ const ConnectedGoogleComboAccountCard = () => { } = useGoogleAdsAccount(); const { - googleMCAccount, - isPreconditionReady, + isConnected: isGoogleMCAccountConnected, hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount, } = useGoogleMCAccount(); @@ -73,12 +72,6 @@ const ConnectedGoogleComboAccountCard = () => { googleAdsAccount?.step ) ); - const isGoogleMCAccountConnected = - isPreconditionReady && - ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || - ( googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && - googleMCAccount?.step === 'link_ads' ) ); - const getHelper = () => { if ( isCreatingBothAccounts ) { return ( diff --git a/js/src/hooks/useGoogleMCAccount.js b/js/src/hooks/useGoogleMCAccount.js index 76958ea1d9..066f6a7b65 100644 --- a/js/src/hooks/useGoogleMCAccount.js +++ b/js/src/hooks/useGoogleMCAccount.js @@ -7,6 +7,7 @@ import { useSelect } from '@wordpress/data'; * Internal dependencies */ import { STORE_KEY } from '.~/data/constants'; +import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; import useGoogleAccount from './useGoogleAccount'; /** @@ -43,18 +44,30 @@ const useGoogleMCAccount = () => { // has not been granted necessary access permissions for Google Merchant Center, then // the precondition doesn't meet. isPreconditionReady: false, + isConnected: false, }; } const { getGoogleMCAccount, isResolving, hasFinishedResolution } = select( STORE_KEY ); + const googleMCAccount = getGoogleMCAccount(); return { - googleMCAccount: getGoogleMCAccount(), + googleMCAccount, isResolving: isResolving( 'getGoogleMCAccount' ), hasFinishedResolution: hasFinishedResolution( 'getGoogleMCAccount' ), isPreconditionReady: true, + + // MC is ready when we have a connection and preconditions are met. + // The `link_ads` step will be resolved when the Ads account is connected + // since these can be connected in any order. + isConnected: + googleMCAccount?.status === + GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || + ( googleMCAccount?.status === + GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && + googleMCAccount?.step === 'link_ads' ), }; }, [ diff --git a/js/src/setup-mc/setup-stepper/setup-accounts/index.js b/js/src/setup-mc/setup-stepper/setup-accounts/index.js index d4bfc68f86..bc9ecbbff9 100644 --- a/js/src/setup-mc/setup-stepper/setup-accounts/index.js +++ b/js/src/setup-mc/setup-stepper/setup-accounts/index.js @@ -83,7 +83,7 @@ const SetupAccounts = ( props ) => { const { onContinue = () => {} } = props; const { jetpack } = useJetpackAccount(); const { google, scope } = useGoogleAccount(); - const { googleMCAccount, isPreconditionReady: isGMCPreconditionReady } = + const { googleMCAccount, isConnected: isGoogleMCReady } = useGoogleMCAccount(); const { hasFinishedResolution, hasGoogleAdsConnection } = useGoogleAdsAccount(); @@ -118,15 +118,6 @@ const SetupAccounts = ( props ) => { hasAccess && [ '', 'billing', 'link_merchant' ].includes( step ); - // MC is ready when we have a connection and preconditions are met. - // The `link_ads` step will be resolved when the Ads account is connected - // since these can be connected in any order. - const isGoogleMCReady = - isGMCPreconditionReady && - ( googleMCAccount?.status === 'connected' || - ( googleMCAccount?.status === 'incomplete' && - googleMCAccount?.step === 'link_ads' ) ); - const isContinueButtonDisabled = ! ( hasFinishedResolution && isGoogleAdsReady && From deaa836dfa485afec7863450d86864ac01c7179b Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 13:38:45 +0400 Subject: [PATCH 20/69] Removed unused constant. --- .../connected-google-combo-account-card.js | 5 +---- js/src/setup-mc/setup-stepper/setup-accounts/index.js | 7 +++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index c96d3dc428..92b1506252 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -17,10 +17,7 @@ import './connected-google-combo-account-card.scss'; import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectedIconLabel from '../connected-icon-label'; -import { - GOOGLE_ADS_ACCOUNT_STATUS, - GOOGLE_MC_ACCOUNT_STATUS, -} from '.~/constants'; +import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; /** * Clicking on the "connect to a different Google account" button. diff --git a/js/src/setup-mc/setup-stepper/setup-accounts/index.js b/js/src/setup-mc/setup-stepper/setup-accounts/index.js index bc9ecbbff9..1d98e045d3 100644 --- a/js/src/setup-mc/setup-stepper/setup-accounts/index.js +++ b/js/src/setup-mc/setup-stepper/setup-accounts/index.js @@ -83,8 +83,11 @@ const SetupAccounts = ( props ) => { const { onContinue = () => {} } = props; const { jetpack } = useJetpackAccount(); const { google, scope } = useGoogleAccount(); - const { googleMCAccount, isConnected: isGoogleMCReady } = - useGoogleMCAccount(); + const { + googleMCAccount, + isPreconditionReady: isGMCPreconditionReady, + isConnected: isGoogleMCReady, + } = useGoogleMCAccount(); const { hasFinishedResolution, hasGoogleAdsConnection } = useGoogleAdsAccount(); const { hasAccess, step } = useGoogleAdsAccountStatus(); From 66d6eb9ebb9e5b302e5662a18a050c67b31003ef Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 14:13:01 +0400 Subject: [PATCH 21/69] Wrap all cards together. --- .../connected-google-combo-account-card.js | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 92b1506252..5c480fc9a5 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -105,29 +105,34 @@ const ConnectedGoogleComboAccountCard = () => { }; return ( - - } - helper={ getHelper() } - indicator={ getIndicator() } - > +
+ + } + helper={ getHelper() } + indicator={ getIndicator() } + /> - +
); }; From fa5b3ea8c8a405d1a4b1737ee739917b5ef582be Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 20:57:25 +0400 Subject: [PATCH 22/69] Add more properties to useAutoCreateAdsMCAccounts.js hook. --- .../connect-mc/connect-mc.js | 19 +++++++--- .../connected-google-combo-account-card.js | 4 ++ js/src/hooks/useAutoCreateAdsMCAccounts.js | 37 +++++++++++-------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 356dcd4703..bb0e9e7c21 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -4,7 +4,7 @@ import { __ } from '@wordpress/i18n'; import { useState, useEffect } from '@wordpress/element'; import classNames from 'classnames'; -import { noop } from 'lodash'; +import { noop, merge } from 'lodash'; /** * Internal dependencies @@ -25,12 +25,19 @@ import AccountConnectionStatus from '.~/components/google-mc-account-card/accoun * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. */ -const ConnectMC = ( { onCreateAccountLoading = noop } ) => { +const ConnectMC = ( { + onCreateAccountLoading = noop, + autoAccountCreationResult, +} ) => { const { hasFinishedResolution, isConnected, isPreconditionReady } = useGoogleMCAccount(); const [ value, setValue ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + const accountCreationResponse = merge( + autoAccountCreationResult, + resultCreateAccount + ); useEffect( () => { onCreateAccountLoading( resultCreateAccount?.loading ); @@ -43,14 +50,14 @@ const ConnectMC = ( { onCreateAccountLoading = noop } ) => { if ( resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 || - resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 + accountCreationResponse.response?.status === 403 || + accountCreationResponse.loading || + accountCreationResponse.response?.status === 503 ) { return ( ); diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 5c480fc9a5..0910b33c30 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -50,7 +50,9 @@ const ConnectedGoogleComboAccountCard = () => { accountCreationChecksResolved, accountsCreated, hasExistingMCAccounts, + mcAccountCreationResult, } = useAutoCreateAdsMCAccounts(); + const [ isManuallyCreatingMCAccount, setIsManuallyCreatingMCAccount ] = useState( false ); @@ -129,8 +131,10 @@ const ConnectedGoogleComboAccountCard = () => { helper={ getHelper() } indicator={ getIndicator() } /> +
); diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index 27b35b0671..7dbc462430 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -34,8 +34,8 @@ const useAutoCreateAdsMCAccounts = () => { * accountsCreatedRef - Indicates if the accounts have been created. */ const isCreatingBothAccountsRef = useRef( false ); - const isCreatingAdsAccountsRef = useRef( false ); - const isCreatingMCAccountsRef = useRef( false ); + const isCreatingAdsAccountRef = useRef( false ); + const isCreatingMCAccountRef = useRef( false ); const initHasExistingMCAccountsRef = useRef( null ); const initHasExistingAdsAccountsRef = useRef( null ); const accountsCreatedRef = useRef( false ); @@ -60,7 +60,7 @@ const useAutoCreateAdsMCAccounts = () => { hasFinishedResolution: hasFinishedResolutionForGoogleMCAccount, } = useGoogleMCAccount(); - const [ handleCreateAccount, { response } ] = useCreateMCAccount(); + const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); const [ upsertAdsAccount, { loading } ] = useUpsertAdsAccount(); const isGoogleMCConnected = googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || @@ -117,36 +117,40 @@ const useAutoCreateAdsMCAccounts = () => { ! initHasExistingMCAccountsRef.current; const isCreatingAccounts = - isCreatingAdsAccountsRef.current || - isCreatingMCAccountsRef.current || + isCreatingAdsAccountRef.current || + isCreatingMCAccountRef.current || isCreatingBothAccountsRef.current; useEffect( () => { // Ads account check - if ( isCreatingAdsAccountsRef.current === true && ! loading ) { - isCreatingAdsAccountsRef.current = false; + if ( isCreatingAdsAccountRef.current === true && ! loading ) { + isCreatingAdsAccountRef.current = false; accountsCreatedRef.current = true; } // MC account check if ( - isCreatingMCAccountsRef.current === true && - response?.status === 200 + isCreatingMCAccountRef.current === true && + // We consider the creation process done even if we need to reclaim the URL + // or if we hit the limit of accounts created (status: 406) + [ 200, 403, 406, 503 ].includes( + resultCreateAccount?.response?.status + ) ) { - isCreatingMCAccountsRef.current = false; + isCreatingMCAccountRef.current = false; accountsCreatedRef.current = true; } // both accounts check if ( isCreatingBothAccountsRef.current === true && - response?.status === 200 && + resultCreateAccount?.response?.status === 200 && ! loading ) { isCreatingBothAccountsRef.current = false; accountsCreatedRef.current = true; } - }, [ response, loading ] ); + }, [ resultCreateAccount, loading ] ); useEffect( () => { const handleCreation = async () => { @@ -160,13 +164,13 @@ const useAutoCreateAdsMCAccounts = () => { } if ( shouldCreateAdsAccount ) { - isCreatingAdsAccountsRef.current = true; + isCreatingAdsAccountRef.current = true; await createAdsAccount(); return; } if ( shouldCreateMCAccount ) { - isCreatingMCAccountsRef.current = true; + isCreatingMCAccountRef.current = true; await createMCAccount(); return; } @@ -192,9 +196,10 @@ const useAutoCreateAdsMCAccounts = () => { return { accountCreationChecksResolved, hasExistingMCAccounts: initHasExistingMCAccountsRef.current, - isCreatingAdsAccount: isCreatingAdsAccountsRef.current, - isCreatingMCAccount: isCreatingMCAccountsRef.current, + isCreatingAdsAccount: isCreatingAdsAccountRef.current, + isCreatingMCAccount: isCreatingMCAccountRef.current, isCreatingBothAccounts: isCreatingBothAccountsRef.current, + mcAccountCreationResult: resultCreateAccount, isCreatingAccounts, accountsCreated: accountsCreatedRef.current, }; From 8707feaa2fcad93f207b1b82f897f2a75173f81f Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 21:16:33 +0400 Subject: [PATCH 23/69] Use useState. --- js/src/hooks/useAutoCreateAdsMCAccounts.js | 61 +++++++++++----------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index 7dbc462430..e1efe97d02 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { useEffect, useRef, useCallback } from '@wordpress/element'; +import { useEffect, useRef, useCallback, useState } from '@wordpress/element'; /** * Internal dependencies @@ -33,9 +33,10 @@ const useAutoCreateAdsMCAccounts = () => { * isCreatingAccountsRef - Indicates if the accounts are being created. * accountsCreatedRef - Indicates if the accounts have been created. */ - const isCreatingBothAccountsRef = useRef( false ); - const isCreatingAdsAccountRef = useRef( false ); - const isCreatingMCAccountRef = useRef( false ); + const [ isCreatingAdsAccount, setIsCreatingAdsAccount ] = useState( false ); + const [ isCreatingMCAccount, setIsCreatingMCAccount ] = useState( false ); + const [ isCreatingBothAccounts, setIsCreatingBothAccounts ] = + useState( false ); const initHasExistingMCAccountsRef = useRef( null ); const initHasExistingAdsAccountsRef = useRef( null ); const accountsCreatedRef = useRef( false ); @@ -117,40 +118,38 @@ const useAutoCreateAdsMCAccounts = () => { ! initHasExistingMCAccountsRef.current; const isCreatingAccounts = - isCreatingAdsAccountRef.current || - isCreatingMCAccountRef.current || - isCreatingBothAccountsRef.current; + isCreatingAdsAccount || isCreatingMCAccount || isCreatingBothAccounts; + // We consider the creation process done even if we need to reclaim the URL + // or if we hit the limit of accounts created (status: 406) + const mcAccountCreated = [ 200, 403, 406, 503 ].includes( + resultCreateAccount?.response?.status + ); useEffect( () => { // Ads account check - if ( isCreatingAdsAccountRef.current === true && ! loading ) { - isCreatingAdsAccountRef.current = false; + if ( isCreatingAdsAccount && ! loading ) { accountsCreatedRef.current = true; + setIsCreatingAdsAccount( false ); } // MC account check - if ( - isCreatingMCAccountRef.current === true && - // We consider the creation process done even if we need to reclaim the URL - // or if we hit the limit of accounts created (status: 406) - [ 200, 403, 406, 503 ].includes( - resultCreateAccount?.response?.status - ) - ) { - isCreatingMCAccountRef.current = false; + if ( isCreatingMCAccount && mcAccountCreated ) { + setIsCreatingMCAccount( false ); accountsCreatedRef.current = true; } // both accounts check - if ( - isCreatingBothAccountsRef.current === true && - resultCreateAccount?.response?.status === 200 && - ! loading - ) { - isCreatingBothAccountsRef.current = false; + if ( isCreatingBothAccounts && mcAccountCreated && ! loading ) { + setIsCreatingBothAccounts( false ); accountsCreatedRef.current = true; } - }, [ resultCreateAccount, loading ] ); + }, [ + loading, + isCreatingAdsAccount, + isCreatingMCAccount, + isCreatingBothAccounts, + mcAccountCreated, + ] ); useEffect( () => { const handleCreation = async () => { @@ -164,19 +163,19 @@ const useAutoCreateAdsMCAccounts = () => { } if ( shouldCreateAdsAccount ) { - isCreatingAdsAccountRef.current = true; + setIsCreatingAdsAccount( true ); await createAdsAccount(); return; } if ( shouldCreateMCAccount ) { - isCreatingMCAccountRef.current = true; + setIsCreatingMCAccount( true ); await createMCAccount(); return; } if ( shouldCreateBothAccounts ) { - isCreatingBothAccountsRef.current = true; + setIsCreatingBothAccounts( true ); await createBothAccounts(); } }; @@ -196,9 +195,9 @@ const useAutoCreateAdsMCAccounts = () => { return { accountCreationChecksResolved, hasExistingMCAccounts: initHasExistingMCAccountsRef.current, - isCreatingAdsAccount: isCreatingAdsAccountRef.current, - isCreatingMCAccount: isCreatingMCAccountRef.current, - isCreatingBothAccounts: isCreatingBothAccountsRef.current, + isCreatingAdsAccount, + isCreatingMCAccount, + isCreatingBothAccounts, mcAccountCreationResult: resultCreateAccount, isCreatingAccounts, accountsCreated: accountsCreatedRef.current, From 14a08e82af90628325ef9c020c576bf5d952a020 Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 10 Oct 2024 22:05:08 +0400 Subject: [PATCH 24/69] Add isConnected check. --- .../connect-mc/connect-mc.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index bb0e9e7c21..f70522836a 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -48,11 +48,12 @@ const ConnectMC = ( { } if ( - resultConnectMC.response?.status === 409 || - resultConnectMC.response?.status === 403 || - accountCreationResponse.response?.status === 403 || - accountCreationResponse.loading || - accountCreationResponse.response?.status === 503 + ! isConnected && + ( resultConnectMC.response?.status === 409 || + resultConnectMC.response?.status === 403 || + accountCreationResponse.response?.status === 403 || + accountCreationResponse.loading || + accountCreationResponse.response?.status === 503 ) ) { return ( Date: Thu, 10 Oct 2024 23:00:46 +0400 Subject: [PATCH 25/69] Use single hook. --- .../connect-mc/connect-mc-footer.js | 8 ++++- .../connect-mc/connect-mc.js | 33 +++++++++---------- .../connected-google-combo-account-card.js | 14 ++++++-- .../disconnect-account-button.js | 4 ++- js/src/hooks/useAutoCreateAdsMCAccounts.js | 7 ++-- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js index 3fdd7a8d7f..b283d447ef 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js @@ -24,10 +24,16 @@ import DisconnectAccountButton from '.~/components/google-mc-account-card/discon const ConnectMCFooter = ( { isConnected, resultConnectMC, + resultCreateAccount, handleCreateAccount, } ) => { + const handleDisconnect = () => { + resultConnectMC?.reset(); + resultCreateAccount?.reset(); + }; + if ( isConnected ) { - return ; + return ; } return ( diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index f70522836a..da7ffb53ab 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -2,15 +2,13 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useState, useEffect } from '@wordpress/element'; +import { useEffect } from '@wordpress/element'; import classNames from 'classnames'; -import { noop, merge } from 'lodash'; +import { noop } from 'lodash'; /** * Internal dependencies */ -import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; -import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectAccountCard from '../connect-account-card'; import ConnectMCBody from './connect-mc-body'; @@ -26,18 +24,16 @@ import AccountConnectionStatus from '.~/components/google-mc-account-card/accoun */ const ConnectMC = ( { + merchantCenterID, + setMerchantCenterID, + createMCAccount, + connectMCAccount, onCreateAccountLoading = noop, - autoAccountCreationResult, } ) => { const { hasFinishedResolution, isConnected, isPreconditionReady } = useGoogleMCAccount(); - const [ value, setValue ] = useState(); - const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( value ); - const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); - const accountCreationResponse = merge( - autoAccountCreationResult, - resultCreateAccount - ); + const [ handleConnectMC, resultConnectMC ] = connectMCAccount; + const [ handleCreateAccount, resultCreateAccount ] = createMCAccount; useEffect( () => { onCreateAccountLoading( resultCreateAccount?.loading ); @@ -51,14 +47,14 @@ const ConnectMC = ( { ! isConnected && ( resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || - accountCreationResponse.response?.status === 403 || - accountCreationResponse.loading || - accountCreationResponse.response?.status === 503 ) + resultCreateAccount.response?.status === 403 || + resultCreateAccount.loading || + resultCreateAccount.response?.status === 503 ) ) { return ( ); @@ -79,8 +75,8 @@ const ConnectMC = ( { ) } body={ } diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 0910b33c30..d122a2bf7c 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -17,6 +17,8 @@ import './connected-google-combo-account-card.scss'; import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectedIconLabel from '../connected-icon-label'; +import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; +import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; /** @@ -32,6 +34,10 @@ import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; * @fires gla_google_account_connect_different_account_button_click */ const ConnectedGoogleComboAccountCard = () => { + const [ merchantCenterID, setMerchantCenterID ] = useState(); + const connectMCAccount = useConnectMCAccount( merchantCenterID ); + const createMCAccount = useCreateMCAccount(); + const { googleAdsAccount, hasFinishedResolution: hasFinishedResolutionForCurrentAdsAccount, @@ -50,8 +56,7 @@ const ConnectedGoogleComboAccountCard = () => { accountCreationChecksResolved, accountsCreated, hasExistingMCAccounts, - mcAccountCreationResult, - } = useAutoCreateAdsMCAccounts(); + } = useAutoCreateAdsMCAccounts( createMCAccount, connectMCAccount ); const [ isManuallyCreatingMCAccount, setIsManuallyCreatingMCAccount ] = useState( false ); @@ -134,7 +139,10 @@ const ConnectedGoogleComboAccountCard = () => {
); diff --git a/js/src/components/google-mc-account-card/disconnect-account-button.js b/js/src/components/google-mc-account-card/disconnect-account-button.js index 96b67ff2c3..f0f2ce19c1 100644 --- a/js/src/components/google-mc-account-card/disconnect-account-button.js +++ b/js/src/components/google-mc-account-card/disconnect-account-button.js @@ -2,6 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { noop } from 'lodash'; /** * Internal dependencies @@ -23,7 +24,7 @@ import { useAppDispatch } from '.~/data'; * * * @fires gla_mc_account_connect_different_account_button_click */ -const DisconnectAccountButton = () => { +const DisconnectAccountButton = ( { onDisconnect = noop } ) => { const { createNotice, removeNotice } = useDispatchCoreNotices(); const { invalidateResolution } = useAppDispatch(); @@ -57,6 +58,7 @@ const DisconnectAccountButton = () => { await fetchGoogleMCDisconnect(); invalidateResolution( 'getExistingGoogleMCAccounts', [] ); invalidateResolution( 'getGoogleMCAccount', [] ); + onDisconnect(); } catch ( error ) { createNotice( 'error', diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index e1efe97d02..c8c95e1f33 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -6,7 +6,6 @@ import { useEffect, useRef, useCallback, useState } from '@wordpress/element'; /** * Internal dependencies */ -import useCreateMCAccount from '../components/google-mc-account-card/useCreateMCAccount'; import useUpsertAdsAccount from '.~/hooks/useUpsertAdsAccount'; import useExistingGoogleAdsAccounts from '.~/hooks/useExistingGoogleAdsAccounts'; import useExistingGoogleMCAccounts from '.~/hooks/useExistingGoogleMCAccounts'; @@ -25,7 +24,7 @@ import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; * * @return {AutoCreateAccountsStatus} Object containing properties related to the account creation status. */ -const useAutoCreateAdsMCAccounts = () => { +const useAutoCreateAdsMCAccounts = ( createMerchantCenterAccount ) => { /** * Refs are used to avoid the re-render of the parent component. * @@ -61,7 +60,8 @@ const useAutoCreateAdsMCAccounts = () => { hasFinishedResolution: hasFinishedResolutionForGoogleMCAccount, } = useGoogleMCAccount(); - const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + const [ handleCreateAccount, resultCreateAccount ] = + createMerchantCenterAccount; const [ upsertAdsAccount, { loading } ] = useUpsertAdsAccount(); const isGoogleMCConnected = googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || @@ -198,7 +198,6 @@ const useAutoCreateAdsMCAccounts = () => { isCreatingAdsAccount, isCreatingMCAccount, isCreatingBothAccounts, - mcAccountCreationResult: resultCreateAccount, isCreatingAccounts, accountsCreated: accountsCreatedRef.current, }; From 25d2ff3b18ce6c679b1639e4bb4820ce3573a0f2 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 16 Oct 2024 19:06:32 +0400 Subject: [PATCH 26/69] Save WIP. --- .../account-creation-description.js | 8 ++++++-- .../connected-google-combo-account-card.js | 13 +++++++------ js/src/hooks/useAutoCreateAdsMCAccounts.js | 4 ++-- js/src/setup-mc/setup-stepper/index.js | 10 +++++----- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/js/src/components/google-combo-account-card/account-creation-description.js b/js/src/components/google-combo-account-card/account-creation-description.js index 61bdfca544..958702a1b9 100644 --- a/js/src/components/google-combo-account-card/account-creation-description.js +++ b/js/src/components/google-combo-account-card/account-creation-description.js @@ -18,12 +18,16 @@ import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; * @param {boolean} props.isCreatingBothAccounts Whether both, MC and Ads accounts are being created. * @param {boolean} props.isCreatingOnlyMCAccount Whether only the Merchant Center account is being created. * @param {boolean} props.isCreatingOnlyAdsAccount Whether only Google Ads account is being created. + * @param {boolean} props.isGoogleMCAccountConnected Whether we have a connected MC account. + * @param {boolean} props.isGoogleAdsAccountConnected Whether we have a connected Ads account. */ const AccountCreationDescription = ( { accountsCreated, isCreatingBothAccounts, isCreatingOnlyMCAccount, isCreatingOnlyAdsAccount, + isGoogleMCAccountConnected, + isGoogleAdsAccountConnected, } ) => { const { google } = useGoogleAccount(); const { @@ -96,7 +100,7 @@ const AccountCreationDescription = ( { return ( <>

{ google?.email }

- { ! isLoadingAccountsData && googleMCAccount.id > 0 && ( + { isGoogleMCAccountConnected && (

{ sprintf( // Translators: %s is the Merchant Center ID @@ -108,7 +112,7 @@ const AccountCreationDescription = ( { ) }

) } - { ! isLoadingAccountsData && googleAdsAccount.id > 0 && ( + { isGoogleAdsAccountConnected && (

{ sprintf( // Translators: %s is the Google Ads ID diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index beb163535f..d5cb3eb6ca 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -18,7 +18,7 @@ import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectedIconLabel from '../connected-icon-label'; import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; -import useCreateMCAccount from '.~/components/google-mc-account-card/useCreateMCAccount'; +import useCreateMCAccount from '.~/hooks/useCreateMCAccount'; import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; /** @@ -47,12 +47,8 @@ const ConnectedGoogleComboAccountCard = () => { isCreatingOnlyMCAccount, accountCreationChecksResolved, accountsCreated, - hasExistingMCAccounts, } = useAutoCreateAdsMCAccounts( createMCAccount, connectMCAccount ); - const [ isManuallyCreatingMCAccount, setIsManuallyCreatingMCAccount ] = - useState( false ); - if ( ! accountCreationChecksResolved || ! hasFinishedResolutionForCurrentAdsAccount || @@ -110,6 +106,12 @@ const ConnectedGoogleComboAccountCard = () => { isCreatingBothAccounts={ isCreatingBothAccounts } isCreatingOnlyAdsAccount={ isCreatingOnlyAdsAccount } isCreatingOnlyMCAccount={ isCreatingOnlyMCAccount } + isGoogleMCAccountConnected={ + isGoogleMCAccountConnected + } + isGoogleAdsAccountConnected={ + isGoogleAdsAccountConnected + } accountsCreated={ accountsCreated } /> } @@ -118,7 +120,6 @@ const ConnectedGoogleComboAccountCard = () => { /> { +const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { // Refs are used to avoid the re-render of the parent component. const isCreatingBothAccountsRef = useRef( false ); const isCreatingAdsAccountRef = useRef( false ); @@ -56,7 +56,7 @@ const useAutoCreateAdsMCAccounts = () => { hasFinishedResolution: hasFinishedResolutionForGoogleMCAccount, } = useGoogleMCAccount(); - const [ handleCreateAccount, { response } ] = useCreateMCAccount(); + const [ handleCreateAccount, { response } ] = createMCAccount; const [ upsertAdsAccount, { loading } ] = useUpsertAdsAccount(); const isGoogleMCConnected = googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || diff --git a/js/src/setup-mc/setup-stepper/index.js b/js/src/setup-mc/setup-stepper/index.js index 2c35a06064..05cdb1d310 100644 --- a/js/src/setup-mc/setup-stepper/index.js +++ b/js/src/setup-mc/setup-stepper/index.js @@ -26,12 +26,12 @@ const SetupStepper = () => { const { status, step } = mcSetup; - if ( status === 'complete' ) { - getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); - return null; - } + // if ( status === 'complete' ) { + // getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); + // return null; + // } - return ; + return ; }; export default SetupStepper; From a8d5db1bb51a2881bcfda9ed98db94078f00ea98 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 16 Oct 2024 21:53:26 +0400 Subject: [PATCH 27/69] Save WIP --- .../account-creation-description.js | 19 ++++--------------- .../connect-mc/connect-mc.js | 19 ++++++------------- .../connected-google-combo-account-card.js | 12 ++---------- .../connect-mc/index.js | 2 +- js/src/hooks/useAutoCreateAdsMCAccounts.js | 16 +++++++++++----- .../useConnectMCAccount.js | 0 6 files changed, 24 insertions(+), 44 deletions(-) rename js/src/{components/google-mc-account-card => hooks}/useConnectMCAccount.js (100%) diff --git a/js/src/components/google-combo-account-card/account-creation-description.js b/js/src/components/google-combo-account-card/account-creation-description.js index 958702a1b9..e41476eb48 100644 --- a/js/src/components/google-combo-account-card/account-creation-description.js +++ b/js/src/components/google-combo-account-card/account-creation-description.js @@ -14,7 +14,6 @@ import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; * Renders the description for the account creation card. * * @param {Object} props Props. - * @param {boolean} props.accountsCreated Whether accounts have been created. * @param {boolean} props.isCreatingBothAccounts Whether both, MC and Ads accounts are being created. * @param {boolean} props.isCreatingOnlyMCAccount Whether only the Merchant Center account is being created. * @param {boolean} props.isCreatingOnlyAdsAccount Whether only Google Ads account is being created. @@ -22,7 +21,6 @@ import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; * @param {boolean} props.isGoogleAdsAccountConnected Whether we have a connected Ads account. */ const AccountCreationDescription = ( { - accountsCreated, isCreatingBothAccounts, isCreatingOnlyMCAccount, isCreatingOnlyAdsAccount, @@ -30,20 +28,9 @@ const AccountCreationDescription = ( { isGoogleAdsAccountConnected, } ) => { const { google } = useGoogleAccount(); - const { - googleMCAccount, - hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount, - } = useGoogleMCAccount(); + const { googleMCAccount } = useGoogleMCAccount(); - const { - googleAdsAccount, - hasFinishedResolution: hasFinishedResolutionForCurrentAdsAccount, - } = useGoogleAdsAccount(); - - const isLoadingAccountsData = - accountsCreated && - ( ! hasFinishedResolutionForCurrentMCAccount || - ! hasFinishedResolutionForCurrentAdsAccount ); + const { googleAdsAccount } = useGoogleAdsAccount(); const getDescription = () => { if ( @@ -100,6 +87,7 @@ const AccountCreationDescription = ( { return ( <>

{ google?.email }

+ { isGoogleMCAccountConnected && (

{ sprintf( @@ -112,6 +100,7 @@ const AccountCreationDescription = ( { ) }

) } + { isGoogleAdsAccountConnected && (

{ sprintf( diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index da7ffb53ab..8aefb7ced7 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -2,9 +2,8 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useEffect } from '@wordpress/element'; +import { useState } from '@wordpress/element'; import classNames from 'classnames'; -import { noop } from 'lodash'; /** * Internal dependencies @@ -15,6 +14,7 @@ import ConnectMCBody from './connect-mc-body'; import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; +import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -23,22 +23,15 @@ import AccountConnectionStatus from '.~/components/google-mc-account-card/accoun * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. */ -const ConnectMC = ( { - merchantCenterID, - setMerchantCenterID, - createMCAccount, - connectMCAccount, - onCreateAccountLoading = noop, -} ) => { +const ConnectMC = ( { createMCAccount } ) => { + const [ merchantCenterID, setMerchantCenterID ] = useState(); + const connectMCAccount = useConnectMCAccount( merchantCenterID ); + const { hasFinishedResolution, isConnected, isPreconditionReady } = useGoogleMCAccount(); const [ handleConnectMC, resultConnectMC ] = connectMCAccount; const [ handleCreateAccount, resultCreateAccount ] = createMCAccount; - useEffect( () => { - onCreateAccountLoading( resultCreateAccount?.loading ); - }, [ resultCreateAccount, onCreateAccountLoading ] ); - if ( ! hasFinishedResolution ) { return ; } diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index d5cb3eb6ca..6e2a4e2b7a 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -17,7 +17,6 @@ import './connected-google-combo-account-card.scss'; import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; import ConnectedIconLabel from '../connected-icon-label'; -import useConnectMCAccount from '.~/components/google-mc-account-card/useConnectMCAccount'; import useCreateMCAccount from '.~/hooks/useCreateMCAccount'; import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; @@ -26,8 +25,6 @@ import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; * It will also kickoff Ads and Merchant Center account creation if the user does not have accounts. */ const ConnectedGoogleComboAccountCard = () => { - const [ merchantCenterID, setMerchantCenterID ] = useState(); - const connectMCAccount = useConnectMCAccount( merchantCenterID ); const createMCAccount = useCreateMCAccount(); const { @@ -47,7 +44,7 @@ const ConnectedGoogleComboAccountCard = () => { isCreatingOnlyMCAccount, accountCreationChecksResolved, accountsCreated, - } = useAutoCreateAdsMCAccounts( createMCAccount, connectMCAccount ); + } = useAutoCreateAdsMCAccounts( createMCAccount ); if ( ! accountCreationChecksResolved || @@ -119,12 +116,7 @@ const ConnectedGoogleComboAccountCard = () => { indicator={ getIndicator() } /> - +

); }; diff --git a/js/src/components/google-mc-account-card/connect-mc/index.js b/js/src/components/google-mc-account-card/connect-mc/index.js index 0b220843f8..3583d81ad8 100644 --- a/js/src/components/google-mc-account-card/connect-mc/index.js +++ b/js/src/components/google-mc-account-card/connect-mc/index.js @@ -15,7 +15,7 @@ import Subsection from '.~/wcdl/subsection'; import ContentButtonLayout from '.~/components/content-button-layout'; import AccountCard, { APPEARANCE } from '.~/components/account-card'; import CreateAccountButton from '../create-account-button'; -import useConnectMCAccount from '../useConnectMCAccount'; +import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; import AccountConnectionStatus from '../account-connection-status'; import useCreateMCAccount from '../../../hooks/useCreateMCAccount'; import './index.scss'; diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index ef18e88e75..1f99bccf0b 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -6,7 +6,6 @@ import { useEffect, useRef } from '@wordpress/element'; /** * Internal dependencies */ -import useCreateMCAccount from './useCreateMCAccount'; import useUpsertAdsAccount from '.~/hooks/useUpsertAdsAccount'; import useExistingGoogleAdsAccounts from '.~/hooks/useExistingGoogleAdsAccounts'; import useExistingGoogleMCAccounts from '.~/hooks/useExistingGoogleMCAccounts'; @@ -62,8 +61,8 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE; - const hasExistingMCAccount = - isGoogleMCConnected || existingMCAccounts?.length > 0; + const hasExistingMCAccount = false; + // isGoogleMCConnected || existingMCAccounts?.length > 0; const hasExistingAdsAccount = hasGoogleAdsConnection || existingAdsAccounts?.length > 0; @@ -105,6 +104,10 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { isCreatingBothAccountsRef.current; useEffect( () => { + if ( ! response && ! loading ) { + return; + } + // Ads account check if ( isCreatingAdsAccountRef.current === true && ! loading ) { isCreatingAdsAccountRef.current = false; @@ -114,8 +117,10 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { // MC account check if ( isCreatingMCAccountRef.current === true && - response?.status === 200 + // 406: account limit reached + [ 200, 403, 406, 503 ].includes( response?.status ) ) { + console.log( 'MC heree Finished' ); isCreatingMCAccountRef.current = false; accountsCreatedRef.current = true; } @@ -123,9 +128,10 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { // both accounts check if ( isCreatingBothAccountsRef.current === true && - response?.status === 200 && + [ 200, 403, 406, 503 ].includes( response?.status ) && ! loading ) { + console.log( 'heree Finished' ); isCreatingBothAccountsRef.current = false; accountsCreatedRef.current = true; } diff --git a/js/src/components/google-mc-account-card/useConnectMCAccount.js b/js/src/hooks/useConnectMCAccount.js similarity index 100% rename from js/src/components/google-mc-account-card/useConnectMCAccount.js rename to js/src/hooks/useConnectMCAccount.js From 87a2046a09a295dd1581dc607a9343d1060f8c6f Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 16 Oct 2024 22:33:28 +0400 Subject: [PATCH 28/69] Changes to how we manage the state. --- .../connected-google-combo-account-card.js | 7 +- js/src/hooks/useAutoCreateAdsMCAccounts.js | 132 ++++++++++-------- 2 files changed, 82 insertions(+), 57 deletions(-) diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index 6e2a4e2b7a..f6d37a3429 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -25,6 +25,8 @@ import { GOOGLE_ADS_ACCOUNT_STATUS } from '.~/constants'; * It will also kickoff Ads and Merchant Center account creation if the user does not have accounts. */ const ConnectedGoogleComboAccountCard = () => { + // We are using a centralized hook which will be used when auto creating the MC account or manually creating a MC account + // since we need to potentially show the reclaim url in a single place across both scenarios. const createMCAccount = useCreateMCAccount(); const { @@ -44,6 +46,7 @@ const ConnectedGoogleComboAccountCard = () => { isCreatingOnlyMCAccount, accountCreationChecksResolved, accountsCreated, + hasExistingMCAccount, } = useAutoCreateAdsMCAccounts( createMCAccount ); if ( @@ -116,7 +119,9 @@ const ConnectedGoogleComboAccountCard = () => { indicator={ getIndicator() } /> - + { hasExistingMCAccount && ( + + ) } ); }; diff --git a/js/src/hooks/useAutoCreateAdsMCAccounts.js b/js/src/hooks/useAutoCreateAdsMCAccounts.js index 1f99bccf0b..047ed30ef5 100644 --- a/js/src/hooks/useAutoCreateAdsMCAccounts.js +++ b/js/src/hooks/useAutoCreateAdsMCAccounts.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { useEffect, useRef } from '@wordpress/element'; +import { useEffect, useRef, useState } from '@wordpress/element'; /** * Internal dependencies @@ -14,8 +14,6 @@ import useGoogleMCAccount from './useGoogleMCAccount'; import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; /** - * Custom hook to handle the creation of Google Merchant Center (MC) and Google Ads accounts. - * * @typedef {Object} AutoCreateAccountsStatus * @property {boolean} accountsCreated Indicates if both the Google Ads and Google Merchant Center accounts have been successfully created. * @property {boolean} accountCreationChecksResolved Indicates if the account creation checks (for existing accounts) have been resolved. @@ -23,33 +21,43 @@ import { GOOGLE_MC_ACCOUNT_STATUS } from '.~/constants'; * @property {boolean} isCreatingOnlyAdsAccount Indicates if only the Google Ads account is currently being created. * @property {boolean} isCreatingBothAccounts Indicates if both the Google Ads and Google Merchant Center accounts are currently being created. * @property {boolean} isCreatingOnlyMCAccount Indicates if only the Google Merchant Center account is currently being created. - * + * @property {boolean} hasExistingMCAccount Indicates if the user has existing Google Merchant Center account(s). + */ + +/** + * Custom hook to handle the creation of Google Merchant Center (MC) and Google Ads accounts. + * @param {Object} createMCAccount Result of the useCreateMCAccount hook from the parent component. * @return {AutoCreateAccountsStatus} Object containing properties related to the account creation status. */ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { - // Refs are used to avoid the re-render of the parent component. - const isCreatingBothAccountsRef = useRef( false ); - const isCreatingAdsAccountRef = useRef( false ); - const isCreatingMCAccountRef = useRef( false ); + const [ accountsState, setAccountsState ] = useState( { + isCreatingBothAccounts: false, + isCreatingAdsAccount: false, + isCreatingMCAccount: false, + accountsCreated: false, + } ); + const { + isCreatingBothAccounts, + isCreatingAdsAccount, + isCreatingMCAccount, + accountsCreated, + } = accountsState; + const initHasExistingMCAccountsRef = useRef( null ); const initHasExistingAdsAccountsRef = useRef( null ); - const accountsCreatedRef = useRef( false ); const { data: existingMCAccounts, hasFinishedResolution: hasFinishedResolutionForExistingMCAccounts, } = useExistingGoogleMCAccounts(); - const { existingAccounts: existingAdsAccounts, hasFinishedResolution: hasFinishedResolutionForExistingAdsAccount, } = useExistingGoogleAdsAccounts(); - const { hasFinishedResolution: hasFinishedResolutionForGoogleAdsAccount, hasGoogleAdsConnection, } = useGoogleAdsAccount(); - const { googleMCAccount, hasFinishedResolution: hasFinishedResolutionForGoogleMCAccount, @@ -57,12 +65,13 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { const [ handleCreateAccount, { response } ] = createMCAccount; const [ upsertAdsAccount, { loading } ] = useUpsertAdsAccount(); - const isGoogleMCConnected = - googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || - googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE; - const hasExistingMCAccount = false; - // isGoogleMCConnected || existingMCAccounts?.length > 0; + const isGoogleMCConnected = [ + GOOGLE_MC_ACCOUNT_STATUS.CONNECTED, + GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE, + ].includes( googleMCAccount?.status ); + const hasExistingMCAccount = + isGoogleMCConnected || existingMCAccounts?.length > 0; const hasExistingAdsAccount = hasGoogleAdsConnection || existingAdsAccounts?.length > 0; @@ -85,83 +94,92 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { const accountCreationChecksResolved = initHasExistingAdsAccountsRef.current !== null && initHasExistingMCAccountsRef.current !== null; - const shouldCreateAdsAccount = initHasExistingAdsAccountsRef.current === false && initHasExistingMCAccountsRef.current === true; - const shouldCreateMCAccount = initHasExistingAdsAccountsRef.current === true && initHasExistingMCAccountsRef.current === false; - const shouldCreateBothAccounts = ! initHasExistingAdsAccountsRef.current && ! initHasExistingMCAccountsRef.current; - const isCreatingAccounts = - isCreatingAdsAccountRef.current || - isCreatingMCAccountRef.current || - isCreatingBothAccountsRef.current; + isCreatingAdsAccount || isCreatingMCAccount || isCreatingBothAccounts; useEffect( () => { if ( ! response && ! loading ) { return; } - // Ads account check - if ( isCreatingAdsAccountRef.current === true && ! loading ) { - isCreatingAdsAccountRef.current = false; - accountsCreatedRef.current = true; + if ( isCreatingAdsAccount && ! loading ) { + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingAdsAccount: false, + accountsCreated: true, + } ) ); + return; } - // MC account check - if ( - isCreatingMCAccountRef.current === true && - // 406: account limit reached - [ 200, 403, 406, 503 ].includes( response?.status ) - ) { - console.log( 'MC heree Finished' ); - isCreatingMCAccountRef.current = false; - accountsCreatedRef.current = true; + const mcAccountCreated = [ 200, 403, 406, 503 ].includes( + response?.status + ); + if ( isCreatingMCAccount && mcAccountCreated ) { + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingMCAccount: false, + accountsCreated: true, + } ) ); + return; } - // both accounts check - if ( - isCreatingBothAccountsRef.current === true && - [ 200, 403, 406, 503 ].includes( response?.status ) && - ! loading - ) { - console.log( 'heree Finished' ); - isCreatingBothAccountsRef.current = false; - accountsCreatedRef.current = true; + if ( isCreatingBothAccounts && mcAccountCreated && ! loading ) { + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingBothAccounts: false, + accountsCreated: true, + } ) ); } - }, [ response, loading ] ); + }, [ + response, + loading, + isCreatingAdsAccount, + isCreatingBothAccounts, + isCreatingMCAccount, + ] ); useEffect( () => { const handleCreation = async () => { - // Bail out if we haven't resolved the existing accounts checks yet or there's a creation in progress or the accounts have been created. if ( ! accountCreationChecksResolved || isCreatingAccounts || - accountsCreatedRef.current + accountsCreated ) { return; } if ( shouldCreateAdsAccount ) { - isCreatingAdsAccountRef.current = true; + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingAdsAccount: true, + } ) ); await upsertAdsAccount(); return; } if ( shouldCreateMCAccount ) { - isCreatingMCAccountRef.current = true; + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingMCAccount: true, + } ) ); await handleCreateAccount(); return; } if ( shouldCreateBothAccounts ) { - isCreatingBothAccountsRef.current = true; + setAccountsState( ( prevState ) => ( { + ...prevState, + isCreatingBothAccounts: true, + } ) ); await handleCreateAccount(); await upsertAdsAccount(); } @@ -176,15 +194,17 @@ const useAutoCreateAdsMCAccounts = ( createMCAccount ) => { shouldCreateBothAccounts, handleCreateAccount, upsertAdsAccount, + accountsCreated, ] ); return { accountCreationChecksResolved, - isCreatingOnlyAdsAccount: isCreatingAdsAccountRef.current, - isCreatingOnlyMCAccount: isCreatingMCAccountRef.current, - isCreatingBothAccounts: isCreatingBothAccountsRef.current, + isCreatingOnlyAdsAccount: isCreatingAdsAccount, + isCreatingOnlyMCAccount: isCreatingMCAccount, + isCreatingBothAccounts, isCreatingAccounts, - accountsCreated: accountsCreatedRef.current, + accountsCreated, + hasExistingMCAccount, }; }; From 06960d904d3d0b7bde23d9b3c1aa5d99adf0b313 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 16 Oct 2024 22:55:48 +0400 Subject: [PATCH 29/69] Fix select rendering. --- .../connect-mc/connect-mc-body.js | 21 ++++++++-------- .../connect-mc/connect-mc.js | 25 +++++++++++++------ .../connected-google-combo-account-card.js | 1 - .../connected-google-combo-account-card.scss | 3 --- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js index d4106691c4..8fd7a50c2f 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-body.js @@ -19,6 +19,15 @@ import LoadingLabel from '.~/components/loading-label'; * @property {number} id The account ID to be connected. */ +const nonInteractableProps = { + suffix: ' ', + style: { + pointerEvents: 'none', + }, + readOnly: true, + tabIndex: -1, +}; + /** * ConnectMCBody component. * @@ -42,22 +51,12 @@ const ConnectMCBody = ( { isConnecting, handleConnectMC, } ) => { - let selectControlProps = {}; - if ( isConnected ) { - selectControlProps = { - suffix: ' ', - tabIndex: '-1', - readOnly: true, - className: 'gla-google-combo-service-connected-select-control', - }; - } - return ( { isConnected && ( diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 8aefb7ced7..01f09fe5fa 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -2,7 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; +import { useEffect, useState } from '@wordpress/element'; import classNames from 'classnames'; /** @@ -24,14 +24,23 @@ import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; */ const ConnectMC = ( { createMCAccount } ) => { - const [ merchantCenterID, setMerchantCenterID ] = useState(); - const connectMCAccount = useConnectMCAccount( merchantCenterID ); - - const { hasFinishedResolution, isConnected, isPreconditionReady } = - useGoogleMCAccount(); + const { + googleMCAccount, + hasFinishedResolution, + isConnected, + isPreconditionReady, + } = useGoogleMCAccount(); + const [ accountID, setAccountID ] = useState(); + const connectMCAccount = useConnectMCAccount( accountID ); const [ handleConnectMC, resultConnectMC ] = connectMCAccount; const [ handleCreateAccount, resultCreateAccount ] = createMCAccount; + useEffect( () => { + if ( isConnected ) { + setAccountID( googleMCAccount.id ); + } + }, [ googleMCAccount, isConnected ] ); + if ( ! hasFinishedResolution ) { return ; } @@ -68,8 +77,8 @@ const ConnectMC = ( { createMCAccount } ) => { ) } body={ Date: Wed, 16 Oct 2024 23:00:43 +0400 Subject: [PATCH 30/69] Revert changes --- js/src/setup-mc/setup-stepper/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/src/setup-mc/setup-stepper/index.js b/js/src/setup-mc/setup-stepper/index.js index 05cdb1d310..2c35a06064 100644 --- a/js/src/setup-mc/setup-stepper/index.js +++ b/js/src/setup-mc/setup-stepper/index.js @@ -26,12 +26,12 @@ const SetupStepper = () => { const { status, step } = mcSetup; - // if ( status === 'complete' ) { - // getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); - // return null; - // } + if ( status === 'complete' ) { + getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); + return null; + } - return ; + return ; }; export default SetupStepper; From 96c11a2074b70f023aadf6a17c553a55020c2ef9 Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 17 Oct 2024 11:53:47 +0400 Subject: [PATCH 31/69] Update JSDocs. --- .../google-combo-account-card/connect-mc/connect-mc-footer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js index b283d447ef..ded57c7e15 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js @@ -19,6 +19,7 @@ import DisconnectAccountButton from '.~/components/google-mc-account-card/discon * @param {Object} props * @param {boolean} props.isConnected Whether the Merchant Center account is connected. * @param {Object} props.resultConnectMC The result of the connection request, used to handle loading state. + * @param {Object} props.resultCreateAccount The result of the create account request. * @param {Function} props.handleCreateAccount Callback function for creating a new Merchant Center account. */ const ConnectMCFooter = ( { From 4eb41ac333f25030f3612a3ee903eb3efc873601 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 15:31:06 +0400 Subject: [PATCH 32/69] Do not use template literals. --- js/src/hooks/useCreateMCAccount.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/hooks/useCreateMCAccount.js b/js/src/hooks/useCreateMCAccount.js index 39cc2978db..16b93b8dcf 100644 --- a/js/src/hooks/useCreateMCAccount.js +++ b/js/src/hooks/useCreateMCAccount.js @@ -16,7 +16,7 @@ const useCreateMCAccount = () => { const { createNotice } = useDispatchCoreNotices(); const { invalidateResolution } = useAppDispatch(); const [ fetchCreateMCAccount, result ] = useApiFetchCallback( { - path: `/wc/gla/mc/accounts`, + path: '/wc/gla/mc/accounts', method: 'POST', } ); From 6696ee6092d33f6f552cc6fe68400ac0edd1d5f1 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 18:38:57 +0400 Subject: [PATCH 33/69] Update hooks. --- .../connect-mc/connect-mc.js | 25 ++++++++------- .../connected-google-combo-account-card.js | 32 +++++++++++++------ js/src/hooks/useCreateMCAccount.js | 11 ++----- js/src/hooks/useGoogleMCAccount.js | 10 ++---- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index 01f09fe5fa..23ad71b970 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -15,6 +15,7 @@ import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; +import useCreateMCAccount from '.~/hooks/useCreateMCAccount'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -23,30 +24,31 @@ import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; * @property {string} context (`switch-url`|`reclaim-url`) - indicate the button is clicked from which step. */ -const ConnectMC = ( { createMCAccount } ) => { +const ConnectMC = () => { const { googleMCAccount, hasFinishedResolution, - isConnected, + hasGoogleMCConnection, isPreconditionReady, } = useGoogleMCAccount(); const [ accountID, setAccountID ] = useState(); - const connectMCAccount = useConnectMCAccount( accountID ); - const [ handleConnectMC, resultConnectMC ] = connectMCAccount; - const [ handleCreateAccount, resultCreateAccount ] = createMCAccount; + const [ handleConnectMC, resultConnectMC ] = + useConnectMCAccount( accountID ); + const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); + console.log( resultCreateAccount ); useEffect( () => { - if ( isConnected ) { + if ( hasGoogleMCConnection ) { setAccountID( googleMCAccount.id ); } - }, [ googleMCAccount, isConnected ] ); + }, [ googleMCAccount, hasGoogleMCConnection ] ); if ( ! hasFinishedResolution ) { return ; } if ( - ! isConnected && + ! hasGoogleMCConnection && ( resultConnectMC.response?.status === 409 || resultConnectMC.response?.status === 403 || resultCreateAccount.response?.status === 403 || @@ -65,7 +67,8 @@ const ConnectMC = ( { createMCAccount } ) => { return ( { } footer={ { const { googleMCAccount, + hasGoogleMCConnection, hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount, } = useGoogleMCAccount(); + const { data: accounts } = useExistingGoogleMCAccounts(); + const { hasDetermined, creatingWhich } = useAutoCreateAdsMCAccounts(); const { text, subText } = getAccountCreationTexts( wasCreatingAccounts ); @@ -74,17 +78,25 @@ const ConnectedGoogleComboAccountCard = () => { return } />; } + const showConnectMCCard = ! hasGoogleMCConnection && accounts.length > 0; + return ( - } - helper={ ! displayAccountDetails ? subText : null } - indicator={ - - } - /> + <> + + } + helper={ ! displayAccountDetails ? subText : null } + indicator={ + + } + /> + + { showConnectMCCard && } + ); }; diff --git a/js/src/hooks/useCreateMCAccount.js b/js/src/hooks/useCreateMCAccount.js index 16b93b8dcf..a503f7354d 100644 --- a/js/src/hooks/useCreateMCAccount.js +++ b/js/src/hooks/useCreateMCAccount.js @@ -2,7 +2,6 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useRef } from '@wordpress/element'; /** * Internal dependencies @@ -12,18 +11,13 @@ import useApiFetchCallback from '.~/hooks/useApiFetchCallback'; import useDispatchCoreNotices from '.~/hooks/useDispatchCoreNotices'; const useCreateMCAccount = () => { - const singletonRef = useRef( null ); const { createNotice } = useDispatchCoreNotices(); const { invalidateResolution } = useAppDispatch(); const [ fetchCreateMCAccount, result ] = useApiFetchCallback( { - path: '/wc/gla/mc/accounts', + path: `/wc/gla/mc/accounts`, method: 'POST', } ); - if ( singletonRef.current ) { - return singletonRef.current; - } - const handleCreateAccount = async () => { try { await fetchCreateMCAccount( { @@ -45,8 +39,7 @@ const useCreateMCAccount = () => { } }; - singletonRef.current = [ handleCreateAccount, result ]; - return singletonRef.current; + return [ handleCreateAccount, result ]; }; export default useCreateMCAccount; diff --git a/js/src/hooks/useGoogleMCAccount.js b/js/src/hooks/useGoogleMCAccount.js index 64bfc6ffe4..7098b27445 100644 --- a/js/src/hooks/useGoogleMCAccount.js +++ b/js/src/hooks/useGoogleMCAccount.js @@ -46,7 +46,7 @@ const useGoogleMCAccount = () => { // has not been granted necessary access permissions for Google Merchant Center, then // the precondition doesn't meet. isPreconditionReady: false, - isConnected: false, + hasGoogleMCConnection: false, }; } @@ -56,11 +56,6 @@ const useGoogleMCAccount = () => { googleMCAccountSelector ); - const hasGoogleMCConnection = [ - GOOGLE_MC_ACCOUNT_STATUS.CONNECTED, - GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE, - ].includes( googleMCAccount?.status ); - return { googleMCAccount, isResolving: isResolvingGoogleMCAccount, @@ -68,11 +63,10 @@ const useGoogleMCAccount = () => { googleMCAccountSelector ), isPreconditionReady: true, - hasGoogleMCConnection, // MC is ready when we have a connection and preconditions are met. // The `link_ads` step will be resolved when the Ads account is connected // since these can be connected in any order. - isConnected: + hasGoogleMCConnection: googleMCAccount?.status === GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || ( googleMCAccount?.status === From 67b8d3b96f167e2322cd7dfbf354e998fc6fb322 Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 20:36:57 +0400 Subject: [PATCH 34/69] Revert change. --- js/src/hooks/useGoogleMCAccount.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/js/src/hooks/useGoogleMCAccount.js b/js/src/hooks/useGoogleMCAccount.js index 7098b27445..424ed9d3a9 100644 --- a/js/src/hooks/useGoogleMCAccount.js +++ b/js/src/hooks/useGoogleMCAccount.js @@ -55,6 +55,10 @@ const useGoogleMCAccount = () => { const isResolvingGoogleMCAccount = selector.isResolving( googleMCAccountSelector ); + const hasGoogleMCConnection = [ + GOOGLE_MC_ACCOUNT_STATUS.CONNECTED, + GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE, + ].includes( googleMCAccount?.status ); return { googleMCAccount, @@ -63,15 +67,7 @@ const useGoogleMCAccount = () => { googleMCAccountSelector ), isPreconditionReady: true, - // MC is ready when we have a connection and preconditions are met. - // The `link_ads` step will be resolved when the Ads account is connected - // since these can be connected in any order. - hasGoogleMCConnection: - googleMCAccount?.status === - GOOGLE_MC_ACCOUNT_STATUS.CONNECTED || - ( googleMCAccount?.status === - GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE && - googleMCAccount?.step === 'link_ads' ), + hasGoogleMCConnection, }; }, [ From ba5c054876e102eb55b73d49d078bc90e5639a7b Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 20:40:07 +0400 Subject: [PATCH 35/69] Revert change. --- js/src/setup-mc/setup-stepper/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/src/setup-mc/setup-stepper/index.js b/js/src/setup-mc/setup-stepper/index.js index 05cdb1d310..2c35a06064 100644 --- a/js/src/setup-mc/setup-stepper/index.js +++ b/js/src/setup-mc/setup-stepper/index.js @@ -26,12 +26,12 @@ const SetupStepper = () => { const { status, step } = mcSetup; - // if ( status === 'complete' ) { - // getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); - // return null; - // } + if ( status === 'complete' ) { + getHistory().replace( getNewPath( {}, '/google/dashboard' ) ); + return null; + } - return ; + return ; }; export default SetupStepper; From 6fd6dc44b7233c9f687dab752dd465e29469679a Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 20:53:07 +0400 Subject: [PATCH 36/69] Remove unused file. --- .../account-creation-description.js | 127 ------------------ .../connect-mc/connect-mc-footer.js | 10 +- .../connected-google-combo-account-card.js | 6 +- 3 files changed, 8 insertions(+), 135 deletions(-) delete mode 100644 js/src/components/google-combo-account-card/account-creation-description.js diff --git a/js/src/components/google-combo-account-card/account-creation-description.js b/js/src/components/google-combo-account-card/account-creation-description.js deleted file mode 100644 index 21469ae56c..0000000000 --- a/js/src/components/google-combo-account-card/account-creation-description.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * External dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import useGoogleAccount from '.~/hooks/useGoogleAccount'; -import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; -import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; -import { - CREATING_ADS_ACCOUNT, - CREATING_BOTH_ACCOUNTS, - CREATING_MC_ACCOUNT, -} from './constants'; - -/** - * Renders the description for the account creation card. - * - * @param {Object} props Props. - * @param {string|null} props.isCreatingWhichAccount The type of account that is being created. Possible values are 'ads', 'mc', or 'both'. - */ -const AccountCreationDescription = ( { isCreatingWhichAccount } ) => { - const { google, hasFinishedResolution } = useGoogleAccount(); - const { googleMCAccount } = useGoogleMCAccount(); - const { googleAdsAccount } = useGoogleAdsAccount(); - - if ( ! hasFinishedResolution ) { - return null; - } - - const getDescription = () => { - if ( isCreatingWhichAccount ) { - switch ( isCreatingWhichAccount ) { - case CREATING_BOTH_ACCOUNTS: - return ( -

- { __( - 'You don’t have Merchant Center nor Google Ads accounts, so we’re creating them for you.', - 'google-listings-and-ads' - ) } -

- ); - - case CREATING_ADS_ACCOUNT: - return ( - <> -

- { __( - 'You don’t have Google Ads account, so we’re creating one for you.', - 'google-listings-and-ads' - ) } -

- - { __( - 'Required to set up conversion measurement for your store.', - 'google-listings-and-ads' - ) } - - - ); - - case CREATING_MC_ACCOUNT: - return ( - <> -

- { __( - 'You don’t have Merchant Center account, so we’re creating one for you.', - 'google-listings-and-ads' - ) } -

- - { __( - 'Required to sync products so they show on Google.', - 'google-listings-and-ads' - ) } - - - ); - } - } - - const isCreatingAccounts = !! isCreatingWhichAccount; - const isGoogleAdsReady = - ! isCreatingAccounts && googleAdsAccount.id > 0; - const isGoogleMCReady = ! isCreatingAccounts && googleMCAccount.id > 0; - - return ( - <> -

{ google?.email }

- { isGoogleMCReady && ( -

- { sprintf( - // Translators: %s is the Merchant Center ID - __( - 'Merchant Center ID: %s', - 'google-listings-and-ads' - ), - googleMCAccount.id - ) } -

- ) } - { isGoogleAdsReady && ( -

- { sprintf( - // Translators: %s is the Google Ads ID - __( - 'Google Ads ID: %s', - 'google-listings-and-ads' - ), - googleAdsAccount.id - ) } -

- ) } - - ); - }; - - return ( -
- { getDescription() } -
- ); -}; - -export default AccountCreationDescription; diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js index ded57c7e15..27dbb84dde 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc-footer.js @@ -28,12 +28,12 @@ const ConnectMCFooter = ( { resultCreateAccount, handleCreateAccount, } ) => { - const handleDisconnect = () => { - resultConnectMC?.reset(); - resultCreateAccount?.reset(); - }; - if ( isConnected ) { + const handleDisconnect = () => { + resultConnectMC.reset(); + resultCreateAccount.reset(); + }; + return ; } diff --git a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js index aabeb123d0..d70222045d 100644 --- a/js/src/components/google-combo-account-card/connected-google-combo-account-card.js +++ b/js/src/components/google-combo-account-card/connected-google-combo-account-card.js @@ -77,11 +77,11 @@ const ConnectedGoogleComboAccountCard = () => { } // Show the Connect MC card if there's no connected accounts and there are existing accounts. + // The "Edit" button will be used to display the card within the connected state. const showConnectMCCard = ! hasGoogleMCConnection && accounts.length > 0; - console.log( creatingWhich, text, subText ); return ( - <> +
{ resultCreateMCAccount={ resultCreateMCAccount } /> ) } - +
); }; From c13c524410cd90962d22e47a886030e947f254ca Mon Sep 17 00:00:00 2001 From: asvinb Date: Wed, 23 Oct 2024 21:07:37 +0400 Subject: [PATCH 37/69] Review changes. --- .../google-combo-account-card/connect-mc/connect-mc.js | 8 +++----- .../connected-google-combo-account-card.js | 5 +++-- .../google-mc-account-card/connect-mc/index.js | 9 ++++----- js/src/hooks/useGoogleMCAccount.js | 8 ++++---- js/src/setup-mc/setup-stepper/setup-accounts/index.js | 9 ++++----- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index aef98d7a82..bb2f1cd9f9 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -46,11 +46,9 @@ const ConnectMC = ( { createMCAccount, resultCreateMCAccount } ) => { if ( ! hasGoogleMCConnection && - ( resultConnectMC.response?.status === 409 || - resultConnectMC.response?.status === 403 || - resultCreateMCAccount.response?.status === 403 || - resultCreateMCAccount.loading || - resultCreateMCAccount.response?.status === 503 ) + ( [ 403, 409 ].includes( resultConnectMC.response?.status ) || + [ 403, 503 ].includes( resultCreateMCAccount.response?.status ) || + resultCreateMCAccount.loading ) ) { return ( { const { googleMCAccount, - hasGoogleMCConnection, hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount, } = useGoogleMCAccount(); @@ -78,7 +77,9 @@ const ConnectedGoogleComboAccountCard = () => { // Show the Connect MC card if there's no connected accounts and there are existing accounts. // The "Edit" button will be used to display the card within the connected state. - const showConnectMCCard = ! hasGoogleMCConnection && accounts.length > 0; + // @TODO: review + // const showConnectMCCard = ! hasGoogleMCConnection && accounts.length > 0; + const showConnectMCCard = true; return (
diff --git a/js/src/components/google-mc-account-card/connect-mc/index.js b/js/src/components/google-mc-account-card/connect-mc/index.js index c8a74cd759..95c793b2d6 100644 --- a/js/src/components/google-mc-account-card/connect-mc/index.js +++ b/js/src/components/google-mc-account-card/connect-mc/index.js @@ -17,6 +17,7 @@ import AccountCard, { APPEARANCE } from '.~/components/account-card'; import CreateAccountButton from '../create-account-button'; import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; import useCreateMCAccount from '.~/hooks/useCreateMCAccount'; +import AccountConnectionStatus from '../account-connection-status'; import './index.scss'; /** @@ -42,11 +43,9 @@ const ConnectMC = () => { const [ handleCreateAccount, resultCreateAccount ] = useCreateMCAccount(); if ( - resultConnectMC.response?.status === 409 || - resultConnectMC.response?.status === 403 || - resultCreateAccount.response?.status === 403 || - resultCreateAccount.loading || - resultCreateAccount.response?.status === 503 + [ 403, 409 ].includes( resultConnectMC.response?.status ) || + [ 403, 503 ].includes( resultCreateAccount.response?.status ) || + resultCreateAccount.loading ) { return ( { } const selector = select( STORE_KEY ); - const googleMCAccount = selector[ googleMCAccountSelector ](); + const acc = selector[ googleMCAccountSelector ](); const isResolvingGoogleMCAccount = selector.isResolving( googleMCAccountSelector ); const hasGoogleMCConnection = [ GOOGLE_MC_ACCOUNT_STATUS.CONNECTED, GOOGLE_MC_ACCOUNT_STATUS.INCOMPLETE, - ].includes( googleMCAccount?.status ); + ].includes( acc?.status ); return { - googleMCAccount, + googleMCAccount: acc, isResolving: isResolvingGoogleMCAccount, hasFinishedResolution: selector.hasFinishedResolution( googleMCAccountSelector diff --git a/js/src/setup-mc/setup-stepper/setup-accounts/index.js b/js/src/setup-mc/setup-stepper/setup-accounts/index.js index c5e8becd5a..040879bd97 100644 --- a/js/src/setup-mc/setup-stepper/setup-accounts/index.js +++ b/js/src/setup-mc/setup-stepper/setup-accounts/index.js @@ -83,13 +83,12 @@ const SetupAccounts = ( props ) => { const { onContinue = () => {} } = props; const { jetpack } = useJetpackAccount(); const { google, scope } = useGoogleAccount(); - const { - googleMCAccount, - isPreconditionReady: isGMCPreconditionReady, - isConnected: isGoogleMCReady, - } = useGoogleMCAccount(); + const { googleMCAccount, isPreconditionReady: isGMCPreconditionReady } = + useGoogleMCAccount(); const { hasFinishedResolution } = useGoogleAdsAccount(); const isGoogleAdsReady = useGoogleAdsAccountReady(); + // @TODO: review + const isGoogleMCReady = true; /** * When jetpack is loading, or when google account is loading, From b64bba7337e6773c0c8aa204035a88764cb9490e Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 24 Oct 2024 13:21:40 +0400 Subject: [PATCH 38/69] Show ID only when connected. --- .../account-details.js | 4 +++- .../connect-account-card.scss | 4 ++++ .../connect-mc/connect-mc.js | 23 ++++++++----------- .../connected-google-combo-account-card.js | 18 +++++++++------ 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/js/src/components/google-combo-account-card/account-details.js b/js/src/components/google-combo-account-card/account-details.js index 40f81bcf74..ac9618ac1f 100644 --- a/js/src/components/google-combo-account-card/account-details.js +++ b/js/src/components/google-combo-account-card/account-details.js @@ -9,6 +9,7 @@ import { __, sprintf } from '@wordpress/i18n'; import useGoogleAccount from '.~/hooks/useGoogleAccount'; import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount'; import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount'; +import useGoogleMCAccountReady from '.~/hooks/useGoogleMCAccountReady'; /** * Account details. @@ -18,12 +19,13 @@ const AccountDetails = () => { const { google } = useGoogleAccount(); const { googleAdsAccount } = useGoogleAdsAccount(); const { googleMCAccount } = useGoogleMCAccount(); + const isGoogleMCConnected = useGoogleMCAccountReady(); return ( <>

{ google.email }

- { googleMCAccount.id > 0 && + { isGoogleMCConnected && sprintf( // Translators: %s is the Merchant Center ID __( diff --git a/js/src/components/google-combo-account-card/connect-account-card.scss b/js/src/components/google-combo-account-card/connect-account-card.scss index de33c405e3..50c1a3d13c 100644 --- a/js/src/components/google-combo-account-card/connect-account-card.scss +++ b/js/src/components/google-combo-account-card/connect-account-card.scss @@ -16,4 +16,8 @@ border: 0; padding: 0; } + + .app-select-control { + flex: 1; + } } diff --git a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js index bb2f1cd9f9..fc8ae087b5 100644 --- a/js/src/components/google-combo-account-card/connect-mc/connect-mc.js +++ b/js/src/components/google-combo-account-card/connect-mc/connect-mc.js @@ -15,6 +15,7 @@ import ConnectMCFooter from './connect-mc-footer'; import SpinnerCard from '.~/components/spinner-card'; import AccountConnectionStatus from '.~/components/google-mc-account-card/account-connection-status'; import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; +import useGoogleMCAccountReady from '.~/hooks/useGoogleMCAccountReady'; /** * Clicking on the "Switch account" button to select a different Google Merchant Center account to connect. @@ -24,28 +25,25 @@ import useConnectMCAccount from '.~/hooks/useConnectMCAccount'; */ const ConnectMC = ( { createMCAccount, resultCreateMCAccount } ) => { - const { - googleMCAccount, - hasFinishedResolution, - hasGoogleMCConnection, - isPreconditionReady, - } = useGoogleMCAccount(); + const { googleMCAccount, hasFinishedResolution, isPreconditionReady } = + useGoogleMCAccount(); + const isGoogleMCConnected = useGoogleMCAccountReady(); const [ accountID, setAccountID ] = useState(); const [ handleConnectMC, resultConnectMC ] = useConnectMCAccount( accountID ); useEffect( () => { - if ( hasGoogleMCConnection ) { + if ( isGoogleMCConnected ) { setAccountID( googleMCAccount.id ); } - }, [ googleMCAccount, hasGoogleMCConnection ] ); + }, [ googleMCAccount, isGoogleMCConnected ] ); if ( ! hasFinishedResolution ) { return ; } if ( - ! hasGoogleMCConnection && + ! isGoogleMCConnected && ( [ 403, 409 ].includes( resultConnectMC.response?.status ) || [ 403, 503 ].includes( resultCreateMCAccount.response?.status ) || resultCreateMCAccount.loading ) @@ -62,8 +60,7 @@ const ConnectMC = ( { createMCAccount, resultCreateMCAccount } ) => { return ( { } footer={ { + const isGoogleMCConnected = useGoogleMCAccountReady(); // Used to track whether the account creation ever happened. const [ wasCreatingAccounts, setWasCreatingAccounts ] = useState( undefined ); @@ -34,8 +36,14 @@ const ConnectedGoogleComboAccountCard = () => { const { hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount } = useGoogleMCAccount(); - const { data: accounts } = useExistingGoogleMCAccounts(); + // We use a single instance of the hook to create a MC (Merchant Center) account, + // ensuring consistent results across both the main component (ConnectedGoogleComboAccountCard) + // and its child component (ConnectMC). + // This approach is especially useful when an MC account is automatically created, + // and the URL needs to be reclaimed. The URL reclaiming component is rendered + // within the ConnectMC component. const [ createMCAccount, resultCreateMCAccount ] = useCreateMCAccount(); + const { data: accounts } = useExistingGoogleMCAccounts(); const { hasDetermined, creatingWhich } = useAutoCreateAdsMCAccounts( createMCAccount ); const { text, subText } = getAccountCreationTexts( wasCreatingAccounts ); @@ -65,9 +73,7 @@ const ConnectedGoogleComboAccountCard = () => { // Show the Connect MC card if there's no connected accounts and there are existing accounts. // The "Edit" button will be used to display the card within the connected state. - // @TODO: review - // const showConnectMCCard = ! hasGoogleMCConnection && accounts.length > 0; - const showConnectMCCard = true; + const showConnectMCCard = ! isGoogleMCConnected && accounts.length > 0; return (

@@ -79,9 +85,7 @@ const ConnectedGoogleComboAccountCard = () => { ! displayAccountDetails ? text : } helper={ ! displayAccountDetails ? subText : null } - indicator={ - - } + indicator={ } /> { showConnectMCCard && ( From 841bb90842bb08bdf3bf7bb87d374f285598881b Mon Sep 17 00:00:00 2001 From: asvinb Date: Thu, 24 Oct 2024 13:25:24 +0400 Subject: [PATCH 39/69] Make app select control non interactive. --- js/src/components/app-select-control/index.js | 9 +++++++-- .../connect-mc/connect-mc-body.js | 11 +---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/js/src/components/app-select-control/index.js b/js/src/components/app-select-control/index.js index 351bedd844..f28f340ff8 100644 --- a/js/src/components/app-select-control/index.js +++ b/js/src/components/app-select-control/index.js @@ -20,6 +20,7 @@ import './index.scss'; * @param {Function} [props.onChange=noop] Callback function triggered when the selected value changes. Receives the new value as an argument. * @param {string} [props.value] The currently selected value. This component should be used as a controlled component. A special case is that after mounting, when `autoSelectFirstOption` is true and `value` is undefined, it tries to call back `onChange` once to select the first option so that the `value` can be consistent with the `