Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kickoff MC and Ads account creation #2618

Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
1535369
Initial structure.
ankitrox Sep 18, 2024
0d7965c
Use hooks to determine existing accounts.
ankitrox Sep 19, 2024
9e9b662
Fix lint.
ankitrox Sep 19, 2024
c5023b6
Fix: CreateAccounts component.
ankitrox Sep 20, 2024
d41d825
Remove redundant props.
ankitrox Sep 20, 2024
41e6d04
Remove redundant code.
ankitrox Sep 23, 2024
6917337
Introduce hook.
ankitrox Sep 23, 2024
d1b4c77
Fix: Flicker in component due to resolution state.
ankitrox Sep 23, 2024
b997713
Update account creation checks.
ankitrox Sep 24, 2024
d293f15
Update name for resolved checks property.
ankitrox Sep 25, 2024
9ef6c13
E2E tests.
ankitrox Sep 25, 2024
767a906
Move hook to hooks directory.
ankitrox Sep 25, 2024
2de300a
Add JS tests for useCreateAccounts hook.
ankitrox Sep 25, 2024
8239b47
Add indicator style.
ankitrox Sep 25, 2024
2e16bf4
Fix css lint error.
ankitrox Sep 25, 2024
32b47d5
Refactor hook to handle either of the account creation.
ankitrox Sep 27, 2024
f55fd1d
CR feedback - round 2.
ankitrox Sep 30, 2024
95fe0cb
Add CR feedback changes.
ankitrox Oct 1, 2024
1a24f0d
Remove unwanted props.
ankitrox Oct 3, 2024
2325d7a
Use refs to remove no-deps eslint rule.
ankitrox Oct 3, 2024
a0dcb9a
Fix: e2e tests.
ankitrox Oct 3, 2024
ea3a30f
Fix: hook tests.
ankitrox Oct 3, 2024
58738f8
Lint fix.
ankitrox Oct 3, 2024
a2b5f19
Remove unnecessary act in tests.
ankitrox Oct 3, 2024
c4f0d2b
Move hooks to relevant component.
ankitrox Oct 3, 2024
0d5130f
Fix js linting.
ankitrox Oct 3, 2024
896c681
Load correct scss file in appropriate component.
asvinb Oct 3, 2024
1252ac9
Add connected icon label.
ankitrox Oct 8, 2024
6d46a02
Fix: E2E tests.
ankitrox Oct 8, 2024
948acf0
Merge branch 'feature/2509-consolidate-google-account-cards' into fea…
asvinb Oct 8, 2024
2466e3c
Fix: Creating account message showing up constantly.
ankitrox Oct 8, 2024
e0d7ea1
Merge branch 'feature/2567-kickoff-mc-ads-account-creation' of https:…
ankitrox Oct 8, 2024
11eba1b
Update filfilrequest utility.
ankitrox Oct 8, 2024
0df9699
Fix: unit test errors.
ankitrox Oct 8, 2024
ab0d80d
Add E2E test case for connected label.
ankitrox Oct 8, 2024
f2b3c21
Remove ambiguous request mocking.
ankitrox Oct 8, 2024
b1023b6
Remove use of useCallback and redundant code.
ankitrox Oct 14, 2024
7d343cd
Update conditions for rendering.
ankitrox Oct 14, 2024
37859b3
Formatting updates.
ankitrox Oct 14, 2024
298c0f4
Remove unused component.
ankitrox Oct 15, 2024
5ac6cf1
Update property names and description.
ankitrox Oct 15, 2024
d3f4f6f
Add status for MC account mock.
ankitrox Oct 15, 2024
60eff85
Rename constants.
ankitrox Oct 17, 2024
bd98116
Simplify the auto creation hook.
ankitrox Oct 17, 2024
cb382e8
Fix: js lint.
ankitrox Oct 17, 2024
747097d
Update existing MC accounts check.
ankitrox Oct 17, 2024
79eddb9
Add tests for existing accounts.
ankitrox Oct 17, 2024
e03d479
Remove unnecessary refs.
ankitrox Oct 17, 2024
3230a8b
Consolidate useEffect hook into one.
ankitrox Oct 17, 2024
b5e23ff
Optimize hook to use limited refs.
ankitrox Oct 17, 2024
40bd01c
Remove unused constants.
ankitrox Oct 17, 2024
4e65cd7
Fix: E2E tests.
ankitrox Oct 17, 2024
63c2f7f
Add hasGoogleMCConnection property in useGoogleMCAccount hook.
ankitrox Oct 17, 2024
2da86e6
Update doc block.
ankitrox Oct 18, 2024
1180ca8
Refactor to account creation description components.
ankitrox Oct 22, 2024
8393630
Add account creation data hook.
ankitrox Oct 22, 2024
971497a
Improve code readability.
ankitrox Oct 22, 2024
5d1048c
Fix: hook tests.
ankitrox Oct 22, 2024
1b4cae2
Replace isCreatingWhichAccount with creatingWhichAccount.
ankitrox Oct 22, 2024
e74287c
Use separate state variables.
ankitrox Oct 22, 2024
0cc906e
Add doc blocks.
ankitrox Oct 22, 2024
19a3a34
Add hooks for account creation determination.
ankitrox Oct 22, 2024
d3e380e
Refactor useAutoCreateAdsMCAccounts hook.
ankitrox Oct 22, 2024
3561c05
Rename useAccountCreationData hook to useAccountsData.
ankitrox Oct 22, 2024
8813820
Fix: tests.
ankitrox Oct 22, 2024
c9b9f2f
Remove redundant code.
ankitrox Oct 22, 2024
85cc699
Fix: TypeError.
ankitrox Oct 22, 2024
b62199d
Update doc blocks.
ankitrox Oct 22, 2024
3c93840
Fix: E2E tests.
ankitrox Oct 22, 2024
47af5ad
Fix: E2E.
ankitrox Oct 22, 2024
7937784
Add useGoogleAdsAccountReady hook.
ankitrox Oct 23, 2024
1d86086
Remove use of context.
ankitrox Oct 23, 2024
0be881e
Remove unwanted components.
ankitrox Oct 23, 2024
98808af
Optimize the useAutoCreateAdsMCAccounts hook and fix tests.
ankitrox Oct 23, 2024
e74b5e3
Style changes.
ankitrox Oct 23, 2024
38137a3
Remove unnecessary files.
ankitrox Oct 23, 2024
18256f3
Update display account details logic.
ankitrox Oct 23, 2024
7a9854b
Add useGoogleMCAccountReady hook.
ankitrox Oct 23, 2024
2859cf5
Update account details rendering logic.
ankitrox Oct 23, 2024
7a24be5
Tweak useGoogleMCAccountReady hook
joemcgill Oct 23, 2024
e62562f
Remove unused constant
joemcgill Oct 23, 2024
bd1f3e3
Clean up E2E tests for account creation
joemcgill Oct 23, 2024
56a2e15
Fix: E2E test.
ankitrox Oct 24, 2024
599c2d2
E2E tests changs for new hook.
ankitrox Oct 24, 2024
f3f63fe
CR feedback.
ankitrox Oct 24, 2024
72434e2
Remove redundant code.
ankitrox Oct 24, 2024
e00c6e3
Fix: JS lint.
ankitrox Oct 24, 2024
7f20af7
Fix: condition in hook.
ankitrox Oct 24, 2024
d363edc
E2E improvements.
ankitrox Oct 25, 2024
4b8badb
Use E2E mockAdsStatusClaimed function
ankitrox Oct 25, 2024
9137ef6
Use mockAdsAccountConnected utility.
ankitrox Oct 25, 2024
8d381c4
Update docblocks.
ankitrox Oct 25, 2024
8ab1be0
Update JSDoc.
ankitrox Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Internal dependencies
*/
import AccountDetails from './account-details';
import CreatingAccounts from './creating-accounts';
import useAccountsData from '.~/hooks/useAccountsData';

