Skip to content

Commit 14761a3

Browse files
authored
Global Styles on Personal AB: Calypso changes (#98538)
* Calypso is now aware of the GS on Personal AB experiment code and reacts accordingly * Removed pre intitialization requirement * Fixed test * Fixed tests * Fixed the global isGlobalStylesOnPersonal check so that it does not trigger an error in some circumstances * On the Design Picker, we now use the global isGlobalStylesOnPersonal global as default value to avoid prop drilling into the package. * Added window interface to comply with TS * Updated comment to better describe the functionality * Add the global styles experiment status to the window object by using useEffect * Simplified the withSiteGlobalStylesOnPersonal hoc * Removed an unused import * We now support the LiTS with no site selected as part of the experiment * Added final experiment key
1 parent 09df749 commit 14761a3

File tree

20 files changed

+208
-69
lines changed

20 files changed

+208
-69
lines changed

client/components/premium-global-styles-upgrade-modal/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isEnabled } from '@automattic/calypso-config';
21
import { PLAN_PERSONAL, PLAN_PREMIUM } from '@automattic/calypso-products';
32
import { Button, Gridicon, Dialog, ScreenReaderText, PlanPrice } from '@automattic/components';
43
import { Plans } from '@automattic/data-stores';
@@ -10,6 +9,7 @@ import { LoadingEllipsis } from 'calypso/components/loading-ellipsis';
109
import useCheckPlanAvailabilityForPurchase from 'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase';
1110
import { useSelector } from 'calypso/state';
1211
import { getProductBySlug } from 'calypso/state/products-list/selectors';
12+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
1313
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
1414
import useGlobalStylesUpgradeTranslations from './use-global-styles-upgrade-translations';
1515
import './style.scss';
@@ -34,9 +34,7 @@ export default function PremiumGlobalStylesUpgradeModal( {
3434
}: PremiumGlobalStylesUpgradeModalProps ) {
3535
const translate = useTranslate();
3636
// @TODO Cleanup once the test phase is over.
37-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' )
38-
? PLAN_PERSONAL
39-
: PLAN_PREMIUM;
37+
const upgradeToPlan = useSiteGlobalStylesOnPersonal() ? PLAN_PERSONAL : PLAN_PREMIUM;
4038
const premiumPlanProduct = useSelector( ( state ) => getProductBySlug( state, upgradeToPlan ) );
4139
const selectedSiteId = useSelector( getSelectedSiteId );
4240
const translations = useGlobalStylesUpgradeTranslations( { numOfSelectedGlobalStyles } );

client/components/premium-global-styles-upgrade-modal/use-global-styles-upgrade-translations.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { isEnabled } from '@automattic/calypso-config';
21
import { PLAN_PERSONAL, PLAN_PREMIUM } from '@automattic/calypso-products';
32
import { Plans } from '@automattic/data-stores';
43
import { useHasEnTranslation } from '@automattic/i18n-utils';
54
import { useTranslate } from 'i18n-calypso';
5+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
66

77
interface Props {
88
numOfSelectedGlobalStyles?: number;
@@ -14,9 +14,7 @@ const useGlobalStylesUpgradeTranslations = ( { numOfSelectedGlobalStyles = 1 }:
1414
const plans = Plans.usePlans( { coupon: undefined } );
1515

1616
// @TODO Cleanup once the test phase is over.
17-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' )
18-
? PLAN_PERSONAL
19-
: PLAN_PREMIUM;
17+
const upgradeToPlan = useSiteGlobalStylesOnPersonal() ? PLAN_PERSONAL : PLAN_PREMIUM;
2018

2119
const planTitle = plans?.data?.[ upgradeToPlan ]?.productNameShort ?? '';
2220

@@ -43,7 +41,7 @@ const useGlobalStylesUpgradeTranslations = ( { numOfSelectedGlobalStyles = 1 }:
4341
featuresTitle: translate( 'Included with your %(planTitle)s plan', {
4442
args: { planTitle },
4543
} ),
46-
features: isEnabled( 'global-styles/on-personal-plan' ) ? personalFeatures : premiumFeatures,
44+
features: useSiteGlobalStylesOnPersonal() ? personalFeatures : premiumFeatures,
4745
description: translate(
4846
'You’ve selected a premium style that will only be visible to visitors after upgrading to the %(planTitle)s plan or higher.',
4947
'You’ve selected premium styles that will only be visible to visitors after upgrading to the %(planTitle)s plan or higher.',

client/components/theme-tier/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const getIncludedWithLabel = ( planSlug ) => {
1515

1616
export const THEME_TIER_PREMIUM = 'premium';
1717
export const THEME_TIER_PARTNER = 'partner';
18+
export const THEME_TIER_FREE = 'free';
1819

1920
/**
2021
* @typedef {Object} THEME_TIERS

client/components/theme-tier/theme-tier-badge/test/theme-tier-style-variation-badge.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/** @jest-environment jsdom */
22
import { getPlan } from '@automattic/calypso-products';
3+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
34
import { act, render, screen, waitFor } from '@testing-library/react';
45
import userEvent from '@testing-library/user-event';
56
import { useSelector } from 'calypso/state';
@@ -12,6 +13,23 @@ describe( 'ThemeTierStyleVariationBadge', () => {
1213
const siteSlug = 'example.wordpress.com';
1314
let originalWindowLocation;
1415

16+
// Create a QueryClient instance
17+
const createTestQueryClient = () =>
18+
new QueryClient( {
19+
defaultOptions: {
20+
queries: {
21+
retry: false, // Disable retries for tests
22+
cacheTime: 0, // Disable cache
23+
},
24+
},
25+
} );
26+
27+
// Utility to wrap component with QueryClientProvider
28+
const renderWithQueryClient = ( ui ) => {
29+
const queryClient = createTestQueryClient();
30+
return render( <QueryClientProvider client={ queryClient }>{ ui }</QueryClientProvider> );
31+
};
32+
1533
beforeEach( () => {
1634
jest.clearAllMocks();
1735

@@ -30,7 +48,7 @@ describe( 'ThemeTierStyleVariationBadge', () => {
3048
} );
3149

3250
test( 'should render upgrade label', () => {
33-
render( <ThemeTierStyleVariationBadge /> );
51+
renderWithQueryClient( <ThemeTierStyleVariationBadge /> );
3452

3553
const upgradeLabel = screen.getByText( 'Upgrade' );
3654
expect( upgradeLabel ).toBeInTheDocument();
@@ -44,7 +62,7 @@ describe( 'ThemeTierStyleVariationBadge', () => {
4462
getPathSlug: () => pathSlug,
4563
} ) );
4664

47-
render( <ThemeTierStyleVariationBadge /> );
65+
renderWithQueryClient( <ThemeTierStyleVariationBadge /> );
4866

4967
userEvent.hover( screen.getByText( 'Upgrade' ) );
5068

client/components/theme-tier/theme-tier-badge/theme-tier-style-variation-badge.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import { isEnabled } from '@automattic/calypso-config';
21
import { PLAN_PREMIUM, getPlan, PLAN_PERSONAL } from '@automattic/calypso-products';
32
import { PremiumBadge } from '@automattic/components';
43
import { createInterpolateElement } from '@wordpress/element';
54
import { useTranslate } from 'i18n-calypso';
5+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
66
import ThemeTierBadgeCheckoutLink from './theme-tier-badge-checkout-link';
77
import ThemeTierTooltipTracker from './theme-tier-tooltip-tracker';
88

99
export default function ThemeTierStyleVariationBadge() {
1010
const translate = useTranslate();
1111

1212
// @TODO Cleanup once the test phase is over.
13-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' )
13+
const upgradeToPlan = useSiteGlobalStylesOnPersonal()
1414
? getPlan( PLAN_PERSONAL )
1515
: getPlan( PLAN_PREMIUM );
1616

client/jetpack-cloud/sections/partner-portal/primary/wpcom-atomic-hosting/card-content.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { recordTracksEvent } from 'calypso/state/analytics/actions';
1818
import { infoNotice } from 'calypso/state/notices/actions';
1919
import useProductsQuery from 'calypso/state/partner-portal/licenses/hooks/use-products-query';
2020
import { doesPartnerRequireAPaymentMethod } from 'calypso/state/partner-portal/partner/selectors';
21+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
2122
import FeatureItem from './feature-item';
2223
import './style.scss';
2324

@@ -48,6 +49,9 @@ export default function CardContent( {
4849
const { data: agencyProducts } = useProductsQuery();
4950
const paymentMethodRequired = useSelector( doesPartnerRequireAPaymentMethod );
5051

52+
// Set a prop on the window object on whether Global Styles is available on the Personal plan.
53+
useSiteGlobalStylesOnPersonal();
54+
5155
const getLogo = ( planSlug: string ) => {
5256
switch ( planSlug ) {
5357
case PLAN_BUSINESS:

client/landing/stepper/declarative-flow/internals/steps-repository/design-setup/test/unified-design-picker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ const renderComponent = ( component, initialState = {} ) => {
117117
const store = mockStore( {
118118
purchases: {},
119119
sites: {},
120+
ui: { selectedSiteId: 'anySiteId' },
120121
...initialState,
121122
} );
122123

client/landing/stepper/declarative-flow/internals/steps-repository/design-setup/unified-design-picker.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isEnabled } from '@automattic/calypso-config';
21
import {
32
TERM_ANNUALLY,
43
TERM_MONTHLY,
@@ -41,6 +40,7 @@ import {
4140
THEME_TIERS,
4241
THEME_TIER_PARTNER,
4342
THEME_TIER_PREMIUM,
43+
THEME_TIER_FREE,
4444
} from 'calypso/components/theme-tier/constants';
4545
import ThemeTierBadge from 'calypso/components/theme-tier/theme-tier-badge';
4646
import { ThemeUpgradeModal as UpgradeModal } from 'calypso/components/theme-upgrade-modal';
@@ -57,6 +57,7 @@ import {
5757
getProductsByBillingSlug,
5858
} from 'calypso/state/products-list/selectors';
5959
import { hasPurchasedDomain } from 'calypso/state/purchases/selectors/has-purchased-domain';
60+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
6061
import { useSiteGlobalStylesStatus } from 'calypso/state/sites/hooks/use-site-global-styles-status';
6162
import { getSiteSlug } from 'calypso/state/sites/selectors';
6263
import { setActiveTheme, activateOrInstallThenActivate } from 'calypso/state/themes/actions';
@@ -144,6 +145,8 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
144145
const siteDescription = site?.description;
145146
const { shouldLimitGlobalStyles } = useSiteGlobalStylesStatus( site?.ID );
146147
const { data: siteActiveTheme } = useActiveThemeQuery( site?.ID ?? 0, !! site?.ID );
148+
// @TODO Cleanup once the test phase is over.
149+
const isGlobalStylesOnPersonal = useSiteGlobalStylesOnPersonal( site?.ID );
147150

148151
const isDesignFirstFlow =
149152
flow === DESIGN_FIRST_FLOW || queryParams.get( 'flowToReturnTo' ) === DESIGN_FIRST_FLOW;
@@ -581,16 +584,13 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
581584
} )
582585
);
583586

584-
// @TODO Cleanup once the test phase is over.
585-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' ) ? 'personal' : 'premium';
586-
587587
goToCheckout( {
588588
flowName: flow,
589589
stepName,
590590
siteSlug: siteSlug || urlToSlug( site?.URL || '' ) || '',
591591
// When the user is done with checkout, send them back to the current url
592592
destination: window.location.href.replace( window.location.origin, '' ),
593-
plan: upgradeToPlan,
593+
plan: isGlobalStylesOnPersonal ? 'personal' : 'premium',
594594
} );
595595

596596
setShowPremiumGlobalStylesModal( false );
@@ -736,7 +736,7 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
736736
} );
737737
}
738738
function getPrimaryActionButtonAction(): () => void {
739-
if ( isEnabled( 'global-styles/on-personal-plan' ) ) {
739+
if ( isGlobalStylesOnPersonal ) {
740740
if ( isLockedTheme ) {
741741
return upgradePlan;
742742
}
@@ -841,12 +841,16 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
841841
placeholder={ null }
842842
previewUrl={ previewUrl }
843843
splitDefaultVariation={
844-
! ( selectedDesign?.design_tier === THEME_TIER_PREMIUM ) &&
845-
! isBundled &&
846-
! isPremiumThemeAvailable &&
847-
! didPurchaseSelectedTheme &&
848-
! isPluginBundleEligible &&
849-
shouldLimitGlobalStyles
844+
( isGlobalStylesOnPersonal &&
845+
selectedDesign?.design_tier === THEME_TIER_FREE &&
846+
shouldLimitGlobalStyles ) ||
847+
( ! ( selectedDesign?.design_tier === THEME_TIER_PREMIUM ) &&
848+
! isBundled &&
849+
! isPremiumThemeAvailable &&
850+
! didPurchaseSelectedTheme &&
851+
! isPluginBundleEligible &&
852+
! isGlobalStylesOnPersonal &&
853+
shouldLimitGlobalStyles )
850854
}
851855
needsUpgrade={ shouldLimitGlobalStyles || isLockedTheme }
852856
title={ headerDesignTitle }

client/landing/stepper/declarative-flow/internals/steps-repository/launchpad/sidebar.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PLAN_PREMIUM } from '@automattic/calypso-products';
1+
import { PLAN_PERSONAL, PLAN_PREMIUM } from '@automattic/calypso-products';
22
import { Badge, CircularProgressBar, Gridicon, Tooltip } from '@automattic/components';
33
import {
44
OnboardSelect,
@@ -25,6 +25,7 @@ import { TYPE_TIER } from 'calypso/my-sites/earn/memberships/constants';
2525
import { useSelector } from 'calypso/state';
2626
import { isCurrentUserEmailVerified } from 'calypso/state/current-user/selectors';
2727
import { getConnectUrlForSiteId } from 'calypso/state/memberships/settings/selectors';
28+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
2829
import { useSiteGlobalStylesStatus } from 'calypso/state/sites/hooks/use-site-global-styles-status';
2930
import { getEnhancedTasks } from './task-definitions';
3031
import { getLaunchpadTranslations } from './translations';
@@ -107,6 +108,9 @@ const Sidebar = ( {
107108
);
108109

109110
const displayGlobalStylesWarning = globalStylesInUse && shouldLimitGlobalStyles;
111+
const globalStylesMinimumPlan = useSiteGlobalStylesOnPersonal( site?.ID )
112+
? PLAN_PERSONAL
113+
: PLAN_PREMIUM;
110114

111115
let checklist = launchpadChecklist;
112116
if ( selectedDesign?.default ) {
@@ -129,7 +133,7 @@ const Sidebar = ( {
129133
site,
130134
submit,
131135
displayGlobalStylesWarning,
132-
globalStylesMinimumPlan: PLAN_PREMIUM,
136+
globalStylesMinimumPlan,
133137
setShowPlansModal,
134138
queryClient,
135139
goToStep,

client/landing/stepper/declarative-flow/internals/steps-repository/launchpad/task-definitions/plan/index.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import { isEnabled } from '@automattic/calypso-config';
2-
import {
3-
FEATURE_STYLE_CUSTOMIZATION,
4-
isFreePlanProduct,
5-
PLAN_PERSONAL,
6-
} from '@automattic/calypso-products';
1+
import { FEATURE_STYLE_CUSTOMIZATION, isFreePlanProduct } from '@automattic/calypso-products';
72
import { updateLaunchpadSettings } from '@automattic/data-stores/src/queries/use-launchpad';
83
import { localizeUrl } from '@automattic/i18n-utils';
94
import { Task } from '@automattic/launchpad';
@@ -54,13 +49,6 @@ export const getPlanSelectedTask: TaskAction = ( task, flow, context ): Task =>
5449
const { siteSlug, displayGlobalStylesWarning, globalStylesMinimumPlan, hasSkippedCheckout } =
5550
context;
5651

57-
// @TODO Cleanup once the test phase is over.
58-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' )
59-
? PLAN_PERSONAL
60-
: globalStylesMinimumPlan;
61-
62-
const shouldDisplayWarning = displayGlobalStylesWarning;
63-
6452
return {
6553
...task,
6654
actionDispatch: () => {
@@ -71,8 +59,8 @@ export const getPlanSelectedTask: TaskAction = ( task, flow, context ): Task =>
7159
}
7260
},
7361
calypso_path: addQueryArgs( `/plans/${ siteSlug }`, {
74-
...( shouldDisplayWarning && {
75-
plan: upgradeToPlan,
62+
...( displayGlobalStylesWarning && {
63+
plan: globalStylesMinimumPlan,
7664
feature: FEATURE_STYLE_CUSTOMIZATION,
7765
} ),
7866
} ),

client/my-sites/theme/main.jsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getTracksAnonymousUserId } from '@automattic/calypso-analytics';
2-
import config, { isEnabled } from '@automattic/calypso-config';
2+
import config from '@automattic/calypso-config';
33
import {
44
FEATURE_UPLOAD_THEMES,
55
PLAN_BUSINESS,
@@ -66,6 +66,7 @@ import isSiteWPForTeams from 'calypso/state/selectors/is-site-wpforteams';
6666
import isVipSite from 'calypso/state/selectors/is-vip-site';
6767
import siteHasFeature from 'calypso/state/selectors/site-has-feature';
6868
import { useSiteGlobalStylesStatus } from 'calypso/state/sites/hooks/use-site-global-styles-status';
69+
import { withSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/with-site-global-styles-on-personal';
6970
import { getCurrentPlan, isSiteOnECommerceTrial } from 'calypso/state/sites/plans/selectors';
7071
import { getSiteSlug, isJetpackSite } from 'calypso/state/sites/selectors';
7172
import {
@@ -677,28 +678,28 @@ class ThemeSheet extends Component {
677678
isBundledSoftwareSet,
678679
} = this.props;
679680

680-
const isGlobalStylesEnabled = isEnabled( 'global-styles/on-personal-plan' );
681+
const isGlobalStylesOnPersonal = this.props.isGlobalStylesOnPersonal;
681682

682683
const isFreeTier = isFreePlan && themeTier?.slug === 'free';
683684
const hasLimitedFeatures =
684685
! isExternallyManagedTheme &&
685686
! isBundledSoftwareSet &&
686687
! isThemePurchased &&
687-
! isGlobalStylesEnabled &&
688+
! isGlobalStylesOnPersonal &&
688689
! isPremium &&
689690
shouldLimitGlobalStyles;
690691

691692
const shouldSplitDefaultVariation = isFreeTier || hasLimitedFeatures;
692693

693-
const needsUpgrade = isGlobalStylesEnabled
694-
? isFreePlan
694+
const needsUpgrade = isGlobalStylesOnPersonal
695+
? isFreePlan || shouldLimitGlobalStyles
695696
: shouldLimitGlobalStyles || ( isPremium && ! isThemePurchased );
696697

697698
return (
698699
styleVariations.length > 0 && (
699700
<ThemeStyleVariations
700701
description={ this.getStyleVariationDescription() }
701-
splitDefaultVariation={ shouldSplitDefaultVariation }
702+
splitDefaultVariation={ shouldSplitDefaultVariation || needsUpgrade }
702703
selectedVariation={ this.getSelectedStyleVariation() }
703704
variations={ styleVariations }
704705
needsUpgrade={ needsUpgrade }
@@ -1077,7 +1078,7 @@ class ThemeSheet extends Component {
10771078
params.append( 'redirect_to', window.location.href.replace( window.location.origin, '' ) );
10781079

10791080
this.setState( { showUnlockStyleUpgradeModal: false } );
1080-
const upgradeToPlan = isEnabled( 'global-styles/on-personal-plan' ) ? 'personal' : 'premium';
1081+
const upgradeToPlan = this.props.isGlobalStylesOnPersonal ? 'personal' : 'premium';
10811082

10821083
page( `/checkout/${ this.props.siteSlug || '' }/${ upgradeToPlan }?${ params.toString() }` );
10831084
};
@@ -1485,4 +1486,6 @@ export default connect(
14851486
themeStartActivationSync: themeStartActivationSyncAction,
14861487
errorNotice,
14871488
}
1488-
)( withSiteGlobalStylesStatus( localize( ThemeSheetWithOptions ) ) );
1489+
)(
1490+
withSiteGlobalStylesStatus( withSiteGlobalStylesOnPersonal( localize( ThemeSheetWithOptions ) ) )
1491+
);

client/my-sites/theme/theme-style-variations/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import AsyncLoad from 'calypso/components/async-load';
2+
import { useSiteGlobalStylesOnPersonal } from 'calypso/state/sites/hooks/use-site-global-styles-on-personal';
23
import type { StyleVariation } from '@automattic/design-picker/src/types';
34
import type { TranslateResult } from 'i18n-calypso';
45
import './style.scss';
@@ -20,6 +21,7 @@ const ThemeStyleVariations = ( {
2021
needsUpgrade,
2122
onClick,
2223
}: ThemeStyleVariationsProps ) => {
24+
const isGlobalStylesOnPersonal = useSiteGlobalStylesOnPersonal();
2325
return (
2426
<div className="theme__sheet-style-variations">
2527
{ !! description && <p>{ description }</p> }
@@ -35,6 +37,7 @@ const ThemeStyleVariations = ( {
3537
showOnlyHoverViewDefaultVariation={ false }
3638
needsUpgrade={ needsUpgrade }
3739
onSelect={ onClick }
40+
isGlobalStylesOnPersonal={ isGlobalStylesOnPersonal }
3841
/>
3942
</div>
4043
</div>

0 commit comments

Comments
 (0)