Show different fields based on newsletter type, fix saving across

multiple endpoints
This commit is contained in:
Tautvidas Sipavičius
2016-04-06 17:57:56 +03:00
parent 104620a40a
commit ad5441487b
7 changed files with 417 additions and 113 deletions

View File

@@ -63,7 +63,6 @@ function(
break; break;
case 'reactComponent': case 'reactComponent':
console.log(data);
field = (<data.field.component {...data} />); field = (<data.field.component {...data} />);
break; break;
} }

View File

@@ -24,6 +24,12 @@ define(
item: {} item: {}
}; };
}, },
getValues: function() {
return this.props.item ? this.props.item : this.state.item;
},
getErrors: function() {
return this.props.errors ? this.props.errors : this.state.errors;
},
componentDidMount: function() { componentDidMount: function() {
if(this.props.params.id !== undefined) { if(this.props.params.id !== undefined) {
if(this.isMounted()) { if(this.isMounted()) {
@@ -37,10 +43,13 @@ define(
loading: false, loading: false,
item: {} item: {}
}); });
this.refs.form.reset(); if (props.item === undefined) {
this.refs.form.reset();
}
} else { } else {
this.loadItem(props.params.id); this.loadItem(props.params.id);
} }
console.log('Receiving props', arguments);
}, },
loadItem: function(id) { loadItem: function(id) {
this.setState({ loading: true }); this.setState({ loading: true });
@@ -123,19 +132,23 @@ define(
}.bind(this)); }.bind(this));
}, },
handleValueChange: function(e) { handleValueChange: function(e) {
var item = this.state.item, if (this.props.onChange) {
field = e.target.name; return this.props.onChange(e);
} else {
var item = this.state.item,
field = e.target.name;
item[field] = e.target.value; item[field] = e.target.value;
this.setState({ this.setState({
item: item item: item
}); });
return true; return true;
}
}, },
render: function() { render: function() {
if(this.state.errors !== undefined) { if(this.getErrors() !== undefined) {
var errors = this.state.errors.map(function(error, index) { var errors = this.getErrors().map(function(error, index) {
return ( return (
<p key={ 'error-'+index } className="mailpoet_error"> <p key={ 'error-'+index } className="mailpoet_error">
{ error } { error }
@@ -153,7 +166,7 @@ define(
return ( return (
<FormField <FormField
field={ field } field={ field }
item={ this.state.item } item={ this.getValues() }
onValueChange={ this.handleValueChange } onValueChange={ this.handleValueChange }
key={ 'field-'+i } /> key={ 'field-'+i } />
); );

View File

@@ -2,98 +2,26 @@ define(
[ [
'react', 'react',
'react-router', 'react-router',
'underscore',
'mailpoet', 'mailpoet',
'form/form.jsx', 'form/form.jsx',
'form/fields/selection.jsx', 'newsletters/send/standard.jsx',
'newsletters/send/notification.jsx',
'newsletters/send/welcome.jsx',
'newsletters/breadcrumb.jsx' 'newsletters/breadcrumb.jsx'
], ],
function( function(
React, React,
Router, Router,
_,
MailPoet, MailPoet,
Form, Form,
Selection, StandardNewsletterFields,
NotificationNewsletterFields,
WelcomeNewsletterFields,
Breadcrumb Breadcrumb
) { ) {
var settings = window.mailpoet_settings || {};
var fields = [
{
name: 'subject',
label: MailPoet.I18n.t('subjectLine'),
tip: MailPoet.I18n.t('subjectLineTip'),
type: 'text',
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('emptySubjectLineError')
}
},
{
name: 'segments',
label: MailPoet.I18n.t('segments'),
tip: MailPoet.I18n.t('segmentsTip'),
type: 'selection',
placeholder: MailPoet.I18n.t('selectSegmentPlaceholder'),
id: "mailpoet_segments",
endpoint: "segments",
multiple: true,
filter: function(segment) {
return !!(!segment.deleted_at);
},
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'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
},
{
name: 'sender_address',
type: 'text',
placeholder: MailPoet.I18n.t('senderAddressPlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.address : '',
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'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
]
}
];
var messages = { var messages = {
onUpdate: function() { onUpdate: function() {
MailPoet.Notice.success(MailPoet.I18n.t('newsletterUpdated')); MailPoet.Notice.success(MailPoet.I18n.t('newsletterUpdated'));
@@ -107,32 +35,82 @@ define(
mixins: [ mixins: [
Router.History Router.History
], ],
getInitialState: function() {
return {
fields: [],
errors: [],
item: {},
loading: false,
};
},
componentDidMount: function() { componentDidMount: function() {
if(this.isMounted()) {
this.loadItem(this.props.params.id);
}
jQuery('#mailpoet_newsletter').parsley(); jQuery('#mailpoet_newsletter').parsley();
}, },
componentWillReceiveProps: function(props) {
this.loadItem(props.params.id);
},
loadItem: function(id) {
this.setState({ loading: true });
MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'get',
data: id
}).done(function(response) {
if(response === false) {
this.setState({
loading: false,
item: {},
}, function() {
this.history.pushState(null, '/new');
}.bind(this));
} else {
this.setState({
loading: false,
item: response,
fields: this.getFieldsByNewsletter(response),
});
}
}.bind(this));
},
getFieldsByNewsletter: function(newsletter) {
switch(newsletter.type) {
case 'notification': return NotificationNewsletterFields;
case 'welcome': return WelcomeNewsletterFields;
default: return StandardNewsletterFields;
}
},
isValid: function() { isValid: function() {
return jQuery('#mailpoet_newsletter').parsley().isValid(); return jQuery('#mailpoet_newsletter').parsley().isValid();
}, },
isAutomatedNewsletter: function() {
return this.state.item.type !== 'standard';
},
handleSend: function() { handleSend: function() {
if(!this.isValid()) { if(!this.isValid()) {
jQuery('#mailpoet_newsletter').parsley().validate(); jQuery('#mailpoet_newsletter').parsley().validate();
} else { } else {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
endpoint: 'sendingQueue', endpoint: 'newsletters',
action: 'add', action: 'save',
data: { data: this.state.item,
newsletter_id: this.props.params.id, }).then((response) => {
segments: jQuery('#mailpoet_segments').val(), if (response.result === true) {
sender: { return MailPoet.Ajax.post({
'name': jQuery('#mailpoet_newsletter [name="sender_name"]').val(), endpoint: 'sendingQueue',
'address': jQuery('#mailpoet_newsletter [name="sender_address"]').val() action: 'add',
}, data: _.extend({}, this.state.item, {
reply_to: { newsletter_id: this.props.params.id,
'name': jQuery('#mailpoet_newsletter [name="reply_to_name"]').val(), }),
'address': jQuery('#mailpoet_newsletter [name="reply_to_address"]').val() });
} } else {
return response;
} }
}).done(function(response) { }).done((response) => {
if(response.result === true) { if(response.result === true) {
this.history.pushState(null, '/'); this.history.pushState(null, '/');
MailPoet.Notice.success( MailPoet.Notice.success(
@@ -147,10 +125,50 @@ define(
); );
} }
} }
}.bind(this)); });
} }
return false; return false;
}, },
handleSave: function(e) {
e.preventDefault();
MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'save',
data: this.state.item,
}).done((response) => {
this.setState({ loading: false });
if(response.result === true) {
this.history.pushState(null, '/');
messages.onUpdate();
} else {
if(response.errors.length > 0) {
this.setState({ errors: response.errors });
}
}
});
},
handleFormChange: function(e) {
console.log('Form change', e);
var item = this.state.item,
field = e.target.name;
item[field] = e.target.value;
console.log('State before change', this.state);
this.setState({
item: item
});
console.log('State after change', this.state);
return true;
},
handleFormSubmit: function() {
console.log('Handling form submit', arguments);
},
getParams: function() {
return {};
},
render: function() { render: function() {
return ( return (
<div> <div>
@@ -160,18 +178,22 @@ define(
<Form <Form
id="mailpoet_newsletter" id="mailpoet_newsletter"
endpoint="newsletters" fields={ this.state.fields }
fields={ fields } item={ this.state.item }
params={ this.props.params } params={ this.getParams() }
messages={ messages } errors= { this.state.errors }
isValid={ this.isValid } onChange={this.handleFormChange}
onSubmit={this.handleSave}
> >
<p className="submit"> <p className="submit">
<input <input
className="button button-primary" className="button button-primary"
type="button" type="button"
onClick={ this.handleSend } onClick={ this.handleSend }
value={MailPoet.I18n.t('send')} /> value={
this.isAutomatedNewsletter()
? MailPoet.I18n.t('activate')
: MailPoet.I18n.t('send')} />
&nbsp; &nbsp;
<input <input
className="button button-secondary" className="button button-secondary"

View File

@@ -0,0 +1,97 @@
define(
[
'mailpoet',
'newsletters/types/notification/scheduling.jsx'
],
function(
MailPoet,
Scheduling
) {
var settings = window.mailpoet_settings || {};
var fields = [
{
name: 'subject',
label: MailPoet.I18n.t('subjectLine'),
tip: MailPoet.I18n.t('postNotificationSubjectLineTip'),
type: 'text',
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('emptySubjectLineError')
}
},
{
name: 'options',
label: MailPoet.I18n.t('selectPeriodicity'),
type: 'reactComponent',
component: Scheduling,
},
{
name: 'segments',
label: MailPoet.I18n.t('segments'),
tip: MailPoet.I18n.t('segmentsTip'),
type: 'selection',
placeholder: MailPoet.I18n.t('selectSegmentPlaceholder'),
id: "mailpoet_segments",
endpoint: "segments",
multiple: true,
filter: function(segment) {
return !!(!segment.deleted_at);
},
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'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
},
{
name: 'sender_address',
type: 'text',
placeholder: MailPoet.I18n.t('senderAddressPlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.address : '',
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'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
]
}
];
return fields;
}
);

View File

@@ -0,0 +1,89 @@
define(
[
'mailpoet'
],
function(
MailPoet
) {
var settings = window.mailpoet_settings || {};
var fields = [
{
name: 'subject',
label: MailPoet.I18n.t('subjectLine'),
tip: MailPoet.I18n.t('subjectLineTip'),
type: 'text',
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('emptySubjectLineError')
}
},
{
name: 'segments',
label: MailPoet.I18n.t('segments'),
tip: MailPoet.I18n.t('segmentsTip'),
type: 'selection',
placeholder: MailPoet.I18n.t('selectSegmentPlaceholder'),
id: "mailpoet_segments",
endpoint: "segments",
multiple: true,
filter: function(segment) {
return !!(!segment.deleted_at);
},
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'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
},
{
name: 'sender_address',
type: 'text',
placeholder: MailPoet.I18n.t('senderAddressPlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.address : '',
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'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
]
}
];
return fields;
}
);

View File

@@ -0,0 +1,81 @@
define(
[
'mailpoet',
'newsletters/types/welcome/scheduling.jsx'
],
function(
MailPoet,
Scheduling
) {
var settings = window.mailpoet_settings || {};
var fields = [
{
name: 'subject',
label: MailPoet.I18n.t('subjectLine'),
tip: MailPoet.I18n.t('subjectLineTip'),
type: 'text',
validation: {
'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('emptySubjectLineError')
}
},
{
name: 'options',
label: MailPoet.I18n.t('sendWelcomeEmailWhen'),
type: 'reactComponent',
component: Scheduling,
},
{
name: 'sender',
label: MailPoet.I18n.t('sender'),
tip: MailPoet.I18n.t('senderTip'),
fields: [
{
name: 'sender_name',
type: 'text',
placeholder: MailPoet.I18n.t('senderNamePlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
},
{
name: 'sender_address',
type: 'text',
placeholder: MailPoet.I18n.t('senderAddressPlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.address : '',
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'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
]
}
];
return fields;
}
);

View File

@@ -87,6 +87,9 @@
'postNotificationsNewsletterTypeDescription': __('Automatically send posts immediately, daily, weekly or monthly. Filter by categories, if you like.'), 'postNotificationsNewsletterTypeDescription': __('Automatically send posts immediately, daily, weekly or monthly. Filter by categories, if you like.'),
'selectPeriodicity': __('Select a periodicity'), 'selectPeriodicity': __('Select a periodicity'),
'periodicity': __('Periodicity'), 'periodicity': __('Periodicity'),
'postNotificationSubjectLineTip': __("Insert [newsletter:total] to show number of posts, [newsletter:post_title] to show the latest post's title & [newsletter:number] to display the issue number."),
'activate': __('Activate'),
'sendWelcomeEmailWhen': __('Send welcome email when...'),
'daily': __('Once a day at...'), 'daily': __('Once a day at...'),
'weekly': __('Weekly on...'), 'weekly': __('Weekly on...'),