/**
* AccountCardDescription component.
* @return {JSX.Element} AccountCardDescription component.
*/
const AccountCardDescription = () => {
const { creatingWhich, google, googleAdsAccount, googleMCAccount } =
useAccountsData();

return (
<>
{ creatingWhich ? (
asvinb marked this conversation as resolved.
Show resolved Hide resolved
<CreatingAccounts creatingAccounts={ creatingWhich } />
) : (
<AccountDetails
email={ google.email }
googleAdsID={ googleAdsAccount.id }
googleMerchantCenterID={ googleMCAccount.id }
/>
) }
</>
);
};

export default AccountCardDescription;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';

/**
* Account details.
*
* @param {Object} props Component props.
* @param {string} props.email Google account email address.
* @param {number} props.googleAdsID Google Ads account ID.
* @param {number} props.googleMerchantCenterID Google Merchant Center account ID.
* @return {JSX.Element} JSX markup.
*/
const AccountDetails = ( { email, googleAdsID, googleMerchantCenterID } ) => {
return (
<div className="gla-account-card__account_details">
<span>{ email }</span>
<span>
asvinb marked this conversation as resolved.
Show resolved Hide resolved
{ sprintf(
// Translators: %s is the Merchant Center ID
__( 'Merchant Center ID: %s', 'google-listings-and-ads' ),
googleMerchantCenterID
) }
</span>
<span>
{ sprintf(
// Translators: %s is the Google Ads ID
__( 'Google Ads ID: %s', 'google-listings-and-ads' ),
googleAdsID
) }
</span>
</div>
);
};

