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

Onboarding: Create new ads account. #2651

Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5b64b6b
Create new ads account.
ankitrox Oct 25, 2024
fdccdfb
Fix: lint css.
ankitrox Oct 25, 2024
ab8984e
Merge branch 'update/2596-connect-ads-account' into update/2603-creat…
ankitrox Oct 28, 2024
d4e0142
Add css.
ankitrox Oct 28, 2024
1584e33
Do not show card if account is in unclaimed status.
ankitrox Oct 28, 2024
a00d42c
Merge branch 'update/2596-connect-ads-account' into update/2603-creat…
ankitrox Oct 28, 2024
54fdfc8
Add E2E tests.
ankitrox Oct 28, 2024
3b25965
Fix: E2E issues.
ankitrox Oct 29, 2024
86a174e
Resolve conflicts in E2E.
ankitrox Oct 29, 2024
e1fca96
Resolve conflicts.
ankitrox Oct 29, 2024
073b04f
CR feedback.
ankitrox Oct 29, 2024
863a71c
Resolve conflicts.
ankitrox Oct 29, 2024
e9a071b
Merge branch 'update/2596-connect-ads-account' into update/2603-creat…
ankitrox Oct 29, 2024
3e2dcbe
Show correct text when creating an account.
asvinb Oct 30, 2024
db10842
Revert change.
asvinb Oct 30, 2024
3e4249c
Prevent complete re rendering of the card.
asvinb Oct 30, 2024
0c3f1c7
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Oct 30, 2024
f31dcc4
Fix error.
asvinb Oct 30, 2024
46aef1c
Fetch existing accounts again.
asvinb Oct 30, 2024
b93f3aa
Display updating text only when clicking the claim button.
asvinb Oct 30, 2024
d3dae92
Save WIP.
asvinb Oct 31, 2024
9f335dd
Merge branch 'feature/2509-consolidate-google-account-cards' into upd…
asvinb Oct 31, 2024
3c19aa9
Save WIP.
asvinb Oct 31, 2024
90db787
UX improvements.
asvinb Nov 4, 2024
797ea87
Review comments.
asvinb Nov 4, 2024
74ff220
Use single quotes.
asvinb Nov 4, 2024
e6222de
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 4, 2024
2d9c2cf
Use correct class name.
asvinb Nov 4, 2024
5638687
Improve 'Connect Google account' E2E tests
joemcgill Nov 4, 2024
6bb4318
Update title and indicator label.
asvinb Nov 5, 2024
d46d6ca
Merge branch 'update/2603-create-ads-account' of github.com:woocommer…
asvinb Nov 5, 2024
50e36fd
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 5, 2024
75c7827
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 6, 2024
fea64c6
Address CR feedback.
asvinb Nov 6, 2024
92fb813
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 6, 2024
01f1097
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
joemcgill Nov 6, 2024
5e81fba
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 7, 2024
fc6214d
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 7, 2024
b89142d
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 7, 2024
4fd8997
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 8, 2024
24a9c4f
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 8, 2024
bccac35
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 8, 2024
35580cb
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 8, 2024
3044904
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
asvinb Nov 8, 2024
d82c8d8
Address CR feedback.
asvinb Nov 8, 2024
4be14db
Fix ConnectAds props
joemcgill Nov 11, 2024
ab319c7
Fix E2E tests
joemcgill Nov 11, 2024
a05eb38
Merge branch 'update/2582-claim-ads-account' into update/2603-create-…
joemcgill Nov 11, 2024
d074504
Limit Ads claim updates to 3 retries
joemcgill Nov 11, 2024
51718c2
Inline docs updates
joemcgill Nov 12, 2024
3492fa5
Docblock fix
joemcgill Nov 12, 2024
54448e3
Update JSDoc.
asvinb Nov 13, 2024
55cbeb9
Merge branch 'feature/2509-consolidate-google-account-cards' into upd…
joemcgill Nov 13, 2024
f2aa1c9
E2E: Remove flaky mocks from auto account creation test
joemcgill Nov 13, 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
2 changes: 1 addition & 1 deletion js/src/components/account-card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const appearanceDict = {
// The `center` is the default alignment, and no need to append any additional class name.
const alignStyleName = {
center: false,
top: `gla-account-card__styled--align-top`,
top: 'gla-account-card__styled--align-top',
};

const indicatorAlignStyleName = {
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this PR not include code changes that are not attributed to it? The d074504 commit belongs more to #2644 (be3e8ec).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually made the commit originally in this PR, since testing all of the claim functionality properly was better when I could create a new account from the same UI, but I agree that functionally it fit more in the PR for the Claim functionality, so I cherry-picked this commit there. Given that the other will be merged first, it should be fine to leave this as is and resolve any merge conflicts after #2644 is merged.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { useState } from '@wordpress/element';
import { useCallback, useState, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
Expand All @@ -12,18 +12,43 @@ import { useAppDispatch } from '.~/data';
import useWindowFocusCallbackIntervalEffect from '.~/hooks/useWindowFocusCallbackIntervalEffect';
import './claim-ads-account.scss';

const CLAIM_RETRIES = 3;

/**
* ClaimAdsAccount component.
*
* @return {JSX.Element} ClaimAdsAccount component.
*/
const ClaimAdsAccount = () => {
const [ updating, setUpdating ] = useState( false );
const [ claiming, setClaiming ] = useState( false );
const retries = useRef( CLAIM_RETRIES );
const { fetchGoogleAdsAccountStatus } = useAppDispatch();
useWindowFocusCallbackIntervalEffect( fetchGoogleAdsAccountStatus, 30 );

const checkUpdatedAdsAccountStatus = useCallback( async () => {
if ( ! claiming ) {
return;
}

await fetchGoogleAdsAccountStatus()
.then( () => {
retries.current -= 1;
// Reset the claiming state after 3 retries.
if ( retries.current < 1 ) {
setClaiming( false );
}
} )
.catch( () => {
// Reset the claiming state if the API call fails.
setClaiming( false );
} );
}, [ claiming, fetchGoogleAdsAccountStatus ] );

useWindowFocusCallbackIntervalEffect( checkUpdatedAdsAccountStatus, 30 );

const handleOnClick = () => {
setUpdating( true );
// Reset retries.
retries.current = CLAIM_RETRIES;
setClaiming( true );
};

return (
Expand All @@ -47,16 +72,16 @@ const ClaimAdsAccount = () => {
) }
</p>
<ClaimAccountButton
loading={ updating }
loading={ claiming }
text={
updating
claiming
? __( 'Waiting…', 'google-listings-and-ads' )
: __(
'Claim account in Google Ads',
'google-listings-and-ads'
)
}
isPrimary={ ! updating }
isPrimary={ ! claiming }
onClick={ handleOnClick }
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import AppModal from '.~/components/app-modal';
import AppButton from '.~/components/app-button';
import WarningIcon from '.~/components/warning-icon';
import './confirm-create-modal.scss';

/**
* Google Ads account creation confirmation modal.
* This modal is shown when the user tries to create a new Google Ads account.
*
* @param {Object} props Component props.
* @param {Function} props.onContinue Callback to continue with account creation.
* @param {Function} props.onRequestClose Callback to close the modal.
* @return {JSX.Element} Confirmation modal.
*/
const ConfirmCreateModal = ( { onContinue, onRequestClose } ) => {
return (
<AppModal
className="gla-ads-warning-modal"
title={ __(
'Create Google Ads Account',
'google-listings-and-ads'
) }
buttons={ [
<AppButton key="confirm" isSecondary onClick={ onContinue }>
{ __(
'Yes, I want a new account',
'google-listings-and-ads'
) }
</AppButton>,
<AppButton key="cancel" isPrimary onClick={ onRequestClose }>
{ __( 'Cancel', 'google-listings-and-ads' ) }
</AppButton>,
] }
onRequestClose={ onRequestClose }
>
<p className="gla-ads-warning-modal__warning-text">
<WarningIcon />
<span>
{ __(
'Are you sure you want to create a new Google Ads account?',
'google-listings-and-ads'
) }
</span>
</p>
<p>
{ __(
'You already have another Ads account associated with this Google account.',
'google-listings-and-ads'
) }
</p>
<p>
{ __(
'If you create a new Google Ads account, you will need to accept an invite to the account before it can be used.',
'google-listings-and-ads'
) }
</p>
</AppModal>
);
};

export default ConfirmCreateModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.gla-ads-warning-modal {

.gla-ads-warning-modal__warning-text {
display: flex;
align-items: center;
gap: calc(var(--main-gap) / 3);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ import DisconnectAccount from '.~/components/google-ads-account-card/disconnect-
*
* @param {Object} props Props.
* @param {boolean} props.isConnected Whether the account is connected.
* @param {Function} props.onCreateNewClick Callback when clicking on the button to create a new account.
* @param {Object} props.restProps Rest props. Passed to AppButton.
* @return {JSX.Element} Footer component.
*/
const ConnectAdsFooter = ( { isConnected, ...restProps } ) => {
// If the account is connected, show the disconnect button.
const ConnectAdsFooter = ( {
isConnected,
onCreateNewClick,
...restProps
} ) => {
if ( isConnected ) {
return <DisconnectAccount />;
}

return (
<AppButton isTertiary { ...restProps }>
<AppButton isTertiary onClick={ onCreateNewClick } { ...restProps }>
{ __(
'Or, create a new Google Ads account',
'google-listings-and-ads'
Expand Down
124 changes: 28 additions & 96 deletions js/src/components/google-combo-account-card/connect-ads/connect-ads.js
Original file line number Diff line number Diff line change
@@ -1,122 +1,54 @@
/**
* External dependencies
*/
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';

/**
* Internal dependencies
*/
import useApiFetchCallback from '.~/hooks/useApiFetchCallback';
import useDispatchCoreNotices from '.~/hooks/useDispatchCoreNotices';
import useGoogleAdsAccount from '.~/hooks/useGoogleAdsAccount';
import { useAppDispatch } from '.~/data';
import useGoogleAdsAccountReady from '.~/hooks/useGoogleAdsAccountReady';
import AccountCard from '.~/components/account-card';
import AdsAccountSelectControl from '.~/components/ads-account-select-control';
import ConnectedIconLabel from '.~/components/connected-icon-label';
import ConnectAdsFooter from './connect-ads-footer';
import LoadingLabel from '.~/components/loading-label';
import ConnectButton from '.~/components/google-ads-account-card/connect-ads/connect-button';
import ConfirmCreateModal from './confirm-create-modal';
import ConnectExistingAccount from './connect-existing-account';
import UpsertingAccount from './upserting-account';

/**
* ConnectAds component renders an account card to connect to an existing Google Ads account.
*
* @param {Object} props Component props.
* @param {Function} props.onRequestCreate A callback to fire when creating a new account.
* @param {string} props.upsertingAction The action the user is performing. Either 'create' or 'update'.
eason9487 marked this conversation as resolved.
Show resolved Hide resolved
* @return {JSX.Element} {@link AccountCard} filled with content.
*/
const ConnectAds = () => {
const [ value, setValue ] = useState();
const [ isLoading, setLoading ] = useState( false );
const { refetchGoogleAdsAccount } = useGoogleAdsAccount();
const { createNotice } = useDispatchCoreNotices();
const { fetchGoogleAdsAccountStatus } = useAppDispatch();
const isConnected = useGoogleAdsAccountReady();
const { googleAdsAccount, hasFinishedResolution } = useGoogleAdsAccount();
const [ connectGoogleAdsAccount ] = useApiFetchCallback( {
path: '/wc/gla/ads/accounts',
method: 'POST',
data: { id: value },
} );
const ConnectAds = ( { onRequestCreate, upsertingAction } ) => {
const [ showCreateNewModal, setShowCreateNewModal ] = useState( false );

useEffect( () => {
if ( isConnected ) {
setValue( googleAdsAccount.id );
}
}, [ googleAdsAccount, isConnected ] );
if ( upsertingAction ) {
return <UpsertingAccount upsertingAction={ upsertingAction } />;
}

const handleConnectClick = async () => {
if ( ! value ) {
return;
}

setLoading( true );
try {
await connectGoogleAdsAccount();
await fetchGoogleAdsAccountStatus();
await refetchGoogleAdsAccount();
setLoading( false );
} catch ( error ) {
setLoading( false );
createNotice(
'error',
__(
'Unable to connect your Google Ads account. Please try again later.',
'google-listings-and-ads'
)
);
}
const handleCreateClick = () => {
setShowCreateNewModal( true );
};

const getIndicator = () => {
if ( ! hasFinishedResolution ) {
return <LoadingLabel />;
}

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

if ( isConnected ) {
return <ConnectedIconLabel />;
}
const handleRequestClose = () => {
setShowCreateNewModal( false );
};

return (
<ConnectButton accountID={ value } onClick={ handleConnectClick } />
);
const handleContinue = () => {
onRequestCreate();
handleRequestClose();
};

return (
<AccountCard
className="gla-google-combo-account-card gla-google-combo-service-account-card--ads"
title={ __(
'Connect to existing Google Ads account',
'google-listings-and-ads'
) }
helper={ __(
'Required to set up conversion measurement for your store.',
'google-listings-and-ads'
) }
alignIndicator="toDetail"
indicator={ getIndicator() }
detail={
<AdsAccountSelectControl
value={ value }
onChange={ setValue }
autoSelectFirstOption
nonInteractive={ isConnected }
<>
<ConnectExistingAccount onCreateClick={ handleCreateClick } />
{ showCreateNewModal && (
<ConfirmCreateModal
onContinue={ handleContinue }
onRequestClose={ handleRequestClose }
/>
}
actions={
<ConnectAdsFooter
isConnected={ isConnected }
disabled={ isLoading }
/>
}
/>
) }
</>
);
};

Expand Down
Loading