Convert React.createClass to ES6 classes and createReactClass calls

This commit is contained in:
Tautvidas Sipavičius
2018-10-31 21:18:44 +02:00
parent eb1acc8145
commit d4fa041ba8
38 changed files with 587 additions and 411 deletions

View File

@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
const FormFieldCheckbox = React.createClass({ class FormFieldCheckbox extends React.Component {
onValueChange: function onValueChange(e) { onValueChange = (e) => {
e.target.value = this.checkbox.checked ? '1' : '0'; e.target.value = this.checkbox.checked ? '1' : '0';
return this.props.onValueChange(e); return this.props.onValueChange(e);
}, };
render: function render() {
render() {
if (this.props.field.values === undefined) { if (this.props.field.values === undefined) {
return false; return false;
} }
@ -37,7 +38,7 @@ const FormFieldCheckbox = React.createClass({
{ options } { options }
</div> </div>
); );
}, }
}); }
export default FormFieldCheckbox; export default FormFieldCheckbox;

View File

@ -8,8 +8,8 @@ import FormFieldSelection from 'form/fields/selection.jsx';
import FormFieldDate from 'form/fields/date.jsx'; import FormFieldDate from 'form/fields/date.jsx';
import jQuery from 'jquery'; import jQuery from 'jquery';
const FormField = React.createClass({ class FormField extends React.Component {
renderField: function renderField(data, inline = false) { renderField = (data, inline = false) => {
let description = false; let description = false;
if (data.field.description) { if (data.field.description) {
description = ( description = (
@ -76,8 +76,9 @@ const FormField = React.createClass({
{ description } { description }
</div> </div>
); );
}, };
render: function render() {
render() {
let field = false; let field = false;
if (this.props.field.fields !== undefined) { if (this.props.field.fields !== undefined) {
@ -113,7 +114,7 @@ const FormField = React.createClass({
</td> </td>
</tr> </tr>
); );
}, }
}); }
export default FormField; export default FormField;

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
const FormFieldRadio = React.createClass({ class FormFieldRadio extends React.Component {
render: function render() { render() {
if (this.props.field.values === undefined) { if (this.props.field.values === undefined) {
return false; return false;
} }
@ -30,7 +30,7 @@ const FormFieldRadio = React.createClass({
{ options } { options }
</div> </div>
); );
}, }
}); }
export default FormFieldRadio; export default FormFieldRadio;

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import _ from 'underscore'; import _ from 'underscore';
const FormFieldSelect = React.createClass({ class FormFieldSelect extends React.Component {
render() { render() {
if (this.props.field.values === undefined) { if (this.props.field.values === undefined) {
return false; return false;
@ -70,7 +70,7 @@ const FormFieldSelect = React.createClass({
{options} {options}
</select> </select>
); );
}, }
}); }
module.exports = FormFieldSelect; module.exports = FormFieldSelect;

View File

@ -4,22 +4,26 @@ import _ from 'underscore';
import 'react-dom'; import 'react-dom';
import 'select2'; import 'select2';
const Selection = React.createClass({ class Selection extends React.Component {
allowMultipleValues: function allowMultipleValues() { allowMultipleValues = () => {
return (this.props.field.multiple === true); return (this.props.field.multiple === true);
}, };
isSelect2Initialized: function isSelect2Initialized() {
isSelect2Initialized = () => {
return (jQuery(`#${this.select.id}`).hasClass('select2-hidden-accessible') === true); return (jQuery(`#${this.select.id}`).hasClass('select2-hidden-accessible') === true);
}, };
isSelect2Component: function isSelect2Component() {
isSelect2Component = () => {
return this.allowMultipleValues() || this.props.field.forceSelect2; return this.allowMultipleValues() || this.props.field.forceSelect2;
}, };
componentDidMount: function componentDidMount() {
componentDidMount() {
if (this.isSelect2Component()) { if (this.isSelect2Component()) {
this.setupSelect2(); this.setupSelect2();
} }
}, }
componentDidUpdate: function componentDidUpdate(prevProps) {
componentDidUpdate(prevProps) {
if ((this.props.item !== undefined && prevProps.item !== undefined) if ((this.props.item !== undefined && prevProps.item !== undefined)
&& (this.props.item.id !== prevProps.item.id) && (this.props.item.id !== prevProps.item.id)
) { ) {
@ -34,27 +38,32 @@ const Selection = React.createClass({
) { ) {
this.resetSelect2(); this.resetSelect2();
} }
}, }
componentWillUnmount: function componentWillUnmount() {
componentWillUnmount() {
if (this.isSelect2Component()) { if (this.isSelect2Component()) {
this.destroySelect2(); this.destroySelect2();
} }
}, }
getFieldId: function getFieldId(data) {
getFieldId = (data) => {
const props = data || this.props; const props = data || this.props;
return props.field.id || props.field.name; return props.field.id || props.field.name;
}, };
resetSelect2: function resetSelect2() {
resetSelect2 = () => {
this.destroySelect2(); this.destroySelect2();
this.setupSelect2(); this.setupSelect2();
}, };
destroySelect2: function destroySelect2() {
destroySelect2 = () => {
if (this.isSelect2Initialized()) { if (this.isSelect2Initialized()) {
jQuery(`#${this.select.id}`).select2('destroy'); jQuery(`#${this.select.id}`).select2('destroy');
this.cleanupAfterSelect2(); this.cleanupAfterSelect2();
} }
}, };
cleanupAfterSelect2: function cleanupAfterSelect2() {
cleanupAfterSelect2 = () => {
// remove DOM elements created by Select2 that are not tracked by React // remove DOM elements created by Select2 that are not tracked by React
jQuery(`#${this.select.id}`) jQuery(`#${this.select.id}`)
.find('option:not(.default)') .find('option:not(.default)')
@ -64,8 +73,9 @@ const Selection = React.createClass({
jQuery(`#${this.select.id}`) jQuery(`#${this.select.id}`)
.off('select2:unselecting') .off('select2:unselecting')
.off('select2:opening'); .off('select2:opening');
}, };
setupSelect2: function setupSelect2() {
setupSelect2 = () => {
if (this.isSelect2Initialized()) { if (this.isSelect2Initialized()) {
return; return;
} }
@ -138,8 +148,9 @@ const Selection = React.createClass({
}); });
select2.on('change', this.handleChange); select2.on('change', this.handleChange);
}, };
getSelectedValues: function getSelectedValues() {
getSelectedValues = () => {
if (this.props.field.selected !== undefined) { if (this.props.field.selected !== undefined) {
return this.props.field.selected(this.props.item); return this.props.field.selected(this.props.item);
} else if (this.props.item !== undefined && this.props.field.name !== undefined) { } else if (this.props.item !== undefined && this.props.field.name !== undefined) {
@ -152,8 +163,9 @@ const Selection = React.createClass({
} }
} }
return null; return null;
}, };
getItems: function getItems() {
getItems = () => {
let items; let items;
if (typeof (window[`mailpoet_${this.props.field.endpoint}`]) !== 'undefined') { if (typeof (window[`mailpoet_${this.props.field.endpoint}`]) !== 'undefined') {
items = window[`mailpoet_${this.props.field.endpoint}`]; items = window[`mailpoet_${this.props.field.endpoint}`];
@ -168,8 +180,9 @@ const Selection = React.createClass({
} }
return items; return items;
}, };
handleChange: function handleChange(e) {
handleChange = (e) => {
if (this.props.onValueChange === undefined) return; if (this.props.onValueChange === undefined) return;
const valueTextPair = jQuery(`#${this.select.id}`).children(':selected').map(function element() { const valueTextPair = jQuery(`#${this.select.id}`).children(':selected').map(function element() {
@ -185,43 +198,49 @@ const Selection = React.createClass({
id: e.target.id, id: e.target.id,
}, },
}); });
}, };
getLabel: function getLabel(item) {
getLabel = (item) => {
if (this.props.field.getLabel !== undefined) { if (this.props.field.getLabel !== undefined) {
return this.props.field.getLabel(item, this.props.item); return this.props.field.getLabel(item, this.props.item);
} }
return item.name; return item.name;
}, };
getSearchLabel: function getSearchLabel(item) {
getSearchLabel = (item) => {
if (this.props.field.getSearchLabel !== undefined) { if (this.props.field.getSearchLabel !== undefined) {
return this.props.field.getSearchLabel(item, this.props.item); return this.props.field.getSearchLabel(item, this.props.item);
} }
return null; return null;
}, };
getValue: function getValue(item) {
getValue = (item) => {
if (this.props.field.getValue !== undefined) { if (this.props.field.getValue !== undefined) {
return this.props.field.getValue(item, this.props.item); return this.props.field.getValue(item, this.props.item);
} }
return item.id; return item.id;
}, };
// When it's impossible to represent the desired value in DOM, // When it's impossible to represent the desired value in DOM,
// this function may be used to transform the placeholder value into // this function may be used to transform the placeholder value into
// desired value. // desired value.
transformChangedValue: function transformChangedValue(value, textValuePair) { transformChangedValue = (value, textValuePair) => {
if (typeof this.props.field.transformChangedValue === 'function') { if (typeof this.props.field.transformChangedValue === 'function') {
return this.props.field.transformChangedValue.call(this, value, textValuePair); return this.props.field.transformChangedValue.call(this, value, textValuePair);
} }
return value; return value;
}, };
insertEmptyOption: function insertEmptyOption() {
insertEmptyOption = () => {
// https://select2.org/placeholders // https://select2.org/placeholders
// For single selects only, in order for the placeholder value to appear, // For single selects only, in order for the placeholder value to appear,
// we must have a blank <option> as the first option in the <select> control. // we must have a blank <option> as the first option in the <select> control.
if (this.allowMultipleValues()) return undefined; if (this.allowMultipleValues()) return undefined;
if (this.props.field.placeholder) return (<option className="default" />); if (this.props.field.placeholder) return (<option className="default" />);
return undefined; return undefined;
}, };
render: function render() {
render() {
const items = this.getItems(this.props.field); const items = this.getItems(this.props.field);
const selectedValues = this.getSelectedValues(); const selectedValues = this.getSelectedValues();
const options = items.map((item) => { const options = items.map((item) => {
@ -255,7 +274,7 @@ const Selection = React.createClass({
{ options } { options }
</select> </select>
); );
}, }
}); }
export default Selection; export default Selection;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
const FormFieldText = React.createClass({ class FormFieldText extends React.Component {
render() { render() {
const name = this.props.field.name || null; const name = this.props.field.name || null;
const item = this.props.item || {}; const item = this.props.item || {};
@ -51,7 +51,7 @@ const FormFieldText = React.createClass({
{...this.props.field.validation} {...this.props.field.validation}
/> />
); );
}, }
}); }
module.exports = FormFieldText; module.exports = FormFieldText;

View File

@ -4,29 +4,30 @@ import classNames from 'classnames';
import FormField from 'form/fields/field.jsx'; import FormField from 'form/fields/field.jsx';
import jQuery from 'jquery'; import jQuery from 'jquery';
const Form = React.createClass({ class Form extends React.Component {
contextTypes: { static contextTypes = {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, };
getDefaultProps: function getDefaultProps() {
return { static defaultProps = {
params: {}, params: {},
}; };
},
getInitialState: function getInitialState() { state = {
return { loading: false,
loading: false, errors: [],
errors: [], item: {},
item: {}, };
};
}, getValues = () => {
getValues: function getValues() {
return this.props.item ? this.props.item : this.state.item; return this.props.item ? this.props.item : this.state.item;
}, };
getErrors: function getErrors() {
getErrors = () => {
return this.props.errors ? this.props.errors : this.state.errors; return this.props.errors ? this.props.errors : this.state.errors;
}, };
componentDidMount: function componentDidMount() {
componentDidMount() {
if (this.props.params.id !== undefined) { if (this.props.params.id !== undefined) {
this.loadItem(this.props.params.id); this.loadItem(this.props.params.id);
} else { } else {
@ -36,8 +37,9 @@ const Form = React.createClass({
}); });
}); });
} }
}, }
componentWillReceiveProps: function componentWillReceiveProps(props) {
componentWillReceiveProps(props) {
if (props.params.id === undefined) { if (props.params.id === undefined) {
setImmediate(() => { setImmediate(() => {
this.setState({ this.setState({
@ -49,8 +51,9 @@ const Form = React.createClass({
this.form.reset(); this.form.reset();
} }
} }
}, }
loadItem: function loadItem(id) {
loadItem = (id) => {
this.setState({ loading: true }); this.setState({ loading: true });
MailPoet.Ajax.post({ MailPoet.Ajax.post({
@ -76,8 +79,9 @@ const Form = React.createClass({
this.context.router.push('/new'); this.context.router.push('/new');
}); });
}); });
}, };
handleSubmit: function handleSubmit(e) {
handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
// handle validation // handle validation
@ -129,8 +133,9 @@ const Form = React.createClass({
this.setState({ errors: response.errors }); this.setState({ errors: response.errors });
} }
}); });
}, };
handleValueChange: function handleValueChange(e) {
handleValueChange = (e) => {
if (this.props.onChange) { if (this.props.onChange) {
return this.props.onChange(e); return this.props.onChange(e);
} }
@ -143,8 +148,9 @@ const Form = React.createClass({
item, item,
}); });
return true; return true;
}, };
render: function render() {
render() {
let errors; let errors;
if (this.getErrors() !== undefined) { if (this.getErrors() !== undefined) {
errors = this.getErrors().map(error => ( errors = this.getErrors().map(error => (
@ -231,7 +237,7 @@ const Form = React.createClass({
{ afterFormContent } { afterFormContent }
</div> </div>
); );
}, }
}); }
export default Form; export default Form;

View File

@ -672,7 +672,7 @@ WysijaForm = {
if (type === undefined) type = 'block'; if (type === undefined) type = 'block';
// identify element // identify element
id = element.identify(); id = element.identify();
instance = WysijaForm.instances[id] || new WysijaForm[type.capitalize().camelize()](id); instance = WysijaForm.instances[id] || new (WysijaForm[type.capitalize().camelize()])(id);
WysijaForm.instances[id] = instance; WysijaForm.instances[id] = instance;
return instance; return instance;

View File

@ -6,11 +6,11 @@ import FormList from './list.jsx';
const history = useRouterHistory(createHashHistory)({ queryKey: false }); const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ class App extends React.Component {
render() { render() {
return this.props.children; return this.props.children;
}, }
}); }
const container = document.getElementById('forms_container'); const container = document.getElementById('forms_container');

View File

@ -122,8 +122,8 @@ const itemActions = [
}, },
]; ];
const FormList = React.createClass({ class FormList extends React.Component {
createForm() { createForm = () => {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: window.mailpoet_api_version,
endpoint: 'forms', endpoint: 'forms',
@ -138,8 +138,9 @@ const FormList = React.createClass({
); );
} }
}); });
}, };
renderItem(form, actions) {
renderItem = (form, actions) => {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
'column-primary', 'column-primary',
@ -177,7 +178,8 @@ const FormList = React.createClass({
</td> </td>
</div> </div>
); );
}, };
render() { render() {
return ( return (
<div> <div>
@ -204,7 +206,7 @@ const FormList = React.createClass({
/> />
</div> </div>
); );
}, }
}); }
module.exports = FormList; module.exports = FormList;

View File

@ -9,11 +9,11 @@ import KnowledgeBase from 'help/knowledge_base.jsx';
const history = useRouterHistory(createHashHistory)({ queryKey: false }); const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ class App extends React.Component {
render() { render() {
return this.props.children; return this.props.children;
}, }
}); }
const container = document.getElementById('help_container'); const container = document.getElementById('help_container');

View File

@ -1,14 +1,13 @@
import React from 'react'; import React from 'react';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
const ListingBulkActions = React.createClass({ class ListingBulkActions extends React.Component {
getInitialState: function getInitialState() { state = {
return { action: false,
action: false, extra: false,
extra: false, };
};
}, handleChangeAction = (e) => {
handleChangeAction: function handleChangeAction(e) {
this.setState({ this.setState({
action: e.target.value, action: e.target.value,
extra: false, extra: false,
@ -22,8 +21,9 @@ const ListingBulkActions = React.createClass({
}); });
} }
}); });
}, };
handleApplyAction: function handleApplyAction(e) {
handleApplyAction = (e) => {
e.preventDefault(); e.preventDefault();
const action = this.getSelectedAction(); const action = this.getSelectedAction();
@ -58,8 +58,9 @@ const ListingBulkActions = React.createClass({
action: false, action: false,
extra: false, extra: false,
}); });
}, };
getSelectedAction: function getSelectedAction() {
getSelectedAction = () => {
const selectedAction = this.action.value; const selectedAction = this.action.value;
if (selectedAction.length > 0) { if (selectedAction.length > 0) {
const action = this.props.bulk_actions.filter(act => (act.name === selectedAction)); const action = this.props.bulk_actions.filter(act => (act.name === selectedAction));
@ -69,8 +70,9 @@ const ListingBulkActions = React.createClass({
} }
} }
return null; return null;
}, };
render: function render() {
render() {
if (this.props.bulk_actions.length === 0) { if (this.props.bulk_actions.length === 0) {
return null; return null;
} }
@ -108,7 +110,7 @@ const ListingBulkActions = React.createClass({
{ this.state.extra } { this.state.extra }
</div> </div>
); );
}, }
}); }
export default ListingBulkActions; export default ListingBulkActions;