export default AccountDetails;
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import {
CREATING_ADS_ACCOUNT,
CREATING_BOTH_ACCOUNTS,
CREATING_MC_ACCOUNT,
} from '../constants';

/**
* Account creation in progress description.
* @param {Object} props Component props.
* @param {string|null} props.creatingAccounts Whether the accounts are being created. Possible values are: 'both', 'ads', 'mc'.
* @return {JSX.Element|null} JSX markup.
*/
const CreatingAccounts = ( { creatingAccounts } ) => {
let text = null;
let subText = null;

asvinb marked this conversation as resolved.
Show resolved Hide resolved
switch ( creatingAccounts ) {
case CREATING_BOTH_ACCOUNTS:
text = __(
'You don’t have Merchant Center nor Google Ads accounts, so we’re creating them for you.',
'google-listings-and-ads'
);
subText = __(
'Merchant Center is required to sync products so they show on Google. Google Ads is required to set up conversion measurement for your store.',
'google-listings-and-ads'
);
break;

case CREATING_ADS_ACCOUNT:
text = __(
'You don’t have Google Ads account, so we’re creating one for you.',
'google-listings-and-ads'
);
subText = __(
'Required to set up conversion measurement for your store.',
'google-listings-and-ads'
);
break;

case CREATING_MC_ACCOUNT:
text = __(
'You don’t have Merchant Center account, so we’re creating one for you.',
'google-listings-and-ads'
);
subText = __(
'Required to sync products so they show on Google.',
'google-listings-and-ads'
);
break;
}

return (
<>
<p>{ text }</p>
<em>{ subText }</em>
</>
);
};

export default CreatingAccounts;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default } from './account-card-description';
export { default as CreatingAccounts } from './creating-accounts.js';
export { default as AccountDetails } from './account-details';
export { default as Indicator } from './indicator.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import ConnectedIconLabel from '.~/components/connected-icon-label';
import LoadingLabel from '.~/components/loading-label/loading-label';
import useAccountsData from '.~/hooks/useAccountsData';
import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount';
import useGoogleAdsAccountStatus from '.~/hooks/useGoogleAdsAccountStatus';
import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount';

