Add react component support to Forms, make newsletter scheduling

components reusable
This commit is contained in:
Tautvidas Sipavičius
2016-04-01 14:00:52 +03:00
parent c1a3ba67f5
commit 104620a40a
9 changed files with 301 additions and 145 deletions

View File

@@ -61,6 +61,11 @@ function(
case 'date':
field = (<FormFieldDate {...data} />);
break;
case 'reactComponent':
console.log(data);
field = (<data.field.component {...data} />);
break;
}
if(inline === true) {

View File

@@ -6,8 +6,8 @@ import NewsletterTypes from 'newsletters/types.jsx'
import NewsletterTemplates from 'newsletters/templates.jsx'
import NewsletterSend from 'newsletters/send.jsx'
import NewsletterStandard from 'newsletters/types/standard.jsx'
import NewsletterWelcome from 'newsletters/types/welcome.jsx'
import NewsletterNotification from 'newsletters/types/notification.jsx'
import NewsletterWelcome from 'newsletters/types/welcome/welcome.jsx'
import NewsletterNotification from 'newsletters/types/notification/notification.jsx'
import createHashHistory from 'history/lib/createHashHistory'
let history = createHashHistory({ queryKey: false })

View File

@@ -0,0 +1,95 @@
define(
[
'underscore',
'react',
'react-router',
'mailpoet',
'newsletters/types/notification/scheduling.jsx',
'newsletters/breadcrumb.jsx'
],
function(
_,
React,
Router,
MailPoet,
Scheduling,
Breadcrumb
) {
var field = {
name: 'options',
label: 'Periodicity',
type: 'reactComponent',
component: Scheduling,
};
var NewsletterNotification = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
options: {
intervalType: 'daily',
timeOfDay: 0,
weekDay: 1,
monthDay: 0,
nthWeekDay: 1,
}
};
},
handleValueChange: function(event) {
var state = this.state;
state[event.target.name] = event.target.value;
this.setState(state);
},
handleNext: function() {
MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'create',
data: _.extend({}, this.state, {
type: 'notification'
}),
}).done(function(response) {
if(response.result && response.newsletter.id) {
this.showTemplateSelection(response.newsletter.id);
} else {
if(response.errors.length > 0) {
response.errors.map(function(error) {
MailPoet.Notice.error(error);
});
}
}
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
},
render: function() {
return (
<div>
<h1>{MailPoet.I18n.t('postNotificationNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" />
<h3>{MailPoet.I18n.t('selectPeriodicity')}</h3>
<Scheduling
item={this.state}
field={field}
onValueChange={this.handleValueChange} />
<p className="submit">
<input
className="button button-primary"
type="button"
onClick={ this.handleNext }
value={MailPoet.I18n.t('next')} />
</p>
</div>
);
},
});
return NewsletterNotification;
}
);

View File