View File

@ -2,8 +2,8 @@ import React from 'react';
import jQuery from 'jquery'; import jQuery from 'jquery';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
const ListingFilters = React.createClass({ class ListingFilters extends React.Component {
handleFilterAction: function handleFilterAction() { handleFilterAction = () => {
const filters = {}; const filters = {};
this.getAvailableFilters().forEach((filter, i) => { this.getAvailableFilters().forEach((filter, i) => {
filters[this[`filter-${i}`].name] = this[`filter-${i}`].value; filters[this[`filter-${i}`].name] = this[`filter-${i}`].value;
@ -12,11 +12,13 @@ const ListingFilters = React.createClass({
this.props.onBeforeSelectFilter(filters); this.props.onBeforeSelectFilter(filters);
} }
return this.props.onSelectFilter(filters); return this.props.onSelectFilter(filters);
}, };
handleEmptyTrash: function handleEmptyTrash() {
handleEmptyTrash = () => {
return this.props.onEmptyTrash(); return this.props.onEmptyTrash();
}, };
getAvailableFilters: function getAvailableFilters() {
getAvailableFilters = () => {
const filters = this.props.filters; const filters = this.props.filters;
return Object.keys(filters).filter(filter => !( return Object.keys(filters).filter(filter => !(
filters[filter].length === 0 filters[filter].length === 0
@ -25,8 +27,9 @@ const ListingFilters = React.createClass({
&& !filters[filter][0].value && !filters[filter][0].value
) )
)); ));
}, };
componentDidUpdate: function componentDidUpdate() {
componentDidUpdate() {
const selectedFilters = this.props.filter; const selectedFilters = this.props.filter;
this.getAvailableFilters().forEach( this.getAvailableFilters().forEach(
(filter, i) => { (filter, i) => {
@ -37,8 +40,9 @@ const ListingFilters = React.createClass({
} }
} }
); );
}, }
render: function render() {
render() {
const filters = this.props.filters; const filters = this.props.filters;
const availableFilters = this.getAvailableFilters() const availableFilters = this.getAvailableFilters()
.map((filter, i) => ( .map((filter, i) => (
@ -89,7 +93,7 @@ const ListingFilters = React.createClass({
{ emptyTrash } { emptyTrash }
</div> </div>
); );
}, }
}); }
export default ListingFilters; export default ListingFilters;

View File

@ -2,13 +2,14 @@ import MailPoet from 'mailpoet';
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
const ListingHeader = React.createClass({ class ListingHeader extends React.Component {
handleSelectItems: function handleSelectItems() { handleSelectItems = () => {
return this.props.onSelectItems( return this.props.onSelectItems(
this.toggle.checked this.toggle.checked
); );
}, };
render: function render() {
render() {
const columns = this.props.columns.map((column, index) => { const columns = this.props.columns.map((column, index) => {
const renderColumn = column; const renderColumn = column;
renderColumn.is_primary = (index === 0); renderColumn.is_primary = (index === 0);
@ -53,16 +54,17 @@ const ListingHeader = React.createClass({
{columns} {columns}
</tr> </tr>
); );
}, }
}); }
const ListingColumn = React.createClass({ class ListingColumn extends React.Component {
handleSort: function handleSort() { handleSort = () => {
const sortBy = this.props.column.name; const sortBy = this.props.column.name;
const sortOrder = (this.props.column.sorted === 'asc') ? 'desc' : 'asc'; const sortOrder = (this.props.column.sorted === 'asc') ? 'desc' : 'asc';
this.props.onSort(sortBy, sortOrder); this.props.onSort(sortBy, sortOrder);
}, };
render: function render() {
render() {
const classes = classNames( const classes = classNames(
'manage-column', 'manage-column',
{ 'column-primary': this.props.column.is_primary }, { 'column-primary': this.props.column.is_primary },
@ -95,7 +97,7 @@ const ListingColumn = React.createClass({
width={this.props.column.width || null} width={this.props.column.width || null}
>{label}</th> >{label}</th>
); );
}, }
}); }
module.exports = ListingHeader; module.exports = ListingHeader;

View File

@ -1,6 +1,7 @@
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
import jQuery from 'jquery'; import jQuery from 'jquery';
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import _ from 'underscore'; import _ from 'underscore';
import { Link } from 'react-router'; import { Link } from 'react-router';
import classNames from 'classnames'; import classNames from 'classnames';
@ -11,33 +12,37 @@ import ListingSearch from 'listing/search.jsx';
import ListingGroups from 'listing/groups.jsx'; import ListingGroups from 'listing/groups.jsx';
import ListingFilters from 'listing/filters.jsx'; import ListingFilters from 'listing/filters.jsx';
const ListingItem = React.createClass({ class ListingItem extends React.Component {
getInitialState: function getInitialState() { state = {
return { expanded: false,
expanded: false, };
};
}, handleSelectItem = (e) => {
handleSelectItem: function handleSelectItem(e) {
this.props.onSelectItem( this.props.onSelectItem(
parseInt(e.target.value, 10), parseInt(e.target.value, 10),
e.target.checked e.target.checked
); );
return !e.target.checked; return !e.target.checked;
}, };
handleRestoreItem: function handleRestoreItem(id) {
handleRestoreItem = (id) => {
this.props.onRestoreItem(id); this.props.onRestoreItem(id);
}, };
handleTrashItem: function handleTrashItem(id) {
handleTrashItem = (id) => {
this.props.onTrashItem(id); this.props.onTrashItem(id);
}, };
handleDeleteItem: function handleDeleteItem(id) {
handleDeleteItem = (id) => {
this.props.onDeleteItem(id); this.props.onDeleteItem(id);
}, };
handleToggleItem: function handleToggleItem() {
handleToggleItem = () => {
this.setState({ expanded: !this.state.expanded }); this.setState({ expanded: !this.state.expanded });
}, };
render: function render() {
render() {
let checkbox = false; let checkbox = false;
if (this.props.is_selectable === true) { if (this.props.is_selectable === true) {
@ -193,12 +198,11 @@ const ListingItem = React.createClass({
{ this.props.onRenderItem(this.props.item, actions) } { this.props.onRenderItem(this.props.item, actions) }
</tr> </tr>
); );
}, }
}); }
class ListingItems extends React.Component {
const ListingItems = React.createClass({ render() {
render: function render() {
if (this.props.items.length === 0) { if (this.props.items.length === 0) {
let message; let message;
if (this.props.loading === true) { if (this.props.loading === true) {
@ -293,13 +297,16 @@ const ListingItems = React.createClass({
})} })}
</tbody> </tbody>
); );
}, }
}); }
const Listing = createReactClass({
displayName: 'Listing',
const Listing = React.createClass({
contextTypes: { contextTypes: {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, },
getInitialState: function getInitialState() { getInitialState: function getInitialState() {
return { return {
loading: false, loading: false,
@ -319,11 +326,13 @@ const Listing = React.createClass({
meta: {}, meta: {},
}; };
}, },
getParam: function getParam(param) { getParam: function getParam(param) {
const regex = /(.*)\[(.*)\]/; const regex = /(.*)\[(.*)\]/;
const matches = regex.exec(param); const matches = regex.exec(param);
return [matches[1], matches[2]]; return [matches[1], matches[2]];
}, },
initWithParams: function initWithParams(params) { initWithParams: function initWithParams(params) {
const state = this.getInitialState(); const state = this.getInitialState();
// check for url params // check for url params
@ -365,6 +374,7 @@ const Listing = React.createClass({
this.getItems(); this.getItems();
}); });
}, },
getParams: function getParams() { getParams: function getParams() {
// get all route parameters (without the "splat") // get all route parameters (without the "splat")
const params = _.omit(this.props.params, 'splat'); const params = _.omit(this.props.params, 'splat');
@ -376,6 +386,7 @@ const Listing = React.createClass({
} }
return params; return params;
}, },
setParams: function setParams() { setParams: function setParams() {
if (this.props.location) { if (this.props.location) {
const params = Object.keys(this.state) const params = Object.keys(this.state)
@ -413,6 +424,7 @@ const Listing = React.createClass({
} }
} }
}, },
getUrlWithParams: function getUrlWithParams(params) { getUrlWithParams: function getUrlWithParams(params) {
let baseUrl = (this.props.base_url !== undefined) let baseUrl = (this.props.base_url !== undefined)
? this.props.base_url ? this.props.base_url
@ -424,6 +436,7 @@ const Listing = React.createClass({
} }
return `/${params}`; return `/${params}`;
}, },
setBaseUrlParams: function setBaseUrlParams(baseUrl) { setBaseUrlParams: function setBaseUrlParams(baseUrl) {
let ret = baseUrl; let ret = baseUrl;
if (ret.indexOf(':') !== -1) { if (ret.indexOf(':') !== -1) {
@ -437,6 +450,7 @@ const Listing = React.createClass({
return ret; return ret;
}, },
componentDidMount: function componentDidMount() { componentDidMount: function componentDidMount() {
this.isComponentMounted = true; this.isComponentMounted = true;
const params = this.props.params || {}; const params = this.props.params || {};
@ -448,13 +462,16 @@ const Listing = React.createClass({
}); });
} }
}, },
componentWillUnmount: function componentWillUnmount() { componentWillUnmount: function componentWillUnmount() {
this.isComponentMounted = false; this.isComponentMounted = false;
}, },
componentWillReceiveProps: function componentWillReceiveProps(nextProps) { componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
const params = nextProps.params || {}; const params = nextProps.params || {};
this.initWithParams(params); this.initWithParams(params);
}, },
getItems: function getItems() { getItems: function getItems() {
if (!this.isComponentMounted) return; if (!this.isComponentMounted) return;
@ -507,6 +524,7 @@ const Listing = React.createClass({
} }
}); });
}, },
handleRestoreItem: function handleRestoreItem(id) { handleRestoreItem: function handleRestoreItem(id) {
this.setState({ this.setState({
loading: true, loading: true,
@ -535,6 +553,7 @@ const Listing = React.createClass({
); );
}); });
}, },
handleTrashItem: function handleTrashItem(id) { handleTrashItem: function handleTrashItem(id) {
this.setState({ this.setState({
loading: true, loading: true,
@ -563,6 +582,7 @@ const Listing = React.createClass({
); );
}); });
}, },
handleDeleteItem: function handleDeleteItem(id) { handleDeleteItem: function handleDeleteItem(id) {
this.setState({ this.setState({
loading: true, loading: true,
@ -591,6 +611,7 @@ const Listing = React.createClass({
); );
}); });
}, },
handleEmptyTrash: function handleEmptyTrash() { handleEmptyTrash: function handleEmptyTrash() {
return this.handleBulkAction('all', { return this.handleBulkAction('all', {
action: 'delete', action: 'delete',
@ -611,6 +632,7 @@ const Listing = React.createClass({
); );
}); });
}, },
handleBulkAction: function handleBulkAction(selectedIds, params) { handleBulkAction: function handleBulkAction(selectedIds, params) {
if ( if (
this.state.selection === false this.state.selection === false
@ -651,6 +673,7 @@ const Listing = React.createClass({
} }
}); });
}, },
handleSearch: function handleSearch(search) { handleSearch: function handleSearch(search) {
this.setState({ this.setState({
search, search,
@ -661,6 +684,7 @@ const Listing = React.createClass({
this.setParams(); this.setParams();
}); });
}, },
handleSort: function handleSort(sortBy, sortOrder = 'asc') { handleSort: function handleSort(sortBy, sortOrder = 'asc') {
this.setState({ this.setState({
sort_by: sortBy, sort_by: sortBy,
@ -669,6 +693,7 @@ const Listing = React.createClass({
this.setParams(); this.setParams();
}); });
}, },
handleSelectItem: function handleSelectItem(id, isChecked) { handleSelectItem: function handleSelectItem(id, isChecked) {
let selectedIds = this.state.selected_ids; let selectedIds = this.state.selected_ids;
let selection = false; let selection = false;
@ -690,6 +715,7 @@ const Listing = React.createClass({
selected_ids: selectedIds, selected_ids: selectedIds,
}); });
}, },
handleSelectItems: function handleSelectItems(isChecked) { handleSelectItems: function handleSelectItems(isChecked) {
if (isChecked === false) { if (isChecked === false) {
this.clearSelection(); this.clearSelection();
@ -702,6 +728,7 @@ const Listing = React.createClass({
}); });
} }
}, },
handleSelectAll: function handleSelectAll() { handleSelectAll: function handleSelectAll() {
if (this.state.selection === 'all') { if (this.state.selection === 'all') {
this.clearSelection(); this.clearSelection();
@ -712,12 +739,14 @@ const Listing = React.createClass({
}); });
} }
}, },
clearSelection: function clearSelection() { clearSelection: function clearSelection() {
this.setState({ this.setState({
selection: false, selection: false,
selected_ids: [], selected_ids: [],
}); });
}, },
handleFilter: function handleFilter(filters) { handleFilter: function handleFilter(filters) {
this.setState({ this.setState({
filter: filters, filter: filters,
@ -726,6 +755,7 @@ const Listing = React.createClass({
this.setParams(); this.setParams();
}); });
}, },
handleGroup: function handleGroup(group) { handleGroup: function handleGroup(group) {
// reset search // reset search
jQuery('#search_input').val(''); jQuery('#search_input').val('');
@ -739,6 +769,7 @@ const Listing = React.createClass({
this.setParams(); this.setParams();
}); });
}, },
handleSetPage: function handleSetPage(page) { handleSetPage: function handleSetPage(page) {
this.setState({ this.setState({
page, page,
@ -748,13 +779,16 @@ const Listing = React.createClass({
this.setParams(); this.setParams();
}); });
}, },
handleRenderItem: function handleRenderItem(item, actions) { handleRenderItem: function handleRenderItem(item, actions) {
const render = this.props.onRenderItem(item, actions, this.state.meta); const render = this.props.onRenderItem(item, actions, this.state.meta);
return render.props.children; return render.props.children;
}, },
handleRefreshItems: function handleRefreshItems() { handleRefreshItems: function handleRefreshItems() {
this.getItems(); this.getItems();
}, },
render: function render() { render: function render() {
const items = this.state.items; const items = this.state.items;
const sortBy = this.state.sort_by; const sortBy = this.state.sort_by;

View File

@ -2,55 +2,64 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
const ListingPages = React.createClass({ class ListingPages extends React.Component {
getInitialState: function getInitialState() { state = {
return { page: null,
page: null, };
};
}, setPage = (page) => {
setPage: function setPage(page) {
this.setState({ this.setState({
page: null, page: null,
}, () => { }, () => {
this.props.onSetPage(this.constrainPage(page)); this.props.onSetPage(this.constrainPage(page));
}); });
}, };
setFirstPage: function setFirstPage() {
setFirstPage = () => {
this.setPage(1); this.setPage(1);
}, };
setLastPage: function setLastPage() {
setLastPage = () => {
this.setPage(this.getLastPage()); this.setPage(this.getLastPage());
}, };
setPreviousPage: function setPreviousPage() {
setPreviousPage = () => {
this.setPage(this.constrainPage( this.setPage(this.constrainPage(
parseInt(this.props.page, 10) - 1) parseInt(this.props.page, 10) - 1)
); );
}, };
setNextPage: function setNextPage() {
setNextPage = () => {
this.setPage(this.constrainPage( this.setPage(this.constrainPage(
parseInt(this.props.page, 10) + 1) parseInt(this.props.page, 10) + 1)
); );
}, };
constrainPage: function constrainPage(page) {
constrainPage = (page) => {
return Math.min(Math.max(1, Math.abs(Number(page))), this.getLastPage()); return Math.min(Math.max(1, Math.abs(Number(page))), this.getLastPage());
}, };
handleSetManualPage: function handleSetManualPage(e) {
handleSetManualPage = (e) => {
if (e.which === 13) { if (e.which === 13) {
this.setPage(this.state.page); this.setPage(this.state.page);
} }
}, };
handleChangeManualPage: function handleChangeManualPage(e) {
handleChangeManualPage = (e) => {
this.setState({ this.setState({
page: e.target.value, page: e.target.value,
}); });
}, };
handleBlurManualPage: function handleBlurManualPage(e) {
handleBlurManualPage = (e) => {
this.setPage(e.target.value); this.setPage(e.target.value);
}, };
getLastPage: function getLastPage() {
getLastPage = () => {
return Math.ceil(this.props.count / this.props.limit); return Math.ceil(this.props.count / this.props.limit);
}, };
render: function render() {
render() {
if (this.props.count === 0) { if (this.props.count === 0) {
return false; return false;
} }
@ -181,7 +190,7 @@ const ListingPages = React.createClass({
{ pagination } { pagination }
</div> </div>
); );
}, }
}); }
module.exports = ListingPages; module.exports = ListingPages;

View File

@ -3,9 +3,10 @@ import classNames from 'classnames';
import { Link } from 'react-router'; import { Link } from 'react-router';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
const Breadcrumb = React.createClass({ class Breadcrumb extends React.Component {
getInitialState: function getInitialState() { constructor(props) {
const steps = this.props.steps || [ super(props);
const steps = props.steps || [
{ {
name: 'type', name: 'type',
label: MailPoet.I18n.t('selectType'), label: MailPoet.I18n.t('selectType'),
@ -24,12 +25,14 @@ const Breadcrumb = React.createClass({
label: MailPoet.I18n.t('send'), label: MailPoet.I18n.t('send'),
}, },
]; ];
return {
this.state = {
step: null, step: null,
steps, steps,
}; };
}, }
render: function render() {
render() {
const steps = this.state.steps.map((step, index) => { const steps = this.state.steps.map((step, index) => {
const stepClasses = classNames( const stepClasses = classNames(
{ mailpoet_current: (this.props.step === step.name) } { mailpoet_current: (this.props.step === step.name) }
@ -58,8 +61,8 @@ const Breadcrumb = React.createClass({
{ steps } { steps }
</p> </p>
); );
}, }
}); }
module.exports = Breadcrumb; module.exports = Breadcrumb;

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import { Link } from 'react-router'; import { Link } from 'react-router';
import Listing from 'listing/listing.jsx'; import Listing from 'listing/listing.jsx';
@ -157,8 +158,10 @@ const newsletterActions = [
}, },
]; ];
const NewsletterListNotification = React.createClass({ const NewsletterListNotification = createReactClass({
displayName: 'NewsletterListNotification',
mixins: [MailerMixin, CronMixin], mixins: [MailerMixin, CronMixin],
updateStatus: function updateStatus(e) { updateStatus: function updateStatus(e) {
// make the event persist so that we can still override the selected value // make the event persist so that we can still override the selected value
// in the ajax callback // in the ajax callback
@ -185,6 +188,7 @@ const NewsletterListNotification = React.createClass({
e.target.value = response.status; e.target.value = response.status;
}); });
}, },
renderStatus: function renderStatus(newsletter) { renderStatus: function renderStatus(newsletter) {
return ( return (
<select <select
@ -197,6 +201,7 @@ const NewsletterListNotification = React.createClass({
</select> </select>
); );
}, },
renderSettings: function renderSettings(newsletter) { renderSettings: function renderSettings(newsletter) {
let sendingFrequency; let sendingFrequency;
@ -265,6 +270,7 @@ const NewsletterListNotification = React.createClass({
</span> </span>
); );
}, },
renderHistoryLink: function renderHistoryLink(newsletter) { renderHistoryLink: function renderHistoryLink(newsletter) {
const childrenCount = Number((newsletter.children_count)); const childrenCount = Number((newsletter.children_count));
if (childrenCount === 0) { if (childrenCount === 0) {
@ -278,6 +284,7 @@ const NewsletterListNotification = React.createClass({
>{ MailPoet.I18n.t('viewHistory') }</Link> >{ MailPoet.I18n.t('viewHistory') }</Link>
); );
}, },
renderItem: function renderItem(newsletter, actions) { renderItem: function renderItem(newsletter, actions) {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
@ -311,6 +318,7 @@ const NewsletterListNotification = React.createClass({
</div> </div>
); );
}, },
render: function render() { render: function render() {
return ( return (
<div> <div>

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import { Link } from 'react-router'; import { Link } from 'react-router';
import classNames from 'classnames'; import classNames from 'classnames';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
@ -57,8 +58,10 @@ let newsletterActions = [
Hooks.addFilter('mailpoet_newsletters_listings_notification_history_actions', StatisticsMixin.addStatsCTAAction); Hooks.addFilter('mailpoet_newsletters_listings_notification_history_actions', StatisticsMixin.addStatsCTAAction);
newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_notification_history_actions', newsletterActions); newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_notification_history_actions', newsletterActions);
const NewsletterListNotificationHistory = React.createClass({ const NewsletterListNotificationHistory = createReactClass({
displayName: 'NewsletterListNotificationHistory',
mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin], mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin],
renderItem: function renderItem(newsletter, actions, meta) { renderItem: function renderItem(newsletter, actions, meta) {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
@ -96,6 +99,7 @@ const NewsletterListNotificationHistory = React.createClass({
</div> </div>
); );
}, },
render: function render() { render: function render() {
return ( return (
<div> <div>

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import { confirmAlert } from 'react-confirm-alert'; import { confirmAlert } from 'react-confirm-alert';
import classNames from 'classnames'; import classNames from 'classnames';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
@ -172,8 +173,10 @@ let newsletterActions = [
Hooks.addFilter('mailpoet_newsletters_listings_standard_actions', StatisticsMixin.addStatsCTAAction); Hooks.addFilter('mailpoet_newsletters_listings_standard_actions', StatisticsMixin.addStatsCTAAction);
newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_standard_actions', newsletterActions); newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_standard_actions', newsletterActions);
const NewsletterListStandard = React.createClass({ const NewsletterListStandard = createReactClass({
displayName: 'NewsletterListStandard',
mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin], mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin],
renderItem: function renderItem(newsletter, actions, meta) { renderItem: function renderItem(newsletter, actions, meta) {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
@ -212,6 +215,7 @@ const NewsletterListStandard = React.createClass({
</div> </div>
); );
}, },
render: function render() { render: function render() {
return ( return (
<div> <div>

View File

@ -4,29 +4,28 @@ import classNames from 'classnames';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
import Hooks from 'wp-js-hooks'; import Hooks from 'wp-js-hooks';
const ListingTabs = React.createClass({ class ListingTabs extends React.Component {
getInitialState() { state = {
return { tab: null,
tab: null, tabs: Hooks.applyFilters('mailpoet_newsletters_listings_tabs', [
tabs: Hooks.applyFilters('mailpoet_newsletters_listings_tabs', [ {
{ name: 'standard',
name: 'standard', label: MailPoet.I18n.t('tabStandardTitle'),
label: MailPoet.I18n.t('tabStandardTitle'), link: '/standard',
link: '/standard', },
}, {
{ name: 'welcome',
name: 'welcome', label: MailPoet.I18n.t('tabWelcomeTitle'),
label: MailPoet.I18n.t('tabWelcomeTitle'), link: '/welcome',
link: '/welcome', },
}, {
{ name: 'notification',
name: 'notification', label: MailPoet.I18n.t('tabNotificationTitle'),
label: MailPoet.I18n.t('tabNotificationTitle'), link: '/notification',
link: '/notification', },
}, ]),
]), };
};
},
render() { render() {
const tabs = this.state.tabs.map((tab) => { const tabs = this.state.tabs.map((tab) => {
const tabClasses = classNames( const tabClasses = classNames(
@ -51,7 +50,7 @@ const ListingTabs = React.createClass({
{ tabs } { tabs }
</h2> </h2>
); );
}, }
}); }
module.exports = ListingTabs; module.exports = ListingTabs;

View File

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import Listing from 'listing/listing.jsx'; import Listing from 'listing/listing.jsx';
import ListingTabs from 'newsletters/listings/tabs.jsx'; import ListingTabs from 'newsletters/listings/tabs.jsx';
import ListingHeading from 'newsletters/listings/heading.jsx'; import ListingHeading from 'newsletters/listings/heading.jsx';
@ -153,8 +155,10 @@ let newsletterActions = [
Hooks.addFilter('mailpoet_newsletters_listings_welcome_notification_actions', StatisticsMixin.addStatsCTAAction); Hooks.addFilter('mailpoet_newsletters_listings_welcome_notification_actions', StatisticsMixin.addStatsCTAAction);
newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_welcome_notification_actions', newsletterActions); newsletterActions = Hooks.applyFilters('mailpoet_newsletters_listings_welcome_notification_actions', newsletterActions);
const NewsletterListWelcome = React.createClass({ const NewsletterListWelcome = createReactClass({
displayName: 'NewsletterListWelcome',
mixins: [StatisticsMixin, MailerMixin, CronMixin], mixins: [StatisticsMixin, MailerMixin, CronMixin],
updateStatus: function updateStatus(e) { updateStatus: function updateStatus(e) {
// make the event persist so that we can still override the selected value // make the event persist so that we can still override the selected value
// in the ajax callback // in the ajax callback
@ -181,6 +185,7 @@ const NewsletterListWelcome = React.createClass({
e.target.value = response.status; e.target.value = response.status;
}); });
}, },
renderStatus: function renderStatus(newsletter) { renderStatus: function renderStatus(newsletter) {
const totalSent = (parseInt(newsletter.total_sent, 10)) ? const totalSent = (parseInt(newsletter.total_sent, 10)) ?
MailPoet.I18n.t('sentToXSubscribers') MailPoet.I18n.t('sentToXSubscribers')
@ -203,6 +208,7 @@ const NewsletterListWelcome = React.createClass({
</div> </div>
); );
}, },
renderSettings: function renderSettings(newsletter) { renderSettings: function renderSettings(newsletter) {
let sendingEvent; let sendingEvent;
let sendingDelay; let sendingDelay;
@ -278,6 +284,7 @@ const NewsletterListWelcome = React.createClass({
</span> </span>
); );
}, },
renderItem: function renderItem(newsletter, actions) { renderItem: function renderItem(newsletter, actions) {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
@ -316,6 +323,7 @@ const NewsletterListWelcome = React.createClass({
</div> </div>
); );
}, },
render: function render() { render: function render() {
return ( return (
<div> <div>

View File

@ -19,11 +19,11 @@ import NewsletterListNotificationHistory from 'newsletters/listings/notification
const history = useRouterHistory(createHashHistory)({ queryKey: false }); const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ class App extends React.Component {
render() { render() {
return this.props.children; return this.props.children;
}, }
}); }
const container = document.getElementById('newsletters_container'); const container = document.getElementById('newsletters_container');

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import createReactClass from 'create-react-class';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
import _ from 'underscore'; import _ from 'underscore';
import Breadcrumb from 'newsletters/breadcrumb.jsx'; import Breadcrumb from 'newsletters/breadcrumb.jsx';
@ -11,10 +12,13 @@ import jQuery from 'jquery';
import { fromUrl } from 'common/thumbnail.jsx'; import { fromUrl } from 'common/thumbnail.jsx';
import Hooks from 'wp-js-hooks'; import Hooks from 'wp-js-hooks';
const NewsletterSend = React.createClass({ const NewsletterSend = createReactClass({
displayName: 'NewsletterSend',
contextTypes: { contextTypes: {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, },
getInitialState: function getInitialState() { getInitialState: function getInitialState() {
return { return {
fields: [], fields: [],
@ -22,14 +26,17 @@ const NewsletterSend = React.createClass({
loading: true, loading: true,
}; };
}, },
getFieldsByNewsletter: function getFieldsByNewsletter(newsletter) { getFieldsByNewsletter: function getFieldsByNewsletter(newsletter) {
const type = this.getSubtype(newsletter); const type = this.getSubtype(newsletter);
return type.getFields(newsletter); return type.getFields(newsletter);
}, },
getSendButtonOptions: function getSendButtonOptions() { getSendButtonOptions: function getSendButtonOptions() {
const type = this.getSubtype(this.state.item); const type = this.getSubtype(this.state.item);
return type.getSendButtonOptions(this.state.item); return type.getSendButtonOptions(this.state.item);
}, },
getSubtype: function getSubtype(newsletter) { getSubtype: function getSubtype(newsletter) {
switch (newsletter.type) { switch (newsletter.type) {
case 'notification': return NotificationNewsletterFields; case 'notification': return NotificationNewsletterFields;
@ -37,16 +44,20 @@ const NewsletterSend = React.createClass({
default: return Hooks.applyFilters('mailpoet_newsletters_send_newsletter_fields', StandardNewsletterFields, newsletter); default: return Hooks.applyFilters('mailpoet_newsletters_send_newsletter_fields', StandardNewsletterFields, newsletter);
} }
}, },
isValid: function isValid() { isValid: function isValid() {
return jQuery('#mailpoet_newsletter').parsley().isValid(); return jQuery('#mailpoet_newsletter').parsley().isValid();
}, },
componentDidMount: function componentDidMount() { componentDidMount: function componentDidMount() {
this.loadItem(this.props.params.id); this.loadItem(this.props.params.id);
jQuery('#mailpoet_newsletter').parsley(); jQuery('#mailpoet_newsletter').parsley();
}, },
componentWillReceiveProps: function componentWillReceiveProps(props) { componentWillReceiveProps: function componentWillReceiveProps(props) {
this.loadItem(props.params.id); this.loadItem(props.params.id);
}, },
loadItem: function loadItem(id) { loadItem: function loadItem(id) {
this.setState({ loading: true }); this.setState({ loading: true });
@ -72,6 +83,7 @@ const NewsletterSend = React.createClass({
}); });
}); });
}, },
saveTemplate: function saveTemplate(response, done) { saveTemplate: function saveTemplate(response, done) {
fromUrl(response.meta.preview_url) fromUrl(response.meta.preview_url)
.then((thumbnail) => { .then((thumbnail) => {
@ -97,6 +109,7 @@ const NewsletterSend = React.createClass({
this.showError({ errors: [err] }); this.showError({ errors: [err] });
}); });
}, },
handleSend: function handleSend(e) { handleSend: function handleSend(e) {
e.preventDefault(); e.preventDefault();
@ -124,6 +137,7 @@ const NewsletterSend = React.createClass({
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
}); });
}, },
sendNewsletter: function sendNewsletter(newsletter) { sendNewsletter: function sendNewsletter(newsletter) {
return MailPoet.Ajax.post( return MailPoet.Ajax.post(
Hooks.applyFilters( Hooks.applyFilters(
@ -171,6 +185,7 @@ const NewsletterSend = React.createClass({
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
}); });
}, },
activateNewsletter: function activateEmail(newsletter) { activateNewsletter: function activateEmail(newsletter) {
return MailPoet.Ajax.post({ return MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: window.mailpoet_api_version,
@ -213,6 +228,7 @@ const NewsletterSend = React.createClass({
MailPoet.Modal.loading(false); MailPoet.Modal.loading(false);
}); });
}, },
handleResume: function handleResume(e) { handleResume: function handleResume(e) {
e.preventDefault(); e.preventDefault();
if (!this.isValid()) { if (!this.isValid()) {
@ -251,6 +267,7 @@ const NewsletterSend = React.createClass({
} }
return false; return false;
}, },
handleSave: function handleSave(e) { handleSave: function handleSave(e) {
e.preventDefault(); e.preventDefault();
@ -264,6 +281,7 @@ const NewsletterSend = React.createClass({
this.showError(err); this.showError(err);
}); });
}, },
handleRedirectToDesign: function handleRedirectToDesign(e) { handleRedirectToDesign: function handleRedirectToDesign(e) {
e.preventDefault(); e.preventDefault();
const redirectTo = e.target.href; const redirectTo = e.target.href;
@ -278,6 +296,7 @@ const NewsletterSend = React.createClass({
this.showError(err); this.showError(err);
}); });
}, },
saveNewsletter: function saveNewsletter() { saveNewsletter: function saveNewsletter() {
const data = this.state.item; const data = this.state.item;
data.queue = undefined; data.queue = undefined;
@ -302,6 +321,7 @@ const NewsletterSend = React.createClass({
this.setState({ loading: false }); this.setState({ loading: false });
}); });
}, },
showError: (response) => { showError: (response) => {
if (response.errors.length > 0) { if (response.errors.length > 0) {
MailPoet.Notice.error( MailPoet.Notice.error(
@ -310,6 +330,7 @@ const NewsletterSend = React.createClass({
); );
} }
}, },
handleFormChange: function handleFormChange(e) { handleFormChange: function handleFormChange(e) {
const item = this.state.item; const item = this.state.item;
const field = e.target.name; const field = e.target.name;
@ -321,6 +342,7 @@ const NewsletterSend = React.createClass({
}); });
return true; return true;
}, },
render: function render() { render: function render() {
const isPaused = this.state.item.status === 'sending' const isPaused = this.state.item.status === 'sending'
&& this.state.item.queue && this.state.item.queue

View File

@ -72,8 +72,8 @@ const datepickerTranslations = {
], ],
}; };
const DateText = React.createClass({ class DateText extends React.Component {
onChange: function onChange(event) { onChange = (event) => {
const changeEvent = event; const changeEvent = event;
// Swap display format to storage format // Swap display format to storage format
const displayDate = changeEvent.target.value; const displayDate = changeEvent.target.value;
@ -81,8 +81,9 @@ const DateText = React.createClass({
changeEvent.target.value = storageDate; changeEvent.target.value = storageDate;
this.props.onChange(changeEvent); this.props.onChange(changeEvent);
}, };
componentDidMount: function componentDidMount() {
componentDidMount() {
const $element = jQuery(this.dateInput); const $element = jQuery(this.dateInput);
const that = this; const that = this;
if ($element.datepicker) { if ($element.datepicker) {
@ -117,28 +118,33 @@ const DateText = React.createClass({
this.datepickerInitialized = true; this.datepickerInitialized = true;
} }
}, }
componentWillUnmount: function componentWillUnmount() {
componentWillUnmount() {
if (this.datepickerInitialized) { if (this.datepickerInitialized) {
jQuery(this.dateInput).datepicker('destroy'); jQuery(this.dateInput).datepicker('destroy');
} }
}, }
getFieldName: function getFieldName() {
getFieldName = () => {
return this.props.name || 'date'; return this.props.name || 'date';
}, };
getDisplayDate: function getDisplayDate(date) {
getDisplayDate = (date) => {
return MailPoet.Date.format(date, { return MailPoet.Date.format(date, {
parseFormat: this.props.storageFormat, parseFormat: this.props.storageFormat,
format: this.props.displayFormat, format: this.props.displayFormat,
}); });
}, };
getStorageDate: function getStorageDate(date) {
getStorageDate = (date) => {
return MailPoet.Date.format(date, { return MailPoet.Date.format(date, {
parseFormat: this.props.displayFormat, parseFormat: this.props.displayFormat,
format: this.props.storageFormat, format: this.props.storageFormat,
}); });
}, };
render: function render() {
render() {
return ( return (
<input <input
type="text" type="text"
@ -152,11 +158,11 @@ const DateText = React.createClass({
{...this.props.validation} {...this.props.validation}
/> />
); );
}, }
}); }
const TimeSelect = React.createClass({ class TimeSelect extends React.Component {
render: function render() { render() {
const options = Object.keys(timeOfDayItems).map( const options = Object.keys(timeOfDayItems).map(
value => ( value => (
<option <option
@ -179,32 +185,33 @@ const TimeSelect = React.createClass({
{options} {options}
</select> </select>
); );
}, }
}); }
const DateTime = React.createClass({ class DateTime extends React.Component {
DATE_TIME_SEPARATOR: ' ', DATE_TIME_SEPARATOR = ' ';
getInitialState: function getInitialState() {
return this.buildStateFromProps(this.props); componentWillReceiveProps(nextProps) {
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
this.setState(this.buildStateFromProps(nextProps)); this.setState(this.buildStateFromProps(nextProps));
}, }
buildStateFromProps: function buildStateFromProps(props) {
buildStateFromProps = (props) => {
const value = props.value || defaultDateTime; const value = props.value || defaultDateTime;
const [date, time] = value.split(this.DATE_TIME_SEPARATOR); const [date, time] = value.split(this.DATE_TIME_SEPARATOR);
return { return {
date, date,
time, time,
}; };
}, };
handleChange: function handleChange(event) {
handleChange = (event) => {
const newState = {}; const newState = {};
newState[event.target.name] = event.target.value; newState[event.target.name] = event.target.value;
this.setState(newState, this.propagateChange); this.setState(newState, this.propagateChange);
}, };
propagateChange: function propagateChange() {
propagateChange = () => {
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange({ this.props.onChange({
target: { target: {
@ -213,11 +220,15 @@ const DateTime = React.createClass({
}, },
}); });
} }
}, };
getDateTime: function getDateTime() {
getDateTime = () => {
return [this.state.date, this.state.time].join(this.DATE_TIME_SEPARATOR); return [this.state.date, this.state.time].join(this.DATE_TIME_SEPARATOR);
}, };
render: function render() {
state = this.buildStateFromProps(this.props);
render() {
return ( return (
<span> <span>
<DateText <DateText
@ -238,11 +249,11 @@ const DateTime = React.createClass({
/> />
</span> </span>
); );
}, }
}); }
const StandardScheduling = React.createClass({ class StandardScheduling extends React.Component {
getCurrentValue: function getCurrentValue() { getCurrentValue = () => {
return _.defaults( return _.defaults(
this.props.item[this.props.field.name] || {}, this.props.item[this.props.field.name] || {},
{ {
@ -250,8 +261,9 @@ const StandardScheduling = React.createClass({
scheduledAt: defaultDateTime, scheduledAt: defaultDateTime,
} }
); );
}, };
handleValueChange: function handleValueChange(event) {
handleValueChange = (event) => {
const oldValue = this.getCurrentValue(); const oldValue = this.getCurrentValue();
const newValue = {}; const newValue = {};
newValue[event.target.name] = event.target.value; newValue[event.target.name] = event.target.value;
@ -262,23 +274,27 @@ const StandardScheduling = React.createClass({
value: _.extend({}, oldValue, newValue), value: _.extend({}, oldValue, newValue),
}, },
}); });
}, };
handleCheckboxChange: function handleCheckboxChange(event) {
handleCheckboxChange = (event) => {
const changeEvent = event; const changeEvent = event;
changeEvent.target.value = this.isScheduledInput.checked ? '1' : '0'; changeEvent.target.value = this.isScheduledInput.checked ? '1' : '0';
return this.handleValueChange(changeEvent); return this.handleValueChange(changeEvent);
}, };
isScheduled: function isScheduled() {
isScheduled = () => {
return this.getCurrentValue().isScheduled === '1'; return this.getCurrentValue().isScheduled === '1';
}, };
getDateValidation: function getDateValidation() {
getDateValidation = () => {
return { return {
'data-parsley-required': true, 'data-parsley-required': true,
'data-parsley-required-message': MailPoet.I18n.t('noScheduledDateError'), 'data-parsley-required-message': MailPoet.I18n.t('noScheduledDateError'),
'data-parsley-errors-container': '#mailpoet_scheduling', 'data-parsley-errors-container': '#mailpoet_scheduling',
}; };
}, };
render: function render() {
render() {
let schedulingOptions; let schedulingOptions;
if (this.isScheduled()) { if (this.isScheduled()) {
@ -313,8 +329,8 @@ const StandardScheduling = React.createClass({
{schedulingOptions} {schedulingOptions}
</div> </div>
); );
}, }
}); }
let fields = [ let fields = [
{ {

View File

@ -5,11 +5,12 @@ import Hooks from 'wp-js-hooks';
import _ from 'underscore'; import _ from 'underscore';
import 'react-router'; import 'react-router';
const NewsletterTypes = React.createClass({ class NewsletterTypes extends React.Component {
contextTypes: { static contextTypes = {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, };
setupNewsletter: function setupNewsletter(type) {
setupNewsletter = (type) => {
if (type !== undefined) { if (type !== undefined) {
this.context.router.push(`/new/${type}`); this.context.router.push(`/new/${type}`);
MailPoet.trackEvent('Emails > Type selected', { MailPoet.trackEvent('Emails > Type selected', {
@ -17,8 +18,9 @@ const NewsletterTypes = React.createClass({
'Email type': type, 'Email type': type,
}); });
} }
}, };
createNewsletter: function createNewsletter(type) {
createNewsletter = (type) => {
MailPoet.trackEvent('Emails > Type selected', { MailPoet.trackEvent('Emails > Type selected', {
'MailPoet Free version': window.mailpoet_version, 'MailPoet Free version': window.mailpoet_version,
'Email type': type, 'Email type': type,
@ -41,8 +43,9 @@ const NewsletterTypes = React.createClass({
); );
} }
}); });
}, };
getAutomaticEmails: function getAutomaticEmails() {
getAutomaticEmails = () => {
if (!window.mailpoet_automatic_emails) return []; if (!window.mailpoet_automatic_emails) return [];
return _.map(window.mailpoet_automatic_emails, (automaticEmail) => { return _.map(window.mailpoet_automatic_emails, (automaticEmail) => {
@ -63,8 +66,9 @@ const NewsletterTypes = React.createClass({
return email; return email;
}); });
}, };
render: function render() {
render() {
const createStandardNewsletter = _.partial(this.createNewsletter, 'standard'); const createStandardNewsletter = _.partial(this.createNewsletter, 'standard');
const createNotificationNewsletter = _.partial(this.setupNewsletter, 'notification'); const createNotificationNewsletter = _.partial(this.setupNewsletter, 'notification');
const createWelcomeNewsletter = _.partial(this.setupNewsletter, 'welcome'); const createWelcomeNewsletter = _.partial(this.setupNewsletter, 'welcome');
@ -169,7 +173,7 @@ const NewsletterTypes = React.createClass({
</ul> </ul>
</div> </div>
); );
}, }
}); }
module.exports = NewsletterTypes; module.exports = NewsletterTypes;

View File

@ -10,27 +10,28 @@ const field = {
component: Scheduling, component: Scheduling,
}; };
const NewsletterNotification = React.createClass({ class NewsletterNotification extends React.Component {
contextTypes: { static contextTypes = {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, };
getInitialState: function getInitialState() {
return { state = {
options: { options: {
intervalType: 'daily', intervalType: 'daily',
timeOfDay: 0, timeOfDay: 0,
weekDay: 1, weekDay: 1,
monthDay: 0, monthDay: 0,
nthWeekDay: 1, nthWeekDay: 1,
}, },
}; };
},
handleValueChange: function handleValueChange(event) { handleValueChange = (event) => {
const state = this.state; const state = this.state;
state[event.target.name] = event.target.value; state[event.target.name] = event.target.value;
this.setState(state); this.setState(state);
}, };
handleNext: function handleNext() {
handleNext = () => {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: window.mailpoet_api_version,
endpoint: 'newsletters', endpoint: 'newsletters',
@ -49,11 +50,13 @@ const NewsletterNotification = React.createClass({
); );
} }
}); });
}, };
showTemplateSelection: function showTemplateSelection(newsletterId) {
showTemplateSelection = (newsletterId) => {
this.context.router.push(`/template/${newsletterId}`); this.context.router.push(`/template/${newsletterId}`);
}, };
render: function render() {
render() {
return ( return (
<div> <div>
<h1>{MailPoet.I18n.t('postNotificationNewsletterTypeTitle')}</h1> <h1>{MailPoet.I18n.t('postNotificationNewsletterTypeTitle')}</h1>
@ -77,8 +80,8 @@ const NewsletterNotification = React.createClass({
</p> </p>
</div> </div>
); );
}, }
}); }
module.exports = NewsletterNotification; module.exports = NewsletterNotification;

View File

@ -34,11 +34,12 @@ const nthWeekDayField = {
values: nthWeekDayValues, values: nthWeekDayValues,
}; };
const NotificationScheduling = React.createClass({ class NotificationScheduling extends React.Component {
getCurrentValue: function getCurrentValue() { getCurrentValue = () => {
return (this.props.item[this.props.field.name] || {}); return (this.props.item[this.props.field.name] || {});
}, };
handleValueChange: function handleValueChange(name, value) {
handleValueChange = (name, value) => {
const oldValue = this.getCurrentValue(); const oldValue = this.getCurrentValue();
const newValue = {}; const newValue = {};
@ -50,38 +51,44 @@ const NotificationScheduling = React.createClass({
value: _.extend({}, oldValue, newValue), value: _.extend({}, oldValue, newValue),
}, },
}); });
}, };
handleIntervalChange: function handleIntervalChange(event) {
handleIntervalChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'intervalType', 'intervalType',
event.target.value event.target.value
); );
}, };
handleTimeOfDayChange: function handleTimeOfDayChange(event) {
handleTimeOfDayChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'timeOfDay', 'timeOfDay',
event.target.value event.target.value
); );
}, };
handleWeekDayChange: function handleWeekDayChange(event) {
handleWeekDayChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'weekDay', 'weekDay',
event.target.value event.target.value
); );
}, };
handleMonthDayChange: function handleMonthDayChange(event) {
handleMonthDayChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'monthDay', 'monthDay',
event.target.value event.target.value
); );
}, };
handleNthWeekDayChange: function handleNthWeekDayChange(event) {
handleNthWeekDayChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'nthWeekDay', 'nthWeekDay',
event.target.value event.target.value
); );
}, };
render: function render() {
render() {
const value = this.getCurrentValue(); const value = this.getCurrentValue();
let timeOfDaySelection; let timeOfDaySelection;
let weekDaySelection; let weekDaySelection;
@ -143,7 +150,7 @@ const NotificationScheduling = React.createClass({
{timeOfDaySelection} {timeOfDaySelection}
</div> </div>
); );
}, }
}); }
module.exports = NotificationScheduling; module.exports = NotificationScheduling;

View File

@ -2,14 +2,16 @@ import React from 'react';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
import Breadcrumb from 'newsletters/breadcrumb.jsx'; import Breadcrumb from 'newsletters/breadcrumb.jsx';
const NewsletterStandard = React.createClass({ class NewsletterStandard extends React.Component {
contextTypes: { static contextTypes = {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, };
showTemplateSelection: function showTemplateSelection(newsletterId) {
showTemplateSelection = (newsletterId) => {
this.context.router.push(`/template/${newsletterId}`); this.context.router.push(`/template/${newsletterId}`);
}, };
componentDidMount: function componentDidMount() {
componentDidMount() {
// No options for this type, create a newsletter upon mounting // No options for this type, create a newsletter upon mounting
MailPoet.Ajax.post({ MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: window.mailpoet_api_version,
@ -28,16 +30,17 @@ const NewsletterStandard = React.createClass({
); );
} }
}); });
}, }
render: function render() {
render() {
return ( return (
<div> <div>
<h1>{MailPoet.I18n.t('regularNewsletterTypeTitle')}</h1> <h1>{MailPoet.I18n.t('regularNewsletterTypeTitle')}</h1>
<Breadcrumb step="type" /> <Breadcrumb step="type" />
</div> </div>
); );
}, }
}); }
module.exports = NewsletterStandard; module.exports = NewsletterStandard;

View File

@ -47,14 +47,16 @@ const afterTimeTypeField = {
values: timeDelayValues, values: timeDelayValues,
}; };
const WelcomeScheduling = React.createClass({ class WelcomeScheduling extends React.Component {
contextTypes: { static contextTypes = {
router: React.PropTypes.object.isRequired, router: React.PropTypes.object.isRequired,
}, };
getCurrentValue: function getCurrentValue() {
getCurrentValue = () => {
return (this.props.item[this.props.field.name] || {}); return (this.props.item[this.props.field.name] || {});
}, };
handleValueChange: function handleValueChange(name, value) {
handleValueChange = (name, value) => {
const oldValue = this.getCurrentValue(); const oldValue = this.getCurrentValue();
const newValue = {}; const newValue = {};
@ -66,38 +68,44 @@ const WelcomeScheduling = React.createClass({
value: _.extend({}, oldValue, newValue), value: _.extend({}, oldValue, newValue),
}, },
}); });
}, };
handleEventChange: function handleEventChange(event) {
handleEventChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'event', 'event',
event.target.value event.target.value
); );
}, };
handleSegmentChange: function handleSegmentChange(event) {
handleSegmentChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'segment', 'segment',
event.target.value event.target.value
); );
}, };
handleRoleChange: function handleRoleChange(event) {
handleRoleChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'role', 'role',
event.target.value event.target.value
); );
}, };
handleAfterTimeNumberChange: function handleAfterTimeNumberChange(event) {
handleAfterTimeNumberChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'afterTimeNumber', 'afterTimeNumber',
event.target.value event.target.value
); );
}, };
handleAfterTimeTypeChange: function handleAfterTimeTypeChange(event) {
handleAfterTimeTypeChange = (event) => {
return this.handleValueChange( return this.handleValueChange(
'afterTimeType', 'afterTimeType',
event.target.value event.target.value
); );
}, };
handleNext: function handleNext() {
handleNext = () => {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: window.mailpoet_api_version,
endpoint: 'newsletters', endpoint: 'newsletters',
@ -116,11 +124,13 @@ const WelcomeScheduling = React.createClass({
); );
} }
}); });
}, };
showTemplateSelection: function showTemplateSelection(newsletterId) {
showTemplateSelection = (newsletterId) => {
this.context.router.push(`/template/${newsletterId}`); this.context.router.push(`/template/${newsletterId}`);
}, };
render: function render() {
render() {
const value = this.getCurrentValue(); const value = this.getCurrentValue();
let roleSegmentSelection; let roleSegmentSelection;
let timeNumber; let timeNumber;
@ -171,7 +181,7 @@ const WelcomeScheduling = React.createClass({
/> />
</div> </div>
); );
}, }
}); }
module.exports = WelcomeScheduling; module.exports = WelcomeScheduling;

View File

@ -191,8 +191,8 @@ const itemActions = [
}, },
]; ];
const SegmentList = React.createClass({ class SegmentList extends React.Component {
renderItem: function renderItem(segment, actions) { renderItem = (segment, actions) => {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
'column-primary', 'column-primary',
@ -248,8 +248,9 @@ const SegmentList = React.createClass({
</td> </td>
</div> </div>
); );
}, };
render: function render() {
render() {
return ( return (
<div> <div>
<h1 className="title"> <h1 className="title">
@ -272,7 +273,7 @@ const SegmentList = React.createClass({
/> />
</div> </div>
); );
}, }
}); }
module.exports = SegmentList; module.exports = SegmentList;

View File

@ -8,11 +8,11 @@ import SegmentForm from 'segments/form.jsx';
const history = useRouterHistory(createHashHistory)({ queryKey: false }); const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ class App extends React.Component {
render() { render() {
return this.props.children; return this.props.children;
}, }
}); }
const container = document.getElementById('segments_container'); const container = document.getElementById('segments_container');

View File

@ -175,8 +175,8 @@ function afterFormContent() {
); );
} }
const SubscriberForm = React.createClass({ class SubscriberForm extends React.Component {
render: function render() { render() {
return ( return (
<div> <div>
<h1 className="title"> <h1 className="title">
@ -194,7 +194,7 @@ const SubscriberForm = React.createClass({
/> />
</div> </div>
); );
}, }
}); }
module.exports = SubscriberForm; module.exports = SubscriberForm;

View File

@ -242,8 +242,8 @@ const itemActions = [
}, },
]; ];
const SubscriberList = React.createClass({ class SubscriberList extends React.Component {
getSegmentFromId: function getSegmentFromId(segmentId) { getSegmentFromId = (segmentId) => {
let result = false; let result = false;
window.mailpoet_segments.forEach((segment) => { window.mailpoet_segments.forEach((segment) => {
if (segment.id === segmentId) { if (segment.id === segmentId) {
@ -251,8 +251,9 @@ const SubscriberList = React.createClass({
} }
}); });
return result; return result;
}, };
renderItem: function renderItem(subscriber, actions) {
renderItem = (subscriber, actions) => {
const rowClasses = classNames( const rowClasses = classNames(
'manage-column', 'manage-column',
'column-primary', 'column-primary',
@ -333,8 +334,9 @@ const SubscriberList = React.createClass({
</td> </td>
</div> </div>
); );
}, };
render: function render() {
render() {
return ( return (
<div> <div>
<h1 className="title"> <h1 className="title">
@ -368,7 +370,7 @@ const SubscriberList = React.createClass({
/> />
</div> </div>
); );
}, }
}); }
module.exports = SubscriberList; module.exports = SubscriberList;

View File

@ -7,11 +7,11 @@ import SubscriberForm from 'subscribers/form.jsx';
const history = useRouterHistory(createHashHistory)({ queryKey: false }); const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ class App extends React.Component {
render() { render() {
return this.props.children; return this.props.children;
}, }
}); }
const container = document.getElementById('subscribers_container'); const container = document.getElementById('subscribers_container');

6
package-lock.json generated
View File

@ -2170,9 +2170,9 @@
} }
}, },
"create-react-class": { "create-react-class": {
"version": "15.6.2", "version": "15.6.3",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
"integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=", "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
"requires": { "requires": {
"fbjs": "^0.8.9", "fbjs": "^0.8.9",
"loose-envify": "^1.3.1", "loose-envify": "^1.3.1",

View File

@ -15,6 +15,7 @@
"blob-tmp": "^1.0.0", "blob-tmp": "^1.0.0",
"classnames": "^2.1.3", "classnames": "^2.1.3",
"codemirror": "^5.37.0", "codemirror": "^5.37.0",
"create-react-class": "^15.6.3",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",
"handlebars": "4.0.11", "handlebars": "4.0.11",
"history": "1.13.1", "history": "1.13.1",

View File

@ -246,6 +246,7 @@ var adminConfig = {
'react-dom', 'react-dom',
require.resolve('react-router'), require.resolve('react-router'),
'react-string-replace', 'react-string-replace',
'prop-types',
'listing/listing.jsx', 'listing/listing.jsx',
'form/form.jsx', 'form/form.jsx',
'intro.js', 'intro.js',