/**
* Account creation indicator.
* Displays a loading indicator when accounts are being created or a connected icon when accounts are connected.
* @return {JSX.Element|null} Indicator component.
*/
const Indicator = () => {
const { creatingWhich } = useAccountsData();
const { hasGoogleAdsConnection } = useGoogleAdsAccount();
const { googleMCAccount, isPreconditionReady } = useGoogleMCAccount();
const { hasAccess, step } = useGoogleAdsAccountStatus();

const isGoogleAdsConnected =
asvinb marked this conversation as resolved.
Show resolved Hide resolved
hasGoogleAdsConnection &&
hasAccess &&
[ '', 'billing', 'link_merchant' ].includes( step );

const isGoogleMCConnected =
isPreconditionReady &&
( googleMCAccount?.status === 'connected' ||
( googleMCAccount?.status === 'incomplete' &&
googleMCAccount?.step === 'link_ads' ) );

if ( creatingWhich ) {
return (
<LoadingLabel
text={ __( 'Creating…', 'google-listings-and-ads' ) }
/>
);
}

if ( isGoogleAdsConnected && isGoogleMCConnected ) {
return <ConnectedIconLabel />;
}

return null;
};

export default Indicator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { createContext, useContext } from '@wordpress/element';

/**
* @typedef {Object} AccountCreationContext
* @property {boolean} accountsCreated - `true` if the accounts have been created, `false` otherwise.
* @property {('ads'|'mc'|'both'|null)} creatingWhich - The accounts that are being created.
*/

/**
* @type {AccountCreationContext}
*/
const defaultContext = {
accountsCreated: undefined,
creatingWhich: undefined,
};

export const AccountCreationContext = createContext( defaultContext );

