Refactor input and button to validate key to its own components

This commit refactors the <input> and <button> used to validate the MSS
key to its own components. After doing this, we will be able to reuse
this components outside of the settings app. In particular, we want to
be able to use it in the welcome wizard app.

It also implements one small change to the verify button that is part of
the changes related to the welcome wizard. Now the verify button is
disabled when the MSS key <input> is empty.

[MAILPOET-4818]
This commit is contained in:
Rodrigo Primo
2023-01-20 16:19:55 -03:00
committed by Aschepikov
parent 110b67bd9c
commit e1e690ad14
7 changed files with 156 additions and 99 deletions

View File

@@ -0,0 +1,86 @@
import { Button } from 'common/index';
import { t } from 'common/functions';
import { Messages } from 'common/premium_key/messages';
import { MssStatus } from 'settings/store/types';
import { MailPoet } from 'mailpoet';
import { select } from '@wordpress/data';
import { STORE_NAME } from 'settings/store/store_name';
import { useContext } from 'react';
import { GlobalContext } from 'context';
import { useAction, useSelector, useSetting } from 'settings/store/hooks';
type KeyState = {
is_approved: boolean;
};
type KeyActivationButtonPropType = {
label: string;
isFullWidth?: boolean;
};
export function KeyActivationButton({
label,
isFullWidth = false,
}: KeyActivationButtonPropType) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { notices } = useContext<any>(GlobalContext);
const state = useSelector('getKeyActivationState')();
const setState = useAction('updateKeyActivationState');
const verifyMssKey = useAction('verifyMssKey');
const verifyPremiumKey = useAction('verifyPremiumKey');
const sendCongratulatoryMssEmail = useAction('sendCongratulatoryMssEmail');
const [apiKeyState] = useSetting('mta', 'mailpoet_api_key_state', 'data');
async function activationCallback() {
await verifyMssKey(state.key);
sendCongratulatoryMssEmail();
setState({ fromAddressModalCanBeShown: true });
}
const showPendingApprovalNotice =
state.inProgress === false &&
state.mssStatus === MssStatus.VALID_MSS_ACTIVE &&
apiKeyState &&
(apiKeyState as KeyState).is_approved === false;
const buttonIsDisabled = state.key === '' || state.key === null;
const verifyKey = async () => {
if (!state.key) {
notices.error(<p>{t('premiumTabNoKeyNotice')}</p>, { scroll: true });
return;
}
await setState({
mssStatus: null,
premiumStatus: null,
premiumInstallationStatus: null,
});
MailPoet.Modal.loading(true);
setState({ inProgress: true });
await verifyMssKey(state.key);
const currentMssStatus =
select(STORE_NAME).getKeyActivationState().mssStatus;
if (currentMssStatus === MssStatus.VALID_MSS_ACTIVE) {
await sendCongratulatoryMssEmail();
}
await verifyPremiumKey(state.key);
setState({ inProgress: false });
MailPoet.Modal.loading(false);
setState({ fromAddressModalCanBeShown: true });
};
return (
<>
<Button
type="button"
onClick={verifyKey}
isFullWidth={isFullWidth}
isDisabled={buttonIsDisabled}
>
{label}
</Button>
{state.isKeyValid !== null &&
Messages(state, showPendingApprovalNotice, activationCallback)}
</>
);
}

View File

@@ -0,0 +1,34 @@
import { Input } from 'common/index';
import { useAction, useSelector } from 'settings/store/hooks';
type KeyInputPropType = {
placeholder?: string;
isFullWidth?: boolean;
};
export function KeyInput({
placeholder,
isFullWidth = false,
}: KeyInputPropType) {
const state = useSelector('getKeyActivationState')();
const setState = useAction('updateKeyActivationState');
return (
<Input
type="text"
id="mailpoet_premium_key"
name="premium[premium_key]"
placeholder={placeholder}
isFullWidth={isFullWidth}
value={state.key || ''}
onChange={(event) =>
setState({
mssStatus: null,
premiumStatus: null,
premiumInstallationStatus: null,
key: event.target.value.trim() || null,
})
}
/>
);
}

