From 886d47ca5b841a4a9c85ca514c266b89b40460fc Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Wed, 17 May 2023 10:15:42 +0300 Subject: [PATCH 1/8] Show only personal and premium plans when jetpackAppPlans parameter is set Support configuring wp.com/plans/yearly/{siteURL} flow with jetpackAppPlans parameter, that limits the number of plans shown to support Jetpack app-specific flows --- client/my-sites/plans/controller.jsx | 1 + client/my-sites/plans/main.jsx | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/client/my-sites/plans/controller.jsx b/client/my-sites/plans/controller.jsx index 144794c3f6dede..481eafc247a8ff 100644 --- a/client/my-sites/plans/controller.jsx +++ b/client/my-sites/plans/controller.jsx @@ -39,6 +39,7 @@ export function plans( context, next ) { : undefined } domainAndPlanPackage={ context.query.domainAndPlanPackage } + jetpackAppPlans={ context.query.jetpackAppPlans } is2023PricingGridVisible={ is2023PricingGridActivePage( null, context.pathname ) } /> ); diff --git a/client/my-sites/plans/main.jsx b/client/my-sites/plans/main.jsx index 198f3a80e23798..160bdf35dd383a 100644 --- a/client/my-sites/plans/main.jsx +++ b/client/my-sites/plans/main.jsx @@ -9,6 +9,8 @@ import { PLAN_WOOEXPRESS_SMALL_MONTHLY, PLAN_WOOEXPRESS_MEDIUM, PLAN_WOOEXPRESS_MEDIUM_MONTHLY, + TYPE_PERSONAL, + TYPE_PREMIUM, } from '@automattic/calypso-products'; import { is2023PricingGridActivePage } from '@automattic/calypso-products/src/plans-utilities'; import { WpcomPlansUI } from '@automattic/data-stores'; @@ -259,6 +261,7 @@ class Plans extends Component { } const hideFreePlan = ! is2023PricingGridVisible || this.props.isDomainAndPlanPackageFlow; + const planTypes = this.props.jetpackAppPlans ? [ TYPE_PERSONAL, TYPE_PREMIUM ] : null; const hidePlanTypeSelector = this.props.domainAndPlanPackage && @@ -281,6 +284,7 @@ class Plans extends Component { showTreatmentPlansReorderTest={ this.props.showTreatmentPlansReorderTest } hidePlansFeatureComparison={ this.props.isDomainAndPlanPackageFlow } is2023PricingGridVisible={ is2023PricingGridVisible } + planTypes={ planTypes } /> ); } From 0ffb9a8ba2908f108bb377cb321499df18b1889d Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Wed, 17 May 2023 10:18:17 +0300 Subject: [PATCH 2/8] Hide domain and plan package header from Plans when jetpackAppPlans parameter is set Support the Jetpack app plan purchasing flows by hiding a navigation header that displays the position inside domain and plan upsell flow and allows to come back --- client/my-sites/plans/main.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/my-sites/plans/main.jsx b/client/my-sites/plans/main.jsx index 160bdf35dd383a..c4164cf0f6a17b 100644 --- a/client/my-sites/plans/main.jsx +++ b/client/my-sites/plans/main.jsx @@ -355,6 +355,7 @@ class Plans extends Component { isFreePlan, currentPlanIntervalType, domainFromHomeUpsellFlow, + jetpackAppPlans, } = this.props; if ( ! selectedSite || this.isInvalidPlanInterval() || ! currentPlan ) { @@ -418,7 +419,9 @@ class Plans extends Component { { isDomainAndPlanPackageFlow && ( <>
- + { ! jetpackAppPlans && ( + + ) } From a070609c86e1b8ae3e74d49d4ca132f9ca7984ac Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Wed, 17 May 2023 10:29:19 +0300 Subject: [PATCH 3/8] Remember jetpackAppPlans parameter when toggling between Plan intervals --- .../plans-features-main/components/plan-type-selector.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/my-sites/plans-features-main/components/plan-type-selector.tsx b/client/my-sites/plans-features-main/components/plan-type-selector.tsx index 9d015fac289f01..5a4e1e318d3bad 100644 --- a/client/my-sites/plans-features-main/components/plan-type-selector.tsx +++ b/client/my-sites/plans-features-main/components/plan-type-selector.tsx @@ -180,6 +180,8 @@ export const IntervalTypeToggle: React.FunctionComponent< IntervalTypeProps > = 'domainAndPlanPackage' ); + const isJetpackAppFlow = new URLSearchParams( window.location.search ).get( 'jetpackAppPlans' ); + const intervalTabs = showBiannualToggle ? [ 'yearly', '2yearly' ] : [ 'monthly', 'yearly' ]; return ( @@ -196,6 +198,7 @@ export const IntervalTypeToggle: React.FunctionComponent< IntervalTypeProps > = intervalType: interval, domain: isDomainUpsellFlow, domainAndPlanPackage: isDomainAndPlanPackageFlow, + jetpackAppPlans: isJetpackAppFlow, ...additionalPathProps, } ) } isPlansInsideStepper={ props.isPlansInsideStepper } From a7e3f3cc2c7f4a0386400bec19ab3fb2fa32c5d5 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Thu, 18 May 2023 14:20:38 +0300 Subject: [PATCH 4/8] Parse domainAndPlanPackage and jetpackAppPlans parameters to support both true and false values Parse using JSON.parse so parameter=true would be correctly parsed as a true Boolean and parameter=false would be parsed as a false Boolean --- client/my-sites/plans/controller.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/my-sites/plans/controller.jsx b/client/my-sites/plans/controller.jsx index 481eafc247a8ff..3d3adf423f8300 100644 --- a/client/my-sites/plans/controller.jsx +++ b/client/my-sites/plans/controller.jsx @@ -38,8 +38,8 @@ export function plans( context, next ) { ? context.query.addDomainFlow === 'true' : undefined } - domainAndPlanPackage={ context.query.domainAndPlanPackage } - jetpackAppPlans={ context.query.jetpackAppPlans } + domainAndPlanPackage={ JSON.parse( context.query.domainAndPlanPackage ) } + jetpackAppPlans={ JSON.parse( context.query.jetpackAppPlans ) } is2023PricingGridVisible={ is2023PricingGridActivePage( null, context.pathname ) } /> ); From 5d02efe3a5097453ed8b55514172c1be1cde5de4 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Thu, 18 May 2023 17:18:57 +0300 Subject: [PATCH 5/8] Handle parameters being null before parsing to Boolean --- client/my-sites/plans/controller.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/my-sites/plans/controller.jsx b/client/my-sites/plans/controller.jsx index 3d3adf423f8300..b4c25913202457 100644 --- a/client/my-sites/plans/controller.jsx +++ b/client/my-sites/plans/controller.jsx @@ -38,8 +38,8 @@ export function plans( context, next ) { ? context.query.addDomainFlow === 'true' : undefined } - domainAndPlanPackage={ JSON.parse( context.query.domainAndPlanPackage ) } - jetpackAppPlans={ JSON.parse( context.query.jetpackAppPlans ) } + domainAndPlanPackage={ JSON.parse( context.query.domainAndPlanPackage ?? false ) } + jetpackAppPlans={ JSON.parse( context.query.jetpackAppPlans ?? false ) } is2023PricingGridVisible={ is2023PricingGridActivePage( null, context.pathname ) } /> ); From 23db8484f3a3ed0576f42bf8dbe1b303017879cf Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Tue, 30 May 2023 10:09:14 +0300 Subject: [PATCH 6/8] Use explicit value comparison for query parameters --- client/my-sites/plans/controller.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/my-sites/plans/controller.jsx b/client/my-sites/plans/controller.jsx index b4c25913202457..0a921c8bb9190d 100644 --- a/client/my-sites/plans/controller.jsx +++ b/client/my-sites/plans/controller.jsx @@ -38,8 +38,8 @@ export function plans( context, next ) { ? context.query.addDomainFlow === 'true' : undefined } - domainAndPlanPackage={ JSON.parse( context.query.domainAndPlanPackage ?? false ) } - jetpackAppPlans={ JSON.parse( context.query.jetpackAppPlans ?? false ) } + domainAndPlanPackage={ context.query.domainAndPlanPackage === 'true' } + jetpackAppPlans={ context.query.jetpackAppPlans === 'true' } is2023PricingGridVisible={ is2023PricingGridActivePage( null, context.pathname ) } /> ); From 9671427fc6af1c93044960357bf3d54d8c35a6d7 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Tue, 30 May 2023 10:09:50 +0300 Subject: [PATCH 7/8] Add a comment explaining filtering of premium and personal plans for the Jetpack app --- client/my-sites/plans/main.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/my-sites/plans/main.jsx b/client/my-sites/plans/main.jsx index c4164cf0f6a17b..6b471ec5e5f2ee 100644 --- a/client/my-sites/plans/main.jsx +++ b/client/my-sites/plans/main.jsx @@ -261,6 +261,7 @@ class Plans extends Component { } const hideFreePlan = ! is2023PricingGridVisible || this.props.isDomainAndPlanPackageFlow; + // The Jetpack mobile app only wants to display two plans -- personal and premium const planTypes = this.props.jetpackAppPlans ? [ TYPE_PERSONAL, TYPE_PREMIUM ] : null; const hidePlanTypeSelector = From 00ecf1d58f7c7cc82739ff12340f79c4f8dd1245 Mon Sep 17 00:00:00 2001 From: Povilas Staskus Date: Tue, 30 May 2023 10:50:59 +0300 Subject: [PATCH 8/8] Define domainAndPlanPackage prop as boolean --- client/my-sites/plans/main.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/my-sites/plans/main.jsx b/client/my-sites/plans/main.jsx index 6b471ec5e5f2ee..0d226bae2a4b68 100644 --- a/client/my-sites/plans/main.jsx +++ b/client/my-sites/plans/main.jsx @@ -150,7 +150,7 @@ class Plans extends Component { static propTypes = { context: PropTypes.object.isRequired, redirectToAddDomainFlow: PropTypes.bool, - domainAndPlanPackage: PropTypes.string, + domainAndPlanPackage: PropTypes.bool, intervalType: PropTypes.string, customerType: PropTypes.string, selectedFeature: PropTypes.string,