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

Domains: Use checkoutless flow for adding mappings on eligible sites #52297

Merged
merged 4 commits into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions client/components/domains/map-domain-step/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class MapDomainStep extends React.Component {
products: PropTypes.object,
cart: PropTypes.object,
selectedSite: PropTypes.oneOfType( [ PropTypes.object, PropTypes.bool ] ),
isBusyMapping: PropTypes.bool,
initialQuery: PropTypes.string,
analyticsSection: PropTypes.string.isRequired,
domainsWithPlansOnly: PropTypes.bool.isRequired,
Expand All @@ -54,6 +55,7 @@ class MapDomainStep extends React.Component {
};

static defaultProps = {
isBusyMapping: false,
onSave: noop,
initialQuery: '',
};
Expand Down Expand Up @@ -124,7 +126,7 @@ class MapDomainStep extends React.Component {
autoFocus // eslint-disable-line jsx-a11y/no-autofocus
/>
<Button
busy={ this.state.isPendingSubmit }
busy={ this.state.isPendingSubmit || this.props.isBusyMapping }
disabled={ ! getTld( searchQuery ) || this.state.isPendingSubmit }
className="map-domain-step__go button is-primary"
onClick={ this.handleAddButtonClick }
Expand Down Expand Up @@ -248,8 +250,8 @@ class MapDomainStep extends React.Component {
! includes( [ AVAILABILITY_CHECK_ERROR, NOT_REGISTRABLE ], status ) &&
includes( [ MAPPABLE, UNKNOWN ], mappableStatus )
) {
// No need to disable isPendingSubmit because this handler should perform a redirect
this.props.onMapDomain( domain );
this.setState( { isPendingSubmit: false } );
return;
}

Expand Down
21 changes: 21 additions & 0 deletions client/lib/wpcom-undocumented/lib/undocumented.js
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,27 @@ Undocumented.prototype.updateWhois = function ( domainName, whois, transferLock,
);
};

/**
* Add domain mapping for eligible clients.
*
* @param {number} siteId The site ID
* @param {string} [domainName] Name of the domain mapping
* @param {Function} fn The callback function
* @returns {Promise} A promise that resolves when the request completes
*/
Undocumented.prototype.addDomainMapping = function ( siteId, domainName, fn ) {
debug( '/site/:site_id/add-domain-mapping' );
return this.wpcom.req.post(
{
path: `/sites/${ siteId }/add-domain-mapping`,
body: {
domain: domainName,
},
},
fn
);
};

/**
* Add domain mapping for VIP clients.
*
Expand Down
80 changes: 64 additions & 16 deletions client/my-sites/domains/map-domain/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import MapDomainStep from 'calypso/components/domains/map-domain-step';
import { DOMAINS_WITH_PLANS_ONLY } from 'calypso/state/current-user/constants';
import { domainRegistration } from 'calypso/lib/cart-values/cart-items';
import wp from 'calypso/lib/wp';
import { domainManagementList } from 'calypso/my-sites/domains/paths';
import { domainManagementEdit, domainManagementList } from 'calypso/my-sites/domains/paths';
import Notice from 'calypso/components/notice';
import { currentUserHasFlag } from 'calypso/state/current-user/selectors';
import isSiteUpgradeable from 'calypso/state/selectors/is-site-upgradeable';
import isSiteOnPaidPlan from 'calypso/state/selectors/is-site-on-paid-plan';
import {
getSelectedSite,
getSelectedSiteId,
Expand All @@ -30,6 +31,7 @@ import QueryProductsList from 'calypso/components/data/query-products-list';
import { getProductsList } from 'calypso/state/products-list/selectors';
import TrademarkClaimsNotice from 'calypso/components/domains/trademark-claims-notice';
import { fillInSingleCartItemAttributes } from 'calypso/lib/cart-values';
import { successNotice } from 'calypso/state/notices/actions';

const wpcom = wp.undocumented();

Expand All @@ -39,6 +41,7 @@ export class MapDomain extends Component {
query: PropTypes.string,
domainsWithPlansOnly: PropTypes.bool.isRequired,
isSiteUpgradeable: PropTypes.bool,
isSiteOnPaidPlan: PropTypes.bool.isRequired,
productsList: PropTypes.object.isRequired,
selectedSite: PropTypes.object,
selectedSiteId: PropTypes.number,
Expand All @@ -49,6 +52,7 @@ export class MapDomain extends Component {
isMounted = false;

state = {
isBusyMapping: false,
errorMessage: null,
suggestion: null,
showTrademarkClaimsNotice: false,
Expand Down Expand Up @@ -102,18 +106,52 @@ export class MapDomain extends Component {
};

handleMapDomain = ( domain ) => {
const { selectedSite, selectedSiteSlug } = this.props;
const { selectedSite, selectedSiteSlug, translate } = this.props;

this.setState( { errorMessage: null } );
this.setState( {
errorMessage: null,
isBusyMapping: true,
} );

// For VIP sites we handle domain mappings differently
// We don't go through the usual checkout process
// Instead, we add the mapping directly
if ( selectedSite.is_vip ) {
wpcom.addVipDomainMapping( selectedSite.ID, domain ).then(
() => page( domainManagementList( selectedSiteSlug ) ),
( error ) => this.setState( { errorMessage: error.message } )
);
wpcom
.addVipDomainMapping( selectedSite.ID, domain )
.then(
() => {
page( domainManagementList( selectedSiteSlug ) );
},
( error ) => {
this.setState( { errorMessage: error.message } );
}
)
.finally( () => {
this.setState( { isBusyMapping: false } );
} );
return;
} else if ( this.props.isSiteOnPaidPlan ) {
wpcom
.addDomainMapping( selectedSite.ID, domain )
.then(
() => {
this.props.successNotice(
translate( 'Domain mapping added! Please make sure to follow the next steps below.' ),
{
isPersistent: true,
duration: 10000,
}
);
page( domainManagementEdit( selectedSiteSlug, domain ) );
},
( error ) => {
this.setState( { errorMessage: error.message } );
}
)
.finally( () => {
this.setState( { isBusyMapping: false } );
} );
return;
}

Expand Down Expand Up @@ -189,11 +227,12 @@ export class MapDomain extends Component {

<HeaderCake onClick={ this.goBack }>{ translate( 'Map a Domain' ) }</HeaderCake>

{ errorMessage && <Notice status="is-error" text={ errorMessage } /> }
{ errorMessage && <Notice status="is-error" text={ errorMessage } showDismiss={ false } /> }

<MapDomainStep
domainsWithPlansOnly={ domainsWithPlansOnly }
initialQuery={ initialQuery }
isBusyMapping={ this.state.isBusyMapping }
products={ productsList }
selectedSite={ selectedSite }
onRegisterDomain={ this.handleRegisterDomain }
Expand All @@ -205,11 +244,20 @@ export class MapDomain extends Component {
}
}

export default connect( ( state ) => ( {
selectedSite: getSelectedSite( state ),
selectedSiteId: getSelectedSiteId( state ),
selectedSiteSlug: getSelectedSiteSlug( state ),
domainsWithPlansOnly: currentUserHasFlag( state, DOMAINS_WITH_PLANS_ONLY ),
isSiteUpgradeable: isSiteUpgradeable( state, getSelectedSiteId( state ) ),
productsList: getProductsList( state ),
} ) )( withShoppingCart( localize( MapDomain ) ) );
export default connect(
( state ) => {
const selectedSiteId = getSelectedSiteId( state );
return {
selectedSite: getSelectedSite( state ),
selectedSiteId,
selectedSiteSlug: getSelectedSiteSlug( state ),
domainsWithPlansOnly: currentUserHasFlag( state, DOMAINS_WITH_PLANS_ONLY ),
isSiteUpgradeable: isSiteUpgradeable( state, selectedSiteId ),
isSiteOnPaidPlan: isSiteOnPaidPlan( state, selectedSiteId ),
productsList: getProductsList( state ),
};
},
{
successNotice,
}
)( withShoppingCart( localize( MapDomain ) ) );
6 changes: 3 additions & 3 deletions test/e2e/specs/specs-calypso/wp-manage-domains-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,16 @@ describe( `[${ host }] Managing Domains: (${ screenSize }) @parallel`, function
return await enterADomainComponent.enterADomain( blogName );
} );

it( 'Can add domain to the cart', async function () {
it.skip( 'Can add domain to the cart', async function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think we can delete these tests instead of disabling them?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, I can do that. When I was working on the PR I wasn't sure and wanted to deploy it so decided to disable them. But now that I think about it - there is no sense of keeping those. I'll prepare a PR

const enterADomainComponent = await EnterADomainComponent.Expect( driver );
return await enterADomainComponent.clickonAddButtonToAddDomainToTheCart();
} );

it( 'Can see checkout page', async function () {
it.skip( 'Can see checkout page', async function () {
return await MapADomainCheckoutPage.Expect( driver );
} );

it( 'Empty the cart', async function () {
it.skip( 'Empty the cart', async function () {
await ReaderPage.Visit( driver );
const navBarComponent = await NavBarComponent.Expect( driver );
await navBarComponent.clickMySites();
Expand Down