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

feat(ras): skip campaign setup #3051

Merged
merged 12 commits into from
Apr 25, 2024
Merged
19 changes: 10 additions & 9 deletions assets/wizards/engagement/components/prerequisite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ export default function Prerequisite( {
saveConfig,
}: PrequisiteProps ) {
const { href } = prerequisite;
const isValid = Boolean( prerequisite.active || prerequisite.is_skipped );

// If the prerequisite is active but has empty fields, show a warning.
const hasEmptyFields = () => {
if ( prerequisite.active && prerequisite.fields && prerequisite.warning ) {
if ( isValid && prerequisite.fields && prerequisite.warning ) {
const emptyValues = Object.keys( prerequisite.fields ).filter(
fieldName => '' === config[ fieldName as keyof Config ]
);
Expand Down Expand Up @@ -93,9 +94,7 @@ export default function Prerequisite( {
: sprintf(
// Translators: Save or Update settings.
__( '%s settings', 'newspack-plugin' ),
prerequisite.active
? __( 'Update', 'newspack-plugin' )
: __( 'Save', 'newspack-plugin' )
isValid ? __( 'Update', 'newspack-plugin' ) : __( 'Save', 'newspack-plugin' )
) }
</Button>
</div>
Expand Down Expand Up @@ -138,7 +137,7 @@ export default function Prerequisite( {
} }
>
{ /* eslint-disable no-nested-ternary */ }
{ ( prerequisite.active
{ ( isValid
? __( 'Update ', 'newspack-plugin' )
: prerequisite.fields
? __( 'Save ', 'newspack-plugin' )
Expand All @@ -158,8 +157,10 @@ export default function Prerequisite( {
);

let status = __( 'Pending', 'newspack-plugin' );
if ( prerequisite.active ) {
status = __( 'Ready', 'newspack-plugin' );
if ( isValid ) {
status = `${ __( 'Ready', 'newspack-plugin' ) } ${
prerequisite.is_skipped ? `(${ __( 'Skipped', 'newspack-plugin' ) })` : ''
}`;
}
if ( prerequisite.is_unavailable ) {
status = __( 'Unavailable', 'newspack-plugin' );
Expand All @@ -170,14 +171,14 @@ export default function Prerequisite( {
className="newspack-ras-wizard__prerequisite"
isMedium
expandable={ ! prerequisite.is_unavailable }
collapse={ prerequisite.active }
collapse={ isValid }
title={ prerequisite.label }
description={ sprintf(
/* translators: %s: Prerequisite status */
__( 'Status: %s', 'newspack-plugin' ),
status
) }
checkbox={ prerequisite.active ? 'checked' : 'unchecked' }
checkbox={ isValid ? 'checked' : 'unchecked' }
notificationLevel="info"
notification={ hasEmptyFields() }
>
Expand Down
1 change: 1 addition & 0 deletions assets/wizards/engagement/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export type PrequisiteProps = {
action_enabled?: boolean;
disabled_text?: string;
is_unavailable?: boolean;
is_skipped?: boolean;
};
};

Expand Down
65 changes: 63 additions & 2 deletions assets/wizards/engagement/views/reader-activation/campaign.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,26 @@ import {
SectionHeader,
Waiting,
withWizardScreen,
utils,
} from '../../../../components/src';
import Prompt from '../../components/prompt';
import Router from '../../../../components/src/proxied-imports/router';
import './style.scss';

const { useHistory } = Router;

export default withWizardScreen( () => {
const { is_skipped_campaign_setup, reader_activation_url } = newspack_engagement_wizard;

const [ inFlight, setInFlight ] = useState( false );
const [ error, setError ] = useState( false );
const [ prompts, setPrompts ] = useState( null );
const [ allReady, setAllReady ] = useState( false );
const { reader_activation_url } = newspack_engagement_wizard;
const [ skipped, setSkipped ] = useState( {
status: '',
isSkipped: is_skipped_campaign_setup === '1',
} );
const history = useHistory();

const fetchPrompts = () => {
setError( false );
Expand All @@ -40,6 +50,45 @@ export default withWizardScreen( () => {
.finally( () => setInFlight( false ) );
};

/**
* Display prompt requiring editors to confirm skipping, on confirmation send request to
* server to store skipped option in options table and redirect back to RAS
*
* @return {void}
*/
async function onSkipCampaignSetup() {
if (
! utils.confirmAction(
__(
'Are you sure you want to skip setting up a reader activation campaign?',
'newspack-plugin'
)
)
) {
return;
}
setError( false );
setSkipped( { ...skipped, status: 'pending' } );
try {
const request = await apiFetch( {
path: '/newspack/v1/wizard/newspack-engagement-wizard/reader-activation/skip-campaign-setup',
method: 'POST',
data: { skip: ! skipped.isSkipped },
} );
if ( ! request.updated ) {
setError( { message: __( 'Server not updated', 'newspack-plugin' ) } );
setSkipped( { isSkipped: false, status: '' } );
return;
}
setSkipped( { isSkipped: Boolean( request.skipped ), status: '' } );
newspack_engagement_wizard.is_skipped_campaign_setup = request.skipped ? '1' : '';
Copy link
Contributor

Choose a reason for hiding this comment

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

After this could we automatically transition to the next view? I clicked the "Skip" button and didn't realize I still had to click "Continue" to proceed.

history.push( '/reader-activation/complete' );
} catch ( err ) {
setError( err );
setSkipped( { isSkipped: false, status: '' } );
}
}

useEffect( () => {
window.scrollTo( 0, 0 );
fetchPrompts();
Expand Down Expand Up @@ -83,9 +132,21 @@ export default withWizardScreen( () => {
/>
) ) }
<div className="newspack-buttons-card">
<Button
isTertiary
disabled={ inFlight || skipped.isSkipped || skipped.status === 'pending' }
onClick={ onSkipCampaignSetup }
>
{ /* eslint-disable-next-line no-nested-ternary */ }
{ skipped.status === 'pending'
? __( 'Skipping…', 'newspack-plugin' )
: skipped.isSkipped
? __( 'Skipped', 'newspack-plugin' )
: __( 'Skip', 'newspack-plugin' ) }
</Button>
<Button
isPrimary
disabled={ inFlight || ! allReady }
disabled={ inFlight || ( ! allReady && ! skipped.isSkipped ) }
href={ `${ reader_activation_url }/complete` }
>
{ __( 'Continue', 'newspack-plugin' ) }
Expand Down
63 changes: 49 additions & 14 deletions assets/wizards/engagement/views/reader-activation/complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,26 @@ import {
} from '../../../../components/src';

const listItems = [
__(
'Your <strong>current segments and prompts</strong> will be deactivated and archived.',
'newspack-plugin'
),
__(
'<strong>Reader registration</strong> will be activated to enable better targeting for driving engagement and conversations.',
'newspack-plugin'
),
__(
'The <strong>Reader Activation campaign</strong> will be activated with default segments and settings.',
'newspack-plugin'
),
{
text: __(
'Your <strong>current segments and prompts</strong> will be deactivated and archived.',
'newspack-plugin'
),
isSkipped: '<span class="is-skipped">[skipped]</span>',
},
{
text: __(
'<strong>Reader registration</strong> will be activated to enable better targeting for driving engagement and conversations.',
'newspack-plugin'
),
},
{
text: __(
'The <strong>Reader Activation campaign</strong> will be activated with default segments and settings.',
'newspack-plugin'
),
isSkipped: '<span class="is-skipped">[skipped]</span>',
},
];

const activationSteps = [
Expand All @@ -42,6 +50,8 @@ const activationSteps = [
__( 'Activating Reader Activation Campaign…', 'newspack-plugin' ),
];

const activationStepsCount = activationSteps.length;

/**
* Get a random number between min and max.
*
Expand All @@ -60,7 +70,29 @@ export default withWizardScreen( () => {
const [ progressLabel, setProgressLabel ] = useState( false );
const [ completed, setCompleted ] = useState( false );
const timer = useRef();
const { reader_activation_url } = newspack_engagement_wizard;
const { reader_activation_url, is_skipped_campaign_setup = '' } = newspack_engagement_wizard;
const isSkippedCampaignSetup = is_skipped_campaign_setup === '1';

/**
* If skipped, remove first item.
*/
if ( isSkippedCampaignSetup && activationSteps.length !== activationStepsCount - 1 ) {
activationSteps.shift();
}

/**
* Generate step list strings
*/
for ( const listItemIndex in listItems ) {
if ( ! listItems[ listItemIndex ].text ) {
continue;
}
const suffix = isSkippedCampaignSetup ? ` ${ listItems[ listItemIndex ].isSkipped ?? '' }` : '';
listItems[ listItemIndex ] = `${ listItems[ listItemIndex ].text }${ suffix }`;
if ( isSkippedCampaignSetup ) {
listItems[ listItemIndex ] += ` ${ listItems[ listItemIndex ].isSkipped ?? '' }`;
}
}

useEffect( () => {
if ( timer.current ) {
Expand All @@ -80,7 +112,7 @@ export default withWizardScreen( () => {
setProgressLabel( __( 'Done!', 'newspack-plugin' ) );
setTimeout( () => {
setInFlight( false );
window.location = reader_activation_url;
// window.location = reader_activation_url;
}, 3000 );
}
}, [ completed, progress ] );
Expand All @@ -95,6 +127,9 @@ export default withWizardScreen( () => {
await apiFetch( {
path: '/newspack/v1/wizard/newspack-engagement-wizard/reader-activation/activate',
method: 'post',
data: {
skip_activation: isSkippedCampaignSetup,
},
} )
);
} catch ( err ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export default withWizardScreen( ( { wizardApiFetch } ) => {
const _allReady =
! missingPlugins.length &&
prerequisites &&
Object.keys( prerequisites ).every( key => prerequisites[ key ]?.active );
Object.keys( prerequisites ).every(
key => prerequisites[ key ]?.active || prerequisites[ key ]?.skipped
);

setAllReady( _allReady );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
margin-top: 0 !important;
}

span.is-skipped {
color: wp-colors.$gray-700;
}

.newspack-ras-campaign {
&__prompt-wizard,
&__completed {
Expand Down
3 changes: 2 additions & 1 deletion includes/reader-activation/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ public static function is_transactional_email_configured() {
* TODO: Make this dynamic once the third UI screen to generate the prompts is built.
*/
public static function is_ras_campaign_configured() {
return self::is_enabled();
return self::is_enabled() || get_option( Engagement_Wizard::SKIP_CAMPAIGN_SETUP_OPTION, '' ) === '1';
}

/**
Expand Down Expand Up @@ -500,6 +500,7 @@ public static function get_prerequisites_status() {
],
'ras_campaign' => [
'active' => self::is_ras_campaign_configured(),
'is_skipped' => get_option( Engagement_Wizard::SKIP_CAMPAIGN_SETUP_OPTION, '' ) === '1',
'plugins' => [
'newspack-popups' => class_exists( '\Newspack_Popups_Model' ),
],
Expand Down
33 changes: 30 additions & 3 deletions includes/wizards/class-engagement-wizard.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

namespace Newspack;

use WP_Error, WP_Query;
use TypeError;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

defined( 'ABSPATH' ) || exit;

Expand All @@ -18,6 +21,8 @@
*/
class Engagement_Wizard extends Wizard {

const SKIP_CAMPAIGN_SETUP_OPTION = '_newspack_ras_skip_campaign_setup';

/**
* The slug of this wizard.
*
Expand Down Expand Up @@ -108,6 +113,24 @@ public function register_api_endpoints() {
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/reader-activation/skip-campaign-setup',
[
'methods' => \WP_REST_Server::EDITABLE,
'callback' => function( $request ) {
$skip = $request->get_param( 'skip' );
$skip_campaign_setup = update_option( static::SKIP_CAMPAIGN_SETUP_OPTION, $skip );
return rest_ensure_response(
[
'skipped' => $skip,
'updated' => $skip_campaign_setup,
]
);
},
'permission_callback' => [ $this, 'api_permissions_check' ],
]
);
register_rest_route(
NEWSPACK_API_NAMESPACE,
'/wizard/' . $this->slug . '/newsletters',
Expand Down Expand Up @@ -256,10 +279,12 @@ public function api_update_reader_activation_settings( $request ) {
/**
* Activate reader activation and publish RAS prompts/segments.
*
* @param WP_REST_Request $request WP Rest Request object.
* @return WP_REST_Response
*/
public function api_activate_reader_activation() {
$response = Reader_Activation::activate();
public function api_activate_reader_activation( WP_REST_Request $request ) {
$skip_activation = $request->get_param( 'skip_activation' ) ?? false;
$response = $skip_activation ? true : Reader_Activation::activate();

if ( \is_wp_error( $response ) ) {
return new \WP_REST_Response( [ 'message' => $response->get_error_message() ], 400 );
Expand Down Expand Up @@ -423,6 +448,8 @@ public function enqueue_scripts_and_styles() {
$data['preview_archive'] = $newspack_popups->preview_archive();
}

$data['is_skipped_campaign_setup'] = get_option( static::SKIP_CAMPAIGN_SETUP_OPTION, '' );

\wp_localize_script(
'newspack-engagement-wizard',
'newspack_engagement_wizard',
Expand Down