Updated all React components to their latest version

- updated code due to deprecated warnings (mostly router stuff & input default value)
- set default sender based on settings when creating new newsletter
- fixed erroneous UTC offset when displaying dates (PHP takes care of it)
This commit is contained in:
Jonathan Labreuille
2016-04-28 16:54:43 +02:00
parent 59199140bf
commit 4047b41a7f
26 changed files with 128 additions and 109 deletions

View File

@ -41,9 +41,7 @@ define('date',
},
format: function(date, options) {
this.init(options);
return Moment.utc(date)
.local()
.format(this.convertFormat(this.options.format));
return Moment(date).format(this.convertFormat(this.options.format));
},
short: function(date) {
return this.format(date, {

View File

@ -7,7 +7,10 @@ function(
var FormFieldText = React.createClass({
render: function() {
var value = this.props.item[this.props.field.name];
if(!value) { value = null; }
if(value === undefined) {
value = this.props.field.defaultValue || '';
}
return (
<input
type="text"
@ -21,7 +24,6 @@ function(
id={ 'field_'+this.props.field.name }
value={ value }
placeholder={ this.props.field.placeholder }
defaultValue={ this.props.field.defaultValue }
onChange={ this.props.onValueChange }
{...this.props.field.validation}
/>

View File

@ -13,10 +13,11 @@ define(
Router,
FormField
) {
var Form = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
getDefaultProps: function() {
return {
params: {},
@ -68,7 +69,7 @@ define(
loading: false,
item: {}
}, function() {
this.history.pushState(null, '/new');
this.context.router.push('/new');
}.bind(this));
} else {
this.setState({
@ -118,7 +119,16 @@ define(
if(this.props.onSuccess !== undefined) {
this.props.onSuccess();
} else {
this.history.pushState(null, '/')
var isChrome = (/Chrome/.test(navigator.userAgent))
&& (/Google Inc/.test(navigator.vendor));
if(
(isChrome && history.length > 2)
|| (!isChrome && history.length > 1)
) {
this.context.router.goBack();
} else {
this.context.router.push('/');
}
}
if(this.props.params.id !== undefined) {

View File

@ -1,10 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute } from 'react-router'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import FormList from 'forms/list.jsx'
import createHashHistory from 'history/lib/createHashHistory'
let history = createHashHistory({ queryKey: false })
const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({
render() {
@ -12,7 +12,7 @@ const App = React.createClass({
}
});
let container = document.getElementById('forms_container');
const container = document.getElementById('forms_container');
if(container) {
ReactDOM.render((

View File

@ -295,9 +295,9 @@ define(
});
var Listing = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
loading: false,
@ -359,9 +359,12 @@ define(
}
})
}
// default overrides
if(this.props.limit !== undefined) {
state.limit = Math.abs(~~this.props.limit);
}
this.setState(state, function() {
this.getItems();
}.bind(this));
@ -398,7 +401,7 @@ define(
if(this.props.location) {
if(this.props.location.pathname !== params) {
this.history.pushState(null, `${params}`)
this.context.router.push(`${params}`);
}
}
},
@ -753,8 +756,8 @@ define(
onSort={ this.handleSort }
onSelectItems={ this.handleSelectItems }
selection={ this.state.selection }
sort_by={ this.state.sort_by }
sort_order={ this.state.sort_order }
sort_by={ sort_by }
sort_order={ sort_order }
columns={ this.props.columns }
is_selectable={ bulk_actions.length > 0 } />
</thead>
@ -783,8 +786,8 @@ define(
onSort={ this.handleSort }
onSelectItems={ this.handleSelectItems }
selection={ this.state.selection }
sort_by={ this.state.sort_by }
sort_order={ this.state.sort_order }
sort_by={ sort_by }
sort_order={ sort_order }
columns={ this.props.columns }
is_selectable={ bulk_actions.length > 0 } />
</tfoot>

View File

@ -14,9 +14,6 @@ define(
var Link = Router.Link;
var Breadcrumb = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
step: null,

View File

@ -1,6 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link } from 'react-router'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import NewsletterList from 'newsletters/list.jsx'
import NewsletterTypes from 'newsletters/types.jsx'
import NewsletterTemplates from 'newsletters/templates.jsx'
@ -8,9 +9,8 @@ import NewsletterSend from 'newsletters/send.jsx'
import NewsletterStandard from 'newsletters/types/standard.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 })
const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({
render() {
@ -18,7 +18,7 @@ const App = React.createClass({
}
});
let container = document.getElementById('newsletters_container');
const container = document.getElementById('newsletters_container');
if(container) {
ReactDOM.render((

View File

@ -23,9 +23,9 @@ define(
) {
var NewsletterSend = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
fields: [],
@ -68,7 +68,7 @@ define(
loading: false,
item: {},
}, function() {
this.history.pushState(null, '/new');
this.context.router.push('/new');
}.bind(this));
} else {
this.setState({
@ -106,8 +106,10 @@ define(
}).done((response) => {
this.setState({ loading: false });
if(response.result === true) {
this.history.pushState(null, '/');
MailPoet.Notice.success(response.data.message);
this.context.router.push('/');
MailPoet.Notice.success(
MailPoet.Notice.success(response.data.message);
);
} else {
if(response.errors) {
MailPoet.Notice.error(response.errors);
@ -133,7 +135,7 @@ define(
this.setState({ loading: false });
if(response.result === true) {
this.history.pushState(null, '/');
this.context.router.push('/');
MailPoet.Notice.success(
MailPoet.I18n.t('newsletterUpdated')
);

View File

@ -60,7 +60,6 @@ define(
name: 'sender_name',
type: 'text',
placeholder: MailPoet.I18n.t('senderNamePlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
@ -69,7 +68,6 @@ define(
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'
@ -86,15 +84,13 @@ define(
{
name: 'reply_to_name',
type: 'text',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder')
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
}
]
}
];

View File

@ -52,7 +52,6 @@ define(
name: 'sender_name',
type: 'text',
placeholder: MailPoet.I18n.t('senderNamePlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
@ -61,7 +60,6 @@ define(
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'
@ -78,15 +76,13 @@ define(
{
name: 'reply_to_name',
type: 'text',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder')
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
}
]
}
];

View File

@ -36,7 +36,6 @@ define(
name: 'sender_name',
type: 'text',
placeholder: MailPoet.I18n.t('senderNamePlaceholder'),
defaultValue: (settings.sender !== undefined) ? settings.sender.name : '',
validation: {
'data-parsley-required': true
}
@ -45,7 +44,6 @@ define(
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'
@ -62,15 +60,13 @@ define(
{
name: 'reply_to_name',
type: 'text',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.name : '',
placeholder: MailPoet.I18n.t('replyToNamePlaceholder')
},
{
name: 'reply_to_address',
type: 'text',
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder'),
defaultValue: (settings.reply_to !== undefined) ? settings.reply_to.address : ''
},
placeholder: MailPoet.I18n.t('replyToAddressPlaceholder')
}
]
}
];

View File

@ -80,9 +80,6 @@ define(
});
var NewsletterTemplates = React.createClass({
mixins: [
Router.History
],
getInitialState: function() {
return {
loading: false,

View File

@ -12,12 +12,12 @@ define(
Breadcrumb
) {
var NewsletterTypes = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
setupNewsletter: function(type) {
if(type !== undefined) {
this.history.pushState(null, `/new/${type}`);
this.context.router.push(`/new/${type}`);
}
},
createNewsletter: function(type) {
@ -30,7 +30,7 @@ define(
}
}).done(function(response) {
if(response.result && response.newsletter.id) {
this.history.pushState(null, `/template/${response.newsletter.id}`);
this.context.router.push(`/template/${response.newsletter.id}`);
} else {
if(response.errors.length > 0) {
response.errors.map(function(error) {

View File

@ -24,9 +24,9 @@ define(
};
var NewsletterNotification = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
options: {
@ -64,7 +64,7 @@ define(
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
this.context.router.push(`/template/${newsletterId}`);
},
render: function() {
return (

View File

@ -13,11 +13,11 @@ define(
) {
var NewsletterStandard = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
this.context.router.push(`/template/${newsletterId}`);
},
componentDidMount: function() {
// No options for this type, create a newsletter upon mounting

View File

@ -65,6 +65,9 @@ define(
};
var WelcomeScheduling = React.createClass({
contextTypes: {
router: React.PropTypes.object.isRequired
},
_getCurrentValue: function() {
return this.props.item[this.props.field.name] || {};
},
@ -131,7 +134,7 @@ define(
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
this.context.router.push(`/template/${newsletterId}`);
},
render: function() {
var value = this._getCurrentValue(),

View File

@ -31,9 +31,9 @@ define(
}
var NewsletterWelcome = React.createClass({
mixins: [
Router.History
],
contextTypes: {
router: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
options: {
@ -71,7 +71,7 @@ define(
}.bind(this));
},
showTemplateSelection: function(newsletterId) {
this.history.pushState(null, `/template/${newsletterId}`);
this.context.router.push(`/template/${newsletterId}`);
},
render: function() {
return (

View File

@ -1,13 +1,11 @@
define(
[
'react',
'react-router',
'mailpoet',
'form/form.jsx'
],
function(
React,
Router,
MailPoet,
Form
) {
@ -21,7 +19,8 @@ define(
{
name: 'description',
label: MailPoet.I18n.t('description'),
type: 'textarea'
type: 'textarea',
tip: MailPoet.I18n.t('segmentDescriptionTip')
}
];
@ -35,9 +34,6 @@ define(
};
const SegmentForm = React.createClass({
mixins: [
Router.History
],
render: function() {
return (
<div>

View File

@ -159,9 +159,6 @@ const item_actions = [
}
];
const bulk_actions = [
];
const SegmentList = React.createClass({
renderItem: function(segment, actions) {
var rowClasses = classNames(
@ -211,7 +208,6 @@ const SegmentList = React.createClass({
endpoint="segments"
onRenderItem={ this.renderItem }
columns={ columns }
bulk_actions={ bulk_actions }
item_actions={ item_actions }
/>
</div>

View File

@ -1,11 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link } from 'react-router'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import SegmentList from 'segments/list.jsx'
import SegmentForm from 'segments/form.jsx'
import createHashHistory from 'history/lib/createHashHistory'
let history = createHashHistory({ queryKey: false })
const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({
render() {
@ -13,7 +13,7 @@ const App = React.createClass({
}
});
let container = document.getElementById('segments_container');
const container = document.getElementById('segments_container');
if(container) {
ReactDOM.render((

View File

@ -115,9 +115,6 @@ define(
var Link = Router.Link;
var SubscriberForm = React.createClass({
mixins: [
Router.History
],
render: function() {
return (
<div>

View File

@ -1,11 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link } from 'react-router'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import SubscriberList from 'subscribers/list.jsx'
import SubscriberForm from 'subscribers/form.jsx'
import createHashHistory from 'history/lib/createHashHistory'
const history = createHashHistory({ queryKey: false })
const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({
render() {

View File

@ -100,9 +100,9 @@ class Mailer {
}
function getSender($sender = false) {
if(!$sender) {
$sender = Setting::getValue('sender', null);
if(!$sender['address']) throw new \Exception(__('Sender name and email are not configured.'));
if(empty($sender)) {
$sender = Setting::getValue('sender', array());
if(empty($sender['address'])) throw new \Exception(__('Sender name and email are not configured.'));
}
return array(
'from_name' => $sender['name'],

View File

@ -219,6 +219,37 @@ class Newsletter extends Model {
if($newsletter === false) {
$newsletter = self::create();
// set default sender based on settings
if(empty($data['sender'])) {
$sender = Setting::getValue('sender', array());
$data['sender_name'] = (
!empty($sender['name'])
? $sender['name']
: ''
);
$data['sender_address'] = (
!empty($sender['address'])
? $sender['address']
: ''
);
}
// set default reply_to based on settings
if(empty($data['reply_to'])) {
$reply_to = Setting::getValue('reply_to', array());
$data['reply_to_name'] = (
!empty($reply_to['name'])
? $reply_to['name']
: ''
);
$data['reply_to_address'] = (
!empty($reply_to['address'])
? $reply_to['address']
: ''
);
}
$newsletter->hydrate($data);
} else {
unset($data['id']);

View File

@ -24,12 +24,12 @@
"napa": "^1.2.0",
"papaparse": "4.1.1",
"parsleyjs": "^2.1.2",
"react": "0.14.3",
"react-dom": "0.14.3",
"react-infinity": "1.2.2",
"react-prefixr": "0.1.0",
"react-router": "1.0.2",
"react-waypoint": "1.0.4",
"react": "latest",
"react-dom": "latest",
"react-infinity": "latest",
"react-prefixr": "latest",
"react-router": "latest",
"react-waypoint": "latest",
"select2": "^4.0.0",
"spectrum-colorpicker": "^1.6.2",
"tinymce": "4.1.10",

View File

@ -37,8 +37,7 @@
'restore': __('Restore'),
'deletePermanently': __('Delete Permanently'),
'save': __('Save'),
'numberOfItems': __('%$1d items'),
'segmentDescriptionTip': __('For your own use and never shown to your subscribers.')
}) %>
<% endblock %>