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': case 'date':
field = (<FormFieldDate {...data} />); field = (<FormFieldDate {...data} />);
break; break;
case 'reactComponent':
console.log(data);
field = (<data.field.component {...data} />);
break;
} }
if(inline === true) { if(inline === true) {

View File

@@ -6,8 +6,8 @@ import NewsletterTypes from 'newsletters/types.jsx'
import NewsletterTemplates from 'newsletters/templates.jsx' import NewsletterTemplates from 'newsletters/templates.jsx'
import NewsletterSend from 'newsletters/send.jsx' import NewsletterSend from 'newsletters/send.jsx'
import NewsletterStandard from 'newsletters/types/standard.jsx' import NewsletterStandard from 'newsletters/types/standard.jsx'
import NewsletterWelcome from 'newsletters/types/welcome.jsx' import NewsletterWelcome from 'newsletters/types/welcome/welcome.jsx'
import NewsletterNotification from 'newsletters/types/notification.jsx' import NewsletterNotification from 'newsletters/types/notification/notification.jsx'
import createHashHistory from 'history/lib/createHashHistory' import createHashHistory from 'history/lib/createHashHistory'
let history = createHashHistory({ queryKey: false }) 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',
'react-router', 'react-router',
'mailpoet', 'mailpoet',
'form/form.jsx', 'form/fields/select.jsx'
'form/fields/select.jsx',
'form/fields/selection.jsx',
'form/fields/text.jsx',
'newsletters/breadcrumb.jsx'
], ],
function( function(
_, _,
React, React,
Router, Router,
MailPoet, MailPoet,
Form, Select
Select,
Selection,
Text,
Breadcrumb
) { ) {
var intervalField = { var intervalField = {
name: 'interval', name: 'intervalType',
values: { values: {
'daily': MailPoet.I18n.t('daily'), 'daily': MailPoet.I18n.t('daily'),
'weekly': MailPoet.I18n.t('weekly'), 'weekly': MailPoet.I18n.t('weekly'),
@@ -96,137 +88,113 @@ define(
}, },
}; };
var NewsletterWelcome = React.createClass({ var NotificationScheduling = React.createClass({
mixins: [ _getCurrentValue: function() {
Router.History return this.props.item[this.props.field.name] || {};
], },
getInitialState: function() { handleValueChange: function(name, value) {
return { var oldValue = this._getCurrentValue(),
intervalType: 'immediate', // 'immediate'|'daily'|'weekly'|'monthly' newValue = {};
timeOfDay: 0, newValue[name] = value;
weekDay: 1,
monthDay: 0, return this.props.onValueChange({
nthWeekDay: 1, target: {
}; name: this.props.field.name,
value: _.extend({}, oldValue, newValue)
}
});
}, },
handleIntervalChange: function(event) { handleIntervalChange: function(event) {
this.setState({ return this.handleValueChange(
intervalType: event.target.value, 'intervalType',
}); event.target.value
);
}, },
handleTimeOfDayChange: function(event) { handleTimeOfDayChange: function(event) {
this.setState({ return this.handleValueChange(
timeOfDay: event.target.value, 'timeOfDay',
}); event.target.value
);
}, },
handleWeekDayChange: function(event) { handleWeekDayChange: function(event) {
this.setState({ return this.handleValueChange(
weekDay: event.target.value, 'weekDay',
}); event.target.value
);
}, },
handleMonthDayChange: function(event) { handleMonthDayChange: function(event) {
this.setState({ return this.handleValueChange(
monthDay: event.target.value, 'monthDay',
}); event.target.value
);
}, },
handleNthWeekDayChange: function(event) { handleNthWeekDayChange: function(event) {
this.setState({ return this.handleValueChange(
nthWeekDay: event.target.value, '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}`);
}, },
render: function() { render: function() {
var timeOfDaySelection, var value = this._getCurrentValue(),
timeOfDaySelection,
weekDaySelection, weekDaySelection,
monthDaySelection, monthDaySelection,
nthWeekDaySelection; nthWeekDaySelection;
if (this.state.intervalType !== 'immediately') {
if (value.intervalType !== 'immediately') {
timeOfDaySelection = ( timeOfDaySelection = (
<Select <Select
field={timeOfDayField} field={timeOfDayField}
item={this.state} item={this._getCurrentValue()}
onValueChange={this.handleTimeOfDayChange} /> onValueChange={this.handleTimeOfDayChange} />
); );
} }
if (this.state.intervalType === 'weekly' if (value.intervalType === 'weekly'
|| this.state.intervalType === 'nthWeekDay') { || value.intervalType === 'nthWeekDay') {
weekDaySelection = ( weekDaySelection = (
<Select <Select
field={weekDayField} field={weekDayField}
item={this.state} item={this._getCurrentValue()}
onValueChange={this.handleWeekDayChange} /> onValueChange={this.handleWeekDayChange} />
); );
} }
if (this.state.intervalType === 'monthly') { if (value.intervalType === 'monthly') {
monthDaySelection = ( monthDaySelection = (
<Select <Select
field={monthDayField} field={monthDayField}
item={this.state} item={this._getCurrentValue()}
onValueChange={this.handleMonthDayChange} /> onValueChange={this.handleMonthDayChange} />
); );
} }
if (this.state.intervalType === 'nthWeekDay') { if (value.intervalType === 'nthWeekDay') {
nthWeekDaySelection = ( nthWeekDaySelection = (
<Select <Select
field={nthWeekDayField} field={nthWeekDayField}
item={this.state} item={this._getCurrentValue()}
onValueChange={this.handleNthWeekDayChange} /> onValueChange={this.handleNthWeekDayChange} />
); );
} }
return ( return (
<div> <div>
<h1>{MailPoet.I18n.t('postNotificationNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" />
<Select <Select
field={intervalField} field={intervalField}
item={this.state} item={this._getCurrentValue()}
onValueChange={this.handleIntervalChange} /> onValueChange={this.handleIntervalChange} />
{nthWeekDaySelection} {nthWeekDaySelection}
{monthDaySelection} {monthDaySelection}
{weekDaySelection} {weekDaySelection}
{timeOfDaySelection} {timeOfDaySelection}
<p className="submit">
<input
className="button button-primary"
type="button"
onClick={ this.handleNext }
value={MailPoet.I18n.t('next')} />
</p>
</div> </div>
); );
}, },
}); });
return NewsletterWelcome; return NotificationScheduling;
} }
); );

View File

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

View File

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