@@ -4,26 +4,18 @@ define(
'react',
'react-router',
'mailpoet',
'form/form.jsx',
'form/fields/select.jsx',
'form/fields/selection.jsx',
'form/fields/text.jsx',
'newsletters/breadcrumb.jsx'
'form/fields/select.jsx'
],
function(
_,
React,
Router,
MailPoet,
Form,
Select,
Selection,
Text,
Breadcrumb
Select
) {
var intervalField = {
name: 'interval',
name: 'intervalType',
values: {
'daily': MailPoet.I18n.t('daily'),
'weekly': MailPoet.I18n.t('weekly'),
@@ -96,137 +88,113 @@ define(
},
};
var NewsletterWelcome = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
intervalType: 'immediate', // 'immediate'|'daily'|'weekly'|'monthly'
timeOfDay: 0,
weekDay: 1,
monthDay: 0,
nthWeekDay: 1,
};
var NotificationScheduling = React.createClass({
_getCurrentValue: function() {
return this.props.item[this.props.field.name] || {};
},
handleValueChange: function(name, value) {
var oldValue = this._getCurrentValue(),
newValue = {};
newValue[name] = value;
return this.props.onValueChange({
target: {
name: this.props.field.name,
value: _.extend({}, oldValue, newValue)
}
});
},
handleIntervalChange: function(event) {
this.setState({
intervalType: event.target.value,
});
return this.handleValueChange(
'intervalType',
event.target.value
);
},
handleTimeOfDayChange: function(event) {
this.setState({
timeOfDay: event.target.value,
});
return this.handleValueChange(
'timeOfDay',
event.target.value
);
},
handleWeekDayChange: function(event) {
this.setState({
weekDay: event.target.value,
});
return this.handleValueChange(
'weekDay',
event.target.value
);
},
handleMonthDayChange: function(event) {
this.setState({
monthDay: event.target.value,
});
return this.handleValueChange(
'monthDay',
event.target.value
);
},
handleNthWeekDayChange: function(event) {
this.setState({
nthWeekDay: event.target.value,
});
},
handleNext: function() {
MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'create',
data: {
type: 'notification',
options: this.state,
},
}).done(function(response) {
if(response.result && response.newsletter.id) {
this.showTemplateSelection(response.newsletter.id);
} else {
if(response.errors.length > 0) {
response.errors.map(function(error) {
MailPoet.Notice.error(error);
});
}
}
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
return this.handleValueChange(
'nthWeekDay',
event.target.value
);
},
render: function() {
var timeOfDaySelection,
var value = this._getCurrentValue(),
timeOfDaySelection,
weekDaySelection,
monthDaySelection,
nthWeekDaySelection;
if (this.state.intervalType !== 'immediately') {
if (value.intervalType !== 'immediately') {
timeOfDaySelection = (
<Select
field={timeOfDayField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleTimeOfDayChange} />
);
}
if (this.state.intervalType === 'weekly'
|| this.state.intervalType === 'nthWeekDay') {
if (value.intervalType === 'weekly'
|| value.intervalType === 'nthWeekDay') {
weekDaySelection = (
<Select
field={weekDayField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleWeekDayChange} />
);
}
if (this.state.intervalType === 'monthly') {
if (value.intervalType === 'monthly') {
monthDaySelection = (
<Select
field={monthDayField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleMonthDayChange} />
);
}
if (this.state.intervalType === 'nthWeekDay') {
if (value.intervalType === 'nthWeekDay') {
nthWeekDaySelection = (
<Select
field={nthWeekDayField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleNthWeekDayChange} />
);
}
return (
<div>
<h1>{MailPoet.I18n.t('postNotificationNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" />
<Select
field={intervalField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleIntervalChange} />
{nthWeekDaySelection}
{monthDaySelection}
{weekDaySelection}
{timeOfDaySelection}
<p className="submit">
<input
className="button button-primary"
type="button"
onClick={ this.handleNext }
value={MailPoet.I18n.t('next')} />
</p>
</div>
);
},
});
return NewsletterWelcome;
return NotificationScheduling;
}
);

View File

@@ -3,16 +3,12 @@ define(
'react',
'react-router',
'mailpoet',
'form/form.jsx',
'form/fields/selection.jsx',
'newsletters/breadcrumb.jsx'
],
function(
React,
Router,
MailPoet,
Form,
Selection,
Breadcrumb
) {

View File

@@ -4,9 +4,7 @@ define(
'react',
'react-router',
'mailpoet',
'form/form.jsx',
'form/fields/select.jsx',
'form/fields/selection.jsx',
'form/fields/text.jsx',
'newsletters/breadcrumb.jsx'
],
@@ -15,9 +13,7 @@ define(
React,
Router,
MailPoet,
Form,
Select,
Selection,
Text,
Breadcrumb
) {
@@ -64,43 +60,51 @@ define(
}
};
var NewsletterWelcome = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
event: 'segment',
segment: 1,
role: 'subscriber',
afterTimeNumber: 1,
afterTimeType: 'immediate',
};
var WelcomeScheduling = React.createClass({
_getCurrentValue: function() {
return this.props.item[this.props.field.name] || {};
},
handleValueChange: function(name, value) {
var oldValue = this._getCurrentValue(),
newValue = {};
newValue[name] = value;
return this.props.onValueChange({
target: {
name: this.props.field.name,
value: _.extend({}, oldValue, newValue)
}
});
},
handleEventChange: function(event) {
this.setState({
event: event.target.value,
});
return this.handleValueChange(
'event',
event.target.value
);
},
handleSegmentChange: function(event) {
this.setState({
segment: event.target.value,
});
return this.handleValueChange(
'segment',
event.target.value
);
},
handleRoleChange: function(event) {
this.setState({
role: event.target.value,
});
return this.handleValueChange(
'role',
event.target.value
);
},
handleAfterTimeNumberChange: function(event) {
this.setState({
afterTimeNumber: event.target.value,
});
return this.handleValueChange(
'afterTimeNumber',
event.target.value
);
},
handleAfterTimeTypeChange: function(event) {
this.setState({
afterTimeType: event.target.value,
});
return this.handleValueChange(
'afterTimeType',
event.target.value
);
},
handleNext: function() {
MailPoet.Ajax.post({
@@ -126,40 +130,38 @@ define(
this.history.pushState(null, `/template/${newsletterId}`);
},
render: function() {
var roleSegmentSelection, timeNumber;
if (this.state.event === 'user') {
var value = this._getCurrentValue(),
roleSegmentSelection, timeNumber;
if (value.event === 'user') {
roleSegmentSelection = (
<Select
field={roleField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleRoleChange} />
);
} else {
roleSegmentSelection = (
<Select
field={segmentField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleSegmentChange} />
);
}
if (this.state.afterTimeType !== 'immediate') {
if (value.afterTimeType !== 'immediate') {
timeNumber = (
<Text
field={afterTimeNumberField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleAfterTimeNumberChange} />
);
}
return (
<div>
<h1>{MailPoet.I18n.t('welcomeNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" />
<h3>{MailPoet.I18n.t('selectEventToSendWelcomeEmail')}</h3>
<Select
field={events}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleEventChange} />
{roleSegmentSelection}
@@ -168,21 +170,14 @@ define(
<Select
field={afterTimeTypeField}
item={this.state}
item={this._getCurrentValue()}
onValueChange={this.handleAfterTimeTypeChange}/>
<p className="submit">
<input
className="button button-primary"
type="button"
onClick={ this.handleNext }
value={MailPoet.I18n.t('next')} />
</p>
</div>
);
},
});
return NewsletterWelcome;
return WelcomeScheduling;
}
);

View File

@@ -0,0 +1,95 @@
define(
[
'underscore',
'react',
'react-router',
'mailpoet',
'newsletters/types/welcome/scheduling.jsx',
'newsletters/breadcrumb.jsx'
],
function(
_,
React,
Router,
MailPoet,
Scheduling,
Breadcrumb
) {
var field = {
name: 'options',
label: 'Event',
type: 'reactComponent',
component: Scheduling,
};
var NewsletterWelcome = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
options: {
event: 'segment',
segment: 1,
role: 'subscriber',
afterTimeNumber: 1,
afterTimeType: 'immediate',
}
};
},
handleValueChange: function(event) {
var state = this.state;
state[event.target.name] = event.target.value;
this.setState(state);
},
handleNext: function() {
MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'create',
data: _.extend({}, this.state, {
type: 'welcome'
}),
}).done(function(response) {
if(response.result && response.newsletter.id) {
this.showTemplateSelection(response.newsletter.id);
} else {
if(response.errors.length > 0) {
response.errors.map(function(error) {
MailPoet.Notice.error(error);
});
}
}
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
},
render: function() {
return (
<div>
<h1>{MailPoet.I18n.t('welcomeNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" />
<h3>{MailPoet.I18n.t('selectEventToSendWelcomeEmail')}</h3>
<Scheduling
item={this.state}
field={field}
onValueChange={this.handleValueChange} />
<p className="submit">
<input
className="button button-primary"
type="button"
onClick={ this.handleNext }
value={MailPoet.I18n.t('next')} />
</p>
</div>
);
},
});
return NewsletterWelcome;
}
);

View File

@@ -85,6 +85,8 @@
'setUp': __('Set up'),
'postNotificationNewsletterTypeTitle': __('Post notifications'),
'postNotificationsNewsletterTypeDescription': __('Automatically send posts immediately, daily, weekly or monthly. Filter by categories, if you like.'),
'selectPeriodicity': __('Select a periodicity'),
'periodicity': __('Periodicity'),
'daily': __('Once a day at...'),
'weekly': __('Weekly on...'),