/**
* AccountCreation's context hook.
* @return {AccountCreationContext} The current context value for AccountCreation.
* @throws Will throw an error if the context provider is missing in the component's ancestors.
*/
export function useAccountCreationContext() {
const adaptiveFormContext = useContext( AccountCreationContext );
asvinb marked this conversation as resolved.
Show resolved Hide resolved

if (
adaptiveFormContext.accountsCreated === undefined ||
adaptiveFormContext.creatingWhich === undefined
) {
throw new Error(
'useAccountCreationContext was used outside of its context provider ConnectedGoogleComboAccountCard.'
);
}

return adaptiveFormContext;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import AppButton from '.~/components/app-button';
import readMoreLink from '../google-account-card/read-more-link';
import useGoogleConnectFlow from '../google-account-card/use-google-connect-flow';
import AppDocumentationLink from '../app-documentation-link';
import './connect-google-combo-account-card.scss';

/**
* @param {Object} props React props
Expand All @@ -34,7 +33,6 @@ const ConnectGoogleComboAccountCard = ( { disabled } ) => {
return (
<AccountCard
appearance={ APPEARANCE.GOOGLE }
className="gla-connect-google-combo-account-card"
disabled={ disabled }
alignIcon="top"
description={
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Internal dependencies
*/
import AccountCard, { APPEARANCE } from '../account-card';
import AccountCardDescription, { Indicator } from './account-card-description';
import { AccountCreationContext } from './account-creation-context';
import AppSpinner from '../app-spinner';
import useAutoCreateAdsMCAccounts from '.~/hooks/useAutoCreateAdsMCAccounts';
import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount';
import useGoogleMCAccount from '.~/hooks/useGoogleMCAccount';
asvinb marked this conversation as resolved.
Show resolved Hide resolved
import './connected-google-combo-account-card.scss';

/**
* Renders a Google account card UI with connected account information.
* It will also kickoff Ads and Merchant Center account creation if the user does not have accounts.
*/
const ConnectedGoogleComboAccountCard = () => {
const { hasFinishedResolution: hasFinishedResolutionForCurrentAdsAccount } =
useGoogleAdsAccount();

const { hasFinishedResolution: hasFinishedResolutionForCurrentMCAccount } =
useGoogleMCAccount();

const { accountsCreated, hasDetermined, creatingWhich } =
useAutoCreateAdsMCAccounts();

if (
! accountsCreated &&
( ! hasDetermined ||
! hasFinishedResolutionForCurrentAdsAccount ||
! hasFinishedResolutionForCurrentMCAccount )
) {
return <AccountCard description={ <AppSpinner /> } />;
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
}

const accountCreationData = {
accountsCreated,
creatingWhich,
};

return (
<AccountCreationContext.Provider value={ accountCreationData }>
<AccountCard
appearance={ APPEARANCE.GOOGLE }
alignIcon="top"
className="gla-google-combo-account-card--connected"
helper={ <AccountCardDescription /> }
indicator={ <Indicator /> }
/>
</AccountCreationContext.Provider>
);
};

export default ConnectedGoogleComboAccountCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.gla-google-combo-account-card--connected {

.gla-account-card__helper {
font-style: normal;
font-size: $gla-font-base;
color: $black;

em {
font-style: italic;
color: $gray-700;
}
}

.gla-account-card__account_details {
display: flex;
asvinb marked this conversation as resolved.
Show resolved Hide resolved
flex-direction: column;
gap: $grid-unit;
}
}
3 changes: 3 additions & 0 deletions js/src/components/google-combo-account-card/constants.js
asvinb marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const CREATING_BOTH_ACCOUNTS = 'both';
export const CREATING_ADS_ACCOUNT = 'ads';
export const CREATING_MC_ACCOUNT = 'mc';
4 changes: 2 additions & 2 deletions js/src/components/google-combo-account-card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import useGoogleAccount from '.~/hooks/useGoogleAccount';
import AppSpinner from '.~/components/app-spinner';
import AccountCard from '.~/components/account-card';
import RequestFullAccessGoogleAccountCard from '../google-account-card/request-full-access-google-account-card';
import { ConnectedGoogleAccountCard } from '../google-account-card';
import ConnectGoogleComboAccountCard from './connect-google-combo-account-card';
import ConnectedGoogleComboAccountCard from './connected-google-combo-account-card';

export default function GoogleComboAccountCard( { disabled = false } ) {
const { google, scope, hasFinishedResolution } = useGoogleAccount();
Expand All @@ -18,7 +18,7 @@ export default function GoogleComboAccountCard( { disabled = false } ) {
const isConnected = google?.active === 'yes';

if ( isConnected && scope.glaRequired ) {
return <ConnectedGoogleAccountCard googleAccount={ google } />;
return <ConnectedGoogleComboAccountCard />;
}

if ( isConnected && ! scope.glaRequired ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ 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 useCreateMCAccount from '.~/hooks/useCreateMCAccount';
import CreatingCard from '../creating-card';
import './index.scss';

Expand Down
2 changes: 1 addition & 1 deletion js/src/components/google-mc-account-card/create-account.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import CreateAccountCard from './create-account-card';
import CreatingCard from './creating-card';
import ReclaimUrlCard from './reclaim-url-card';
import useCreateMCAccount from './useCreateMCAccount';
import useCreateMCAccount from '.~/hooks/useCreateMCAccount';

/**
* Create Account flow.
Expand Down
6 changes: 6 additions & 0 deletions js/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ export const GOOGLE_ADS_ACCOUNT_STATUS = {
INCOMPLETE: 'incomplete',
};

export const GOOGLE_MC_ACCOUNT_STATUS = {
CONNECTED: 'connected',
DISCONNECTED: 'disconnected',
INCOMPLETE: 'incomplete',
};

export const GOOGLE_ADS_BILLING_STATUS = {
UNKNOWN: 'unknown',
PENDING: 'pending',
Expand Down
Loading