View File

@@ -1,21 +1,11 @@
import { useContext } from 'react';
import { MailPoet } from 'mailpoet';
import { STORE_NAME } from 'settings/store/store_name';
import { select } from '@wordpress/data';
import { useAction, useSelector, useSetting } from 'settings/store/hooks'; import { useAction, useSelector, useSetting } from 'settings/store/hooks';
import { GlobalContext } from 'context';
import { Button } from 'common/button/button';
import { t } from 'common/functions'; import { t } from 'common/functions';
import { Input } from 'common/form/input/input';
import { MssStatus } from 'settings/store/types'; import { MssStatus } from 'settings/store/types';
import { Inputs, Label } from 'settings/components'; import { Inputs, Label } from 'settings/components';
import { SetFromAddressModal } from 'common/set_from_address_modal'; import { SetFromAddressModal } from 'common/set_from_address_modal';
import ReactStringReplace from 'react-string-replace'; import ReactStringReplace from 'react-string-replace';
import { Messages } from 'common/premium_key/messages'; import { KeyActivationButton } from 'common/premium_key/key_activation_button';
import { KeyInput } from 'common/premium_key/key_input';
type KeyState = {
is_approved: boolean;
};
type Props = { type Props = {
subscribersCount: number; subscribersCount: number;
@@ -50,18 +40,13 @@ const premiumTabGetKey = ReactStringReplace(
); );
export function KeyActivation({ subscribersCount }: Props) { export function KeyActivation({ subscribersCount }: Props) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { notices } = useContext<any>(GlobalContext);
const state = useSelector('getKeyActivationState')(); const state = useSelector('getKeyActivationState')();
const setState = useAction('updateKeyActivationState'); const setState = useAction('updateKeyActivationState');
const verifyMssKey = useAction('verifyMssKey');
const verifyPremiumKey = useAction('verifyPremiumKey');
const sendCongratulatoryMssEmail = useAction('sendCongratulatoryMssEmail'); const sendCongratulatoryMssEmail = useAction('sendCongratulatoryMssEmail');
const [senderAddress, setSenderAddress] = useSetting('sender', 'address'); const [senderAddress, setSenderAddress] = useSetting('sender', 'address');
const [unauthorizedAddresses, setUnauthorizedAddresses] = useSetting( const [unauthorizedAddresses, setUnauthorizedAddresses] = useSetting(
'authorized_emails_addresses_check', 'authorized_emails_addresses_check',
); );
const [apiKeyState] = useSetting('mta', 'mailpoet_api_key_state', 'data');
const setSaveDone = useAction('setSaveDone'); const setSaveDone = useAction('setSaveDone');
const setAuthorizedAddress = async (address: string) => { const setAuthorizedAddress = async (address: string) => {
await setSenderAddress(address); await setSenderAddress(address);
@@ -74,42 +59,6 @@ export function KeyActivation({ subscribersCount }: Props) {
state.mssStatus === MssStatus.VALID_MSS_ACTIVE && state.mssStatus === MssStatus.VALID_MSS_ACTIVE &&
(!senderAddress || unauthorizedAddresses); (!senderAddress || unauthorizedAddresses);
const showPendingApprovalNotice =
state.inProgress === false &&
state.mssStatus === MssStatus.VALID_MSS_ACTIVE &&
apiKeyState &&
(apiKeyState as KeyState).is_approved === false;
const verifyKey = async () => {
if (!state.key) {
notices.error(<p>{t('premiumTabNoKeyNotice')}</p>, { scroll: true });
return;
}
await setState({
mssStatus: null,
premiumStatus: null,
premiumInstallationStatus: null,
});
MailPoet.Modal.loading(true);
setState({ inProgress: true });
await verifyMssKey(state.key);
const currentMssStatus =
select(STORE_NAME).getKeyActivationState().mssStatus;
if (currentMssStatus === MssStatus.VALID_MSS_ACTIVE) {
await sendCongratulatoryMssEmail();
}
await verifyPremiumKey(state.key);
setState({ inProgress: false });
MailPoet.Modal.loading(false);
setState({ fromAddressModalCanBeShown: true });
};
async function activationCallback() {
await verifyMssKey(state.key);
sendCongratulatoryMssEmail();
setState({ fromAddressModalCanBeShown: true });
}
return ( return (
<div className="mailpoet-settings-grid"> <div className="mailpoet-settings-grid">
<Label <Label
@@ -140,25 +89,8 @@ export function KeyActivation({ subscribersCount }: Props) {
} }
/> />
<Inputs> <Inputs>
<Input <KeyInput />
type="text" <KeyActivationButton label={t('premiumTabVerifyButton')} />
id="mailpoet_premium_key"
name="premium[premium_key]"
value={state.key || ''}
onChange={(event) =>
setState({
mssStatus: null,
premiumStatus: null,
premiumInstallationStatus: null,
key: event.target.value.trim() || null,
})
}
/>
<Button type="button" onClick={verifyKey}>
{t('premiumTabVerifyButton')}
</Button>
{state.isKeyValid !== null &&
Messages(state, showPendingApprovalNotice, activationCallback)}
</Inputs> </Inputs>
{showFromAddressModal && ( {showFromAddressModal && (
<SetFromAddressModal <SetFromAddressModal

View File

@@ -33,6 +33,7 @@ class EditSignUpConfirmationEmailCest {
// when we performed Verify button at Activation Tab and also performed some savings across the plugin. // when we performed Verify button at Activation Tab and also performed some savings across the plugin.
$i->amOnMailpoetPage('Settings'); $i->amOnMailpoetPage('Settings');
$i->click('[data-automation-id="activation_settings_tab"]'); $i->click('[data-automation-id="activation_settings_tab"]');
$i->fillField('[id="mailpoet_premium_key"]', 'Any key');
$i->click('Verify'); $i->click('Verify');
$i->amOnMailpoetPage('Emails'); $i->amOnMailpoetPage('Emails');
$i->waitForText('Emails'); $i->waitForText('Emails');

View File

@@ -0,0 +1,27 @@
<%= localize({
'premiumTabNoKeyNotice': __('Please specify a license key before validating it.', 'mailpoet'),
'premiumTabKeyValidMessage': __('Your key is valid', 'mailpoet'),
'premiumTabKeyNotValidMessage': __('Your key is not valid', 'mailpoet'),
'premiumTabKeyCannotValidate': __('Yikes, we cant validate your key because:'),
'premiumTabKeyCannotValidateLocalhost': __('Youre on localhost or using an IP address instead of a domain. Not allowed for security reasons!'),
'premiumTabKeyCannotValidateBlockingHost': __('Your host is blocking the activation, e.g. Altervista'),
'premiumTabKeyCannotValidateIntranet': __('This website is on an Intranet. Activating MailPoet will not be possible.'),
'learnMore': __('Learn more'),
'premiumTabPremiumActiveMessage': __('MailPoet Premium is active', 'mailpoet'),
'premiumTabPremiumNotInstalledMessage': __('MailPoet Premium is not installed.', 'mailpoet'),
'premiumTabPremiumNotActivatedMessage': __('MailPoet Premium is installed but not activated.', 'mailpoet'),
'premiumTabPremiumDownloadMessage': __('Download MailPoet Premium plugin', 'mailpoet'),
'premiumTabPremiumActivateMessage': __('Activate MailPoet Premium plugin', 'mailpoet'),
'premiumTabPremiumInstallationInstallingMessage': __('downloading MailPoet Premium…', 'mailpoet'),
'premiumTabPremiumInstallationActivatingMessage': __('activating MailPoet Premium…', 'mailpoet'),
'premiumTabPremiumInstallationActiveMessage': __('MailPoet Premium is active!', 'mailpoet'),
'premiumTabPremiumInstallationErrorMessage': __('Something went wrong. Please [link]download the Premium plugin from your account[/link] and [link]contact our support team[/link].', 'mailpoet'),
'premiumTabPremiumKeyNotValidMessage': __('Your key is not valid for MailPoet Premium', 'mailpoet'),
'premiumTabMssActiveMessage': __('MailPoet Sending Service is active', 'mailpoet'),
'premiumTabMssNotActiveMessage': __('MailPoet Sending Service is not active.', 'mailpoet'),
'premiumTabMssActivateMessage': __('Activate MailPoet Sending Service', 'mailpoet'),
'premiumTabMssKeyNotValidMessage': __('Your key is not valid for the MailPoet Sending Service', 'mailpoet'),
'premiumTabPendingApprovalHeading': __('Note: your account is pending approval by MailPoet.', 'mailpoet'),
'premiumTabPendingApprovalMessage': __('Rest assured, this only takes just a couple of hours. Until then, you can still send email previews to yourself. Any active automatic emails, like Welcome Emails, will be paused.', 'mailpoet'),
'premiumTabCongratulatoryMssEmailSent': __('A test email was sent to [email_address]', 'mailpoet'),
}) %>

View File

@@ -186,33 +186,8 @@
'premiumTabDescription': __('Activate your [link]MailPoet plan[/link] to access advanced features like detailed analytics or subscriber segmentation, faster customer support and more.', 'mailpoet'), 'premiumTabDescription': __('Activate your [link]MailPoet plan[/link] to access advanced features like detailed analytics or subscriber segmentation, faster customer support and more.', 'mailpoet'),
'premiumTabGetKey': __('Already have a MailPoet plan? [link]Get your activation key[/link].', 'mailpoet'), 'premiumTabGetKey': __('Already have a MailPoet plan? [link]Get your activation key[/link].', 'mailpoet'),
'premiumTabGetPlan': __('Don\'t yet have a plan? [link]Sign up for one[/link].', 'mailpoet'), 'premiumTabGetPlan': __('Don\'t yet have a plan? [link]Sign up for one[/link].', 'mailpoet'),
'premiumTabNoKeyNotice': __('Please specify a license key before validating it.', 'mailpoet'),
'premiumTabVerifyButton': __('Verify', 'mailpoet'), 'premiumTabVerifyButton': __('Verify', 'mailpoet'),
'premiumTabKeyValidMessage': __('Your key is valid', 'mailpoet'),
'premiumTabKeyNotValidMessage': __('Your key is not valid', 'mailpoet'),
'premiumTabKeyCannotValidate': __('Yikes, we cant validate your key because:'),
'premiumTabKeyCannotValidateLocalhost': __('Youre on localhost or using an IP address instead of a domain. Not allowed for security reasons!'),
'premiumTabKeyCannotValidateBlockingHost': __('Your host is blocking the activation, e.g. Altervista'),
'premiumTabKeyCannotValidateIntranet': __('This website is on an Intranet. Activating MailPoet will not be possible.'),
'learnMore': __('Learn more'),
'premiumTabPremiumActiveMessage': __('MailPoet Premium is active', 'mailpoet'),
'premiumTabPremiumNotInstalledMessage': __('MailPoet Premium is not installed.', 'mailpoet'),
'premiumTabPremiumNotActivatedMessage': __('MailPoet Premium is installed but not activated.', 'mailpoet'),
'premiumTabPremiumDownloadMessage': __('Download MailPoet Premium plugin', 'mailpoet'),
'premiumTabPremiumActivateMessage': __('Activate MailPoet Premium plugin', 'mailpoet'),
'premiumTabPremiumInstallationInstallingMessage': __('downloading MailPoet Premium…', 'mailpoet'),
'premiumTabPremiumInstallationActivatingMessage': __('activating MailPoet Premium…', 'mailpoet'),
'premiumTabPremiumInstallationActiveMessage': __('MailPoet Premium is active!', 'mailpoet'),
'premiumTabPremiumInstallationErrorMessage': __('Something went wrong. Please [link]download the Premium plugin from your account[/link] and [link]contact our support team[/link].', 'mailpoet'),
'premiumTabPremiumKeyNotValidMessage': __('Your key is not valid for MailPoet Premium', 'mailpoet'),
'premiumTabMssActiveMessage': __('MailPoet Sending Service is active', 'mailpoet'),
'premiumTabMssNotActiveMessage': __('MailPoet Sending Service is not active.', 'mailpoet'),
'premiumTabMssActivateMessage': __('Activate MailPoet Sending Service', 'mailpoet'),
'premiumTabMssKeyNotValidMessage': __('Your key is not valid for the MailPoet Sending Service', 'mailpoet'),
'premiumTabPendingApprovalHeading': __('Note: your account is pending approval by MailPoet.', 'mailpoet'),
'premiumTabPendingApprovalMessage': __('Rest assured, this only takes just a couple of hours. Until then, you can still send email previews to yourself. Any active automatic emails, like Welcome Emails, will be paused.', 'mailpoet'),
'premiumTabCongratulatoryMssEmailSent': __('A test email was sent to [email_address]', 'mailpoet'),
'wcCustomizerTitle': _x('Use MailPoet to customize WooCommerce emails', "Setting for using our editor for WooCommerce email"), 'wcCustomizerTitle': _x('Use MailPoet to customize WooCommerce emails', "Setting for using our editor for WooCommerce email"),
'wcCustomizerDescription': _x('You can use the MailPoet editor to customize the template used to send WooCommerce emails (notification for order processing, completed, ...).', "Setting for using our editor for WooCommerce email"), 'wcCustomizerDescription': _x('You can use the MailPoet editor to customize the template used to send WooCommerce emails (notification for order processing, completed, ...).', "Setting for using our editor for WooCommerce email"),
'openTemplateEditor': _x('Open template editor', 'Settings button to go to WooCommerce email editor'), 'openTemplateEditor': _x('Open template editor', 'Settings button to go to WooCommerce email editor'),
@@ -302,6 +277,8 @@
'engagementTrackingPartial': __('Partial additionally track email engagement (opens, clicks). Disable cookie-based tracking.'), 'engagementTrackingPartial': __('Partial additionally track email engagement (opens, clicks). Disable cookie-based tracking.'),
'engagementTrackingBasic': __('Basic only use data your site already has about your subscribers. Disable email engagement and cookie-based tracking, and re-engagement emails.'), 'engagementTrackingBasic': __('Basic only use data your site already has about your subscribers. Disable email engagement and cookie-based tracking, and re-engagement emails.'),
}) %> }) %>
<% include 'premium_key_validation_strings.html' %>
<% endblock %> <% endblock %>
<% block after_javascript %> <% block after_javascript %>

View File

@@ -104,9 +104,9 @@
{ {
// this violation has been added by a formed employee and we don't know how that works any more, so ignore // this violation has been added by a formed employee and we don't know how that works any more, so ignore
"files": [ "files": [
"assets/js/src/common/premium_key/key_activation_button.tsx",
"assets/js/src/settings/pages/advanced/reinstall.tsx", "assets/js/src/settings/pages/advanced/reinstall.tsx",
"assets/js/src/settings/pages/advanced/recalculate_subscriber_score.tsx", "assets/js/src/settings/pages/advanced/recalculate_subscriber_score.tsx",
"assets/js/src/settings/pages/key_activation/key_activation.tsx",
"assets/js/src/settings/pages/send_with/other/activate_or_cancel.tsx", "assets/js/src/settings/pages/send_with/other/activate_or_cancel.tsx",
"assets/js/src/settings/pages/send_with/send_with_choice.tsx" "assets/js/src/settings/pages/send_with/send_with_choice.tsx"
], ],