Display the last newsletter step for the re-engagement email

[MAILPOET-3763]
This commit is contained in:
Pavel Dohnal
2021-09-13 14:18:31 +02:00
committed by Veljko V
parent 6ac7015b5c
commit 7749d17fb1
3 changed files with 196 additions and 2 deletions

View File

@@ -8,6 +8,7 @@ import StandardNewsletterFields from 'newsletters/send/standard.jsx';
import NotificationNewsletterFields from 'newsletters/send/notification.jsx'; import NotificationNewsletterFields from 'newsletters/send/notification.jsx';
import WelcomeNewsletterFields from 'newsletters/send/welcome.jsx'; import WelcomeNewsletterFields from 'newsletters/send/welcome.jsx';
import AutomaticEmailFields from 'newsletters/send/automatic.jsx'; import AutomaticEmailFields from 'newsletters/send/automatic.jsx';
import { ReEngagementNewsletterFields } from 'newsletters/send/re_engagement';
import HelpTooltip from 'help-tooltip.jsx'; import HelpTooltip from 'help-tooltip.jsx';
import jQuery from 'jquery'; import jQuery from 'jquery';
import Background from 'common/background/background'; import Background from 'common/background/background';
@@ -68,6 +69,7 @@ class NewsletterSend extends React.Component {
switch (newsletter.type) { switch (newsletter.type) {
case 'notification': return NotificationNewsletterFields; case 'notification': return NotificationNewsletterFields;
case 'welcome': return WelcomeNewsletterFields; case 'welcome': return WelcomeNewsletterFields;
case 're_engagement': return ReEngagementNewsletterFields;
case 'automatic': case 'automatic':
if (automaticEmails[newsletter.options.group]) { if (automaticEmails[newsletter.options.group]) {
return AutomaticEmailFields; return AutomaticEmailFields;

View File

@@ -0,0 +1,192 @@
import React from 'react';
import MailPoet from 'mailpoet';
import { assoc, find, map } from 'lodash/fp';
import { Scheduling } from '../types/re_engagement/scheduling';
import GATrackingField from './ga_tracking';
import SenderField from './sender_address_field';
interface ReengagementWindow extends Window {
settings: {
deactivate_subscriber_after_inactive_days: string;
}
}
declare let window: ReengagementWindow;
interface onValueChangeParam {
target: {
name: string,
value: {
afterTimeNumber: number|string,
afterTimeType: string,
},
};
}
interface Props {
item: {
options: {
afterTimeNumber: number|string,
afterTimeType: string,
}
};
onValueChange: (val: onValueChangeParam) => void;
}
function FormReEngagementScheduling(props: Props): JSX.Element {
return (
<Scheduling
afterTimeNumber={props.item.options.afterTimeNumber.toString()}
afterTimeType={props.item.options.afterTimeType}
inactiveSubscribersPeriod={
Number(window.settings.deactivate_subscriber_after_inactive_days)
}
updateAfterTimeNumber={(value) => {
props.onValueChange({
target: {
name: 'options',
value: assoc('afterTimeNumber', value, props.item.options),
},
});
}}
updateAfterTimeType={(value) => {
props.onValueChange({
target: {
name: 'options',
value: assoc('afterTimeType', value, props.item.options),
},
});
}}
/>
);
}
const fields = [
{
name: 'email-header',
label: null,
tip: null,
fields: [
{
name: 'subject',
customLabel: MailPoet.I18n.t('subjectLabel'),
className: 'mailpoet-form-field-subject',
placeholder: MailPoet.I18n.t('subjectLine'),
tooltip: MailPoet.I18n.t('subjectLineTip'),
type: 'text',
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('emptySubjectLineError'),
maxLength: 250,
},
},
{
name: 'preheader',
customLabel: MailPoet.I18n.t('preheaderLabel'),
className: 'mailpoet-form-field-preheader',
placeholder: MailPoet.I18n.t('preheaderLine'),
// ignore for now until the MailPoet object is refactored to typescript
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
tooltip: `${MailPoet.I18n.t('preheaderLineTip1')} ${MailPoet.I18n.t('preheaderLineTip2')}`,
type: 'textarea',
validation: {
maxLength: 250,
},
},
],
},
{
name: 'options',
type: 'reactComponent',
component: FormReEngagementScheduling,
},
{
name: 'segments',
label: MailPoet.I18n.t('segments'),
tip: MailPoet.I18n.t('segmentsTip'),
type: 'selection',
placeholder: MailPoet.I18n.t('selectSegmentPlaceholder'),
id: 'mailpoet_segments',
api_version: MailPoet.apiVersion,
endpoint: 'segments',
multiple: true,
filter: function filter(segment) {
return !segment.deleted_at;
},
getLabel: function getLabel(segment) {
return segment.name;
},
getCount: function getCount(segment) {
return parseInt(segment.subscribers, 10).toLocaleString();
},
transformChangedValue: function transformChangedValue(segmentIds) {
const allSegments = this.getItems();
return map((id) => find((segment) => segment.id === id, allSegments), segmentIds);
},
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('noSegmentsSelectedError'),
},
},
{
name: 'sender',
label: MailPoet.I18n.t('sender'),
tip: MailPoet.I18n.t('senderTip'),
fields: [
{
name: 'sender_name',
type: 'text',
placeholder: MailPoet.I18n.t('senderNamePlaceholder'),
validation: {
'data-parsley-required': true,
},
},
{
name: 'sender_address',
type: 'reactComponent',
component: SenderField,
placeholder: MailPoet.I18n.t('senderAddressPlaceholder'),
validation: {
'data-parsley-required': true,
'data-parsley-type': 'email',
},
},
],
},
{
name: 'reply-to',
label: MailPoet.I18n.t('replyTo'),
tip: MailPoet.I18n.t('replyToTip'),
inline: true,
fields: [
{
name: 'reply_to_name',
type: 'text',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder'),
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
validation: {
'data-parsley-type': 'email',
},
},
],
},
GATrackingField,
];
export const ReEngagementNewsletterFields = {
// ignore for now until we refactor the forms to typescript
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
getFields() {
return fields;
},
getSendButtonOptions(): { value: string } {
return {
value: MailPoet.I18n.t('activate'),
};
},
};

View File

@@ -12,8 +12,8 @@ interface Props {
afterTimeNumber: string; afterTimeNumber: string;
afterTimeType: string; afterTimeType: string;
inactiveSubscribersPeriod: number; inactiveSubscribersPeriod: number;
updateAfterTimeNumber: (string) => void; updateAfterTimeNumber: (arg: string) => void;
updateAfterTimeType: (string) => void; updateAfterTimeType: (arg: string) => void;
} }
export function Scheduling({ export function Scheduling({