Skip to content

Commit

Permalink
Add a GS limit notice in the Global Styles sidebar (#74510)
Browse files Browse the repository at this point in the history
* Add a GS limit notice in the Global Styles Root Screen

Just like the other Global Styles limit notices, the new notice is shown only for free and personal plans. The implementation is based on the existing noticed by refactoring the logic we used in the pre-save GS notice.

* Moved useGlobalStylesConfig in a js file so we can bypass the TS errors without using ts-ignore.

* Add the upgrade nudge using the ComplementaryArea slot.

* Added comment explaining why we are doing the condition check inside the fill component.

* Refactor the implementation based on code review feedback.

- Add dedicated tracking events for the sidebar notice and add a blog_id parameter (which will help to get some stats about the sites that upgrade)
- Rename isVisible property to globalStylesInUse
- Rename utils.ts to tracks-events.ts for better visibility
- Removed a property since from the use function since it's not needed
- Fixed CSS margin issues in the sidebar

* Add blog_id property in the tracks events.

* Remove redundant else branch.

* Rename the event functions and change copy

* Add return type and make the component default.

* Update apps/editing-toolkit/editing-toolkit-plugin/wpcom-global-styles/index.php

Co-authored-by: Miguel Torres <[email protected]>

* Fix the Fill hard reset when the nudge appears and disappears the first time.

* Add docblock explaining why we need the fragment.

* Update apps/editing-toolkit/editing-toolkit-plugin/wpcom-global-styles/global-style-sidebar-notice.tsx

Co-authored-by: Miguel Torres <[email protected]>

* Update apps/editing-toolkit/editing-toolkit-plugin/wpcom-global-styles/notice.js

Co-authored-by: Miguel Torres <[email protected]>

* Changed the background color in the test trying to fix the failure.

* Try to fix the failing test (take 2).

* Remove filter

* Add cache clear.

* Pass the theme directly.

* Try to fix the failing test.

* Fix unit test

---------

Co-authored-by: Miguel Torres <[email protected]>
  • Loading branch information
BogdanUngureanu and mmtr authored Apr 3, 2023
1 parent cfa1d33 commit 529f46e
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
declare const wpcomGlobalStyles: { upgradeUrl: string; blogId: string };

import { ExternalLink, Fill, Notice } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { createInterpolateElement, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { recordUpgradeNoticeSidebarShow, recordUpgradeSidebarNoticeClick } from './tracks-events';
import { useGlobalStylesConfig } from './use-global-styles-config';

const GLOBAL_STYLES_SIDEBAR = 'edit-site/global-styles';

type CoreInterfacePlaceholder = {
getActiveComplementaryArea: ( area: string ) => string;
};

export default function GlobalStylesSidebarNotice(): JSX.Element {
const area = useSelect(
( select ) =>
( select( 'core/interface' ) as CoreInterfacePlaceholder ).getActiveComplementaryArea(
'core/edit-site'
),
[]
);

const isGlobalStylesSidebar = GLOBAL_STYLES_SIDEBAR === area;

const globalStylesInUse = useGlobalStylesConfig().globalStylesInUse;

useEffect( () => {
if ( globalStylesInUse && isGlobalStylesSidebar ) {
recordUpgradeNoticeSidebarShow();
}
}, [ globalStylesInUse, isGlobalStylesSidebar ] );

return (
<Fill name="ComplementaryArea/core/edit-site">
{ /*
The fragment is needed in order to avoid a forceUpdate done by the slot-fill library.
When a forceUpdate is done, the local state of the components is cleared, which means that when the nudge is displayed/removed,
the state of GS is cleared, disrupting the UX, since the user will be redirected to the main GS root screen.
*/ }
<>
{ /*
We'll need to do the condition here because if we are doing an early return, the fill will be introduced at the bottom of the page, which means some additional CSS magic needs to be done.
*/ }
{ globalStylesInUse && isGlobalStylesSidebar && (
<div className="interface-complementary-area">
<Notice status="warning" isDismissible={ false } className="wpcom-global-styles-notice">
{ createInterpolateElement(
__(
'Your changes include customized styles that will only be visible once you <a>upgrade to a Premium plan</a>.',
'full-site-editing'
),
{
a: (
<ExternalLink
href={ wpcomGlobalStyles.upgradeUrl }
target="_blank"
onClick={ recordUpgradeSidebarNoticeClick }
/>
),
}
) }
</Notice>
</div>
) }
</>
</Fill>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './public-path';

import domReady from '@wordpress/dom-ready';
import { registerPlugin } from '@wordpress/plugins';
import GlobalStylesSidebarNotice from './global-style-sidebar-notice';
import GlobalStylesModal from './modal';
import GlobalStylesNotice from './notice';
import './store';
Expand All @@ -13,6 +14,7 @@ const showGlobalStylesComponents = () => {
<>
<GlobalStylesModal />
<GlobalStylesNotice />
<GlobalStylesSidebarNotice />
</>
),
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ function wpcom_should_limit_global_styles( $blog_id = 0 ) {
return true;
}

/**
* Get the WPCOM blog id of the current site for tracking purposes.
*/
function wpcom_global_styles_get_wpcom_current_blog_id() {
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
return get_current_blog_id();
} elseif ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) {
/*
* Atomic sites have the WP.com blog ID stored as a Jetpack option. This code deliberately
* doesn't use `Jetpack_Options::get_option` so it works even when Jetpack has not been loaded.
*/
$jetpack_options = get_option( 'jetpack_options' );
if ( is_array( $jetpack_options ) && isset( $jetpack_options['id'] ) ) {
return (int) $jetpack_options['id'];
}
}

return null;
}

/**
* Wrapper to test a blog sticker on both Simple and Atomic sites at once.
*
Expand Down Expand Up @@ -131,8 +151,9 @@ function wpcom_global_styles_enqueue_block_editor_assets() {
'wpcom-global-styles-editor',
'wpcomGlobalStyles',
array(
'assetsUrl' => plugins_url( 'dist/', __FILE__ ),
'upgradeUrl' => "$calypso_domain/plans/$site_slug?plan=value_bundle&feature=advanced-design-customization",
'assetsUrl' => plugins_url( 'dist/', __FILE__ ),
'upgradeUrl' => "$calypso_domain/plans/$site_slug?plan=value_bundle&feature=advanced-design-customization",
'wpcomBlogId' => wpcom_global_styles_get_wpcom_current_blog_id(),
)
);
wp_enqueue_style(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,14 @@
/* global wpcomGlobalStyles */
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { ExternalLink, Notice } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { createInterpolateElement, render, useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

import './notice.scss';
import { recordUpgradePreSaveNoticeClick, recordUpgradeNoticePreSaveShow } from './tracks-events';
import { useGlobalStylesConfig } from './use-global-styles-config';

function GlobalStylesNoticeComponent() {
const { globalStylesConfig, siteChanges } = useSelect( ( select ) => {
const {
getEditedEntityRecord,
__experimentalGetCurrentGlobalStylesId,
__experimentalGetDirtyEntityRecords,
} = select( 'core' );

const _globalStylesId = __experimentalGetCurrentGlobalStylesId
? __experimentalGetCurrentGlobalStylesId()
: null;
const globalStylesRecord = getEditedEntityRecord( 'root', 'globalStyles', _globalStylesId );

return {
globalStylesConfig: {
styles: globalStylesRecord?.styles ?? {},
settings: globalStylesRecord?.settings ?? {},
},
siteChanges: __experimentalGetDirtyEntityRecords ? __experimentalGetDirtyEntityRecords() : [],
};
}, [] );

// Do not show the notice if the use is trying to save the default styles.
const isVisible =
Object.keys( globalStylesConfig.styles ).length ||
Object.keys( globalStylesConfig.settings ).length;
const { siteChanges, globalStylesInUse } = useGlobalStylesConfig();

// Closes the sidebar if there are no more changes to be saved.
useEffect( () => {
Expand All @@ -50,19 +26,21 @@ function GlobalStylesNoticeComponent() {
}, [ siteChanges ] );

useEffect( () => {
if ( isVisible ) {
recordTracksEvent( 'calypso_global_styles_gating_notice_show', {
context: 'site-editor',
} );
if ( globalStylesInUse ) {
recordUpgradeNoticePreSaveShow();
}
}, [ isVisible ] );
}, [ globalStylesInUse ] );

if ( ! isVisible ) {
if ( ! globalStylesInUse ) {
return null;
}

return (
<Notice status="warning" isDismissible={ false } className="wpcom-global-styles-notice">
<Notice
status="warning"
isDismissible={ false }
className="wpcom-global-styles-notice notice-margin"
>
{ createInterpolateElement(
__(
'Your changes include customized styles that will only be visible once you <a>upgrade to a Premium plan</a>.',
Expand All @@ -73,11 +51,7 @@ function GlobalStylesNoticeComponent() {
<ExternalLink
href={ wpcomGlobalStyles.upgradeUrl }
target="_blank"
onClick={ () =>
recordTracksEvent( 'calypso_global_styles_gating_notice_upgrade_click', {
context: 'site-editor',
} )
}
onClick={ recordUpgradePreSaveNoticeClick }
/>
),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
.wpcom-global-styles-notice {
margin: 16px 0 0;
margin: 0 0 0 0;

.notice-margin {
margin: 16px 0 0;
}

.components-notice__content {
margin-right: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,18 @@ class WPCOM_Global_Styles_Test extends TestCase {
* Tests that Global Styles are blocked in the frontend.
*/
public function test_wpcom_block_global_styles_frontend() {
switch_theme( 'twentytwentythree' );
$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme(), true );
$decoded_data = json_decode( $user_cpt['post_content'], true );
unset( $decoded_data['isGlobalStylesUserThemeJSON'] );
$config = $decoded_data;

$config['styles']['color']['background'] = 'hotpink';

$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) );
$theme_json_resolver = new WP_Theme_JSON_Resolver();
$user_data = $theme_json_resolver->get_user_data()->get_data();
$user_data['styles']['color']['background'] = 'hotpink';

// Check that the custom color is kept when Global Styles are available.
$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $user_data, 'custom' ) );
$this->assertEquals( 'hotpink', $theme_json->get_data()['styles']['color']['background'] );

// Check that the custom color is blocked when Global Styles are limited.
add_filter( 'wpcom_force_limit_global_styles', '__return_true' );

$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) );

$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $user_data, 'custom' ) );
$this->assertEmpty( $theme_json->get_data()['styles']['color']['background'] );

remove_filter( 'wpcom_force_limit_global_styles', '__return_true' );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';

declare const wpcomGlobalStyles: { upgradeUrl: string; wpcomBlogId: string | null };

/**
* Record an event when a user clicks on the notice from the pre-save panel.
*/
export function recordUpgradePreSaveNoticeClick(): void {
recordTracksEvent( 'calypso_global_styles_gating_notice_upgrade_click', {
context: 'site-editor',
blog_id: wpcomGlobalStyles.wpcomBlogId,
} );
}

/**
* Record an event when a user clicks on the notice from the Global Styles sidebar.
*/
export function recordUpgradeSidebarNoticeClick(): void {
recordTracksEvent( 'calypso_global_styles_gating_notice_sidebar_upgrade_click', {
context: 'site-editor',
blog_id: wpcomGlobalStyles.wpcomBlogId,
} );
}

/**
* Record an event when the GS upgrade notice is shown in the pre-save screen.
*/
export function recordUpgradeNoticePreSaveShow(): void {
recordTracksEvent( 'calypso_global_styles_gating_notice_show', {
context: 'site-editor',
blog_id: wpcomGlobalStyles.wpcomBlogId,
} );
}

/**
* Record an event when the GS upgrade notice is shown in the Global Styles sidebar.
*/
export function recordUpgradeNoticeSidebarShow(): void {
recordTracksEvent( 'calypso_global_styles_gating_sidebar_notice_show', {
context: 'site-editor',
blog_id: wpcomGlobalStyles.wpcomBlogId,
} );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useSelect } from '@wordpress/data';

export function useGlobalStylesConfig() {
return useSelect( ( select ) => {
const {
getEditedEntityRecord,
__experimentalGetCurrentGlobalStylesId,
__experimentalGetDirtyEntityRecords,
} = select( 'core' );

const _globalStylesId = __experimentalGetCurrentGlobalStylesId
? __experimentalGetCurrentGlobalStylesId()
: null;
const globalStylesRecord = getEditedEntityRecord( 'root', 'globalStyles', _globalStylesId );

const globalStylesConfig = {
styles: globalStylesRecord?.styles ?? {},
settings: globalStylesRecord?.settings ?? {},
};

// Determine if the global Styles are in use on the current site.
const globalStylesInUse = !! (
Object.keys( globalStylesConfig.styles ).length ||
Object.keys( globalStylesConfig.settings ).length
);

return {
globalStylesInUse,
siteChanges: __experimentalGetDirtyEntityRecords ? __experimentalGetDirtyEntityRecords() : [],
};
}, [] );
}

0 comments on commit 529f46e

Please sign in to comment.