forked from MichaelYick/mailpoet
Upgrade react to v16
[MAILPOET-1634]
This commit is contained in:
parent
061c8c2d28
commit
ed8325c6f9
@ -2,8 +2,14 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class FormFieldCheckbox extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.checkboxRef = React.createRef();
|
||||
this.onValueChange = this.onValueChange.bind(this);
|
||||
}
|
||||
|
||||
onValueChange = (e) => {
|
||||
e.target.value = this.checkbox.checked ? '1' : '0';
|
||||
e.target.value = this.checkboxRef.current.checked ? '1' : '0';
|
||||
return this.props.onValueChange(e);
|
||||
};
|
||||
|
||||
@ -20,7 +26,7 @@ class FormFieldCheckbox extends React.Component {
|
||||
<p key={`checkbox-${value}`}>
|
||||
<label htmlFor={this.props.field.name}>
|
||||
<input
|
||||
ref={(c) => { this.checkbox = c; }}
|
||||
ref={this.checkboxRef}
|
||||
type="checkbox"
|
||||
value="1"
|
||||
checked={isChecked}
|
||||
|
@ -6,6 +6,10 @@ import 'select2';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class Selection extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.selectRef = React.createRef();
|
||||
}
|
||||
componentDidMount() {
|
||||
if (this.isSelect2Component()) {
|
||||
this.setupSelect2();
|
||||
@ -16,7 +20,7 @@ class Selection extends React.Component {
|
||||
if ((this.props.item !== undefined && prevProps.item !== undefined)
|
||||
&& (this.props.item.id !== prevProps.item.id)
|
||||
) {
|
||||
jQuery(`#${this.select.id}`)
|
||||
jQuery(`#${this.selectRef.current.id}`)
|
||||
.val(this.getSelectedValues())
|
||||
.trigger('change');
|
||||
}
|
||||
@ -152,7 +156,7 @@ class Selection extends React.Component {
|
||||
select2Options = Object.assign(select2Options, this.props.field.extendSelect2Options);
|
||||
}
|
||||
|
||||
const select2 = jQuery(`#${this.select.id}`).select2(select2Options);
|
||||
const select2 = jQuery(`#${this.selectRef.current.id}`).select2(select2Options);
|
||||
|
||||
let hasRemoved = false;
|
||||
select2.on('select2:unselecting', () => {
|
||||
@ -175,33 +179,33 @@ class Selection extends React.Component {
|
||||
|
||||
destroySelect2 = () => {
|
||||
if (this.isSelect2Initialized()) {
|
||||
jQuery(`#${this.select.id}`).select2('destroy');
|
||||
jQuery(`#${this.selectRef.current.id}`).select2('destroy');
|
||||
this.cleanupAfterSelect2();
|
||||
}
|
||||
};
|
||||
|
||||
cleanupAfterSelect2 = () => {
|
||||
// remove DOM elements created by Select2 that are not tracked by React
|
||||
jQuery(`#${this.select.id}`)
|
||||
jQuery(`#${this.selectRef.current.id}`)
|
||||
.find('option:not(.default)')
|
||||
.remove();
|
||||
|
||||
// unbind events (https://select2.org/programmatic-control/methods#event-unbinding)
|
||||
jQuery(`#${this.select.id}`)
|
||||
jQuery(`#${this.selectRef.current.id}`)
|
||||
.off('select2:unselecting')
|
||||
.off('select2:opening');
|
||||
};
|
||||
|
||||
allowMultipleValues = () => (this.props.field.multiple === true);
|
||||
|
||||
isSelect2Initialized = () => (jQuery(`#${this.select.id}`).hasClass('select2-hidden-accessible') === true);
|
||||
isSelect2Initialized = () => (jQuery(`#${this.selectRef.current.id}`).hasClass('select2-hidden-accessible') === true);
|
||||
|
||||
isSelect2Component = () => this.allowMultipleValues() || this.props.field.forceSelect2;
|
||||
|
||||
handleChange = (e) => {
|
||||
if (this.props.onValueChange === undefined) return;
|
||||
|
||||
const valueTextPair = jQuery(`#${this.select.id}`).children(':selected').map(function element() {
|
||||
const valueTextPair = jQuery(`#${this.selectRef.current.id}`).children(':selected').map(function element() {
|
||||
return { id: jQuery(this).val(), text: jQuery(this).text() };
|
||||
});
|
||||
const value = (this.props.field.multiple) ? _.pluck(valueTextPair, 'id') : _.pluck(valueTextPair, 'id').toString();
|
||||
@ -258,7 +262,7 @@ class Selection extends React.Component {
|
||||
return (
|
||||
<select
|
||||
id={this.getFieldId()}
|
||||
ref={(c) => { this.select = c; }}
|
||||
ref={this.selectRef}
|
||||
disabled={this.props.field.disabled}
|
||||
data-placeholder={this.props.field.placeholder}
|
||||
multiple={this.props.field.multiple}
|
||||
|
@ -41,7 +41,7 @@ class FormFieldText extends React.Component { // eslint-disable-line react/prefe
|
||||
size={
|
||||
(this.props.field.size !== 'auto' && this.props.field.size > 0)
|
||||
? this.props.field.size
|
||||
: false
|
||||
: null
|
||||
}
|
||||
name={name}
|
||||
id={id}
|
||||
|
@ -4,12 +4,9 @@ import classNames from 'classnames';
|
||||
import FormField from 'form/fields/field.jsx';
|
||||
import jQuery from 'jquery';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
class Form extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
params: {},
|
||||
errors: undefined,
|
||||
@ -33,11 +30,15 @@ class Form extends React.Component {
|
||||
endpoint: undefined,
|
||||
};
|
||||
|
||||
state = {
|
||||
loading: false,
|
||||
errors: [],
|
||||
item: {},
|
||||
};
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.formRef = React.createRef();
|
||||
this.state = {
|
||||
loading: false,
|
||||
errors: [],
|
||||
item: {},
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.params.id !== undefined) {
|
||||
@ -60,7 +61,7 @@ class Form extends React.Component {
|
||||
});
|
||||
});
|
||||
if (props.item === undefined) {
|
||||
this.form.reset();
|
||||
this.formRef.current.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +94,7 @@ class Form extends React.Component {
|
||||
loading: false,
|
||||
item: {},
|
||||
}, function failSetStateCallback() {
|
||||
this.context.router.push('/new');
|
||||
this.props.history.push('/new');
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -139,7 +140,7 @@ class Form extends React.Component {
|
||||
if (this.props.onSuccess !== undefined) {
|
||||
this.props.onSuccess();
|
||||
} else {
|
||||
this.context.router.push('/');
|
||||
this.props.history.push('/');
|
||||
}
|
||||
|
||||
if (this.props.params.id !== undefined) {
|
||||
@ -234,7 +235,7 @@ class Form extends React.Component {
|
||||
{ beforeFormContent }
|
||||
<form
|
||||
id={this.props.id}
|
||||
ref={(c) => { this.form = c; }}
|
||||
ref={this.formRef}
|
||||
className={formClasses}
|
||||
onSubmit={
|
||||
(this.props.onSubmit !== undefined)
|
||||
@ -282,6 +283,9 @@ Form.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
onSuccess: PropTypes.func,
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default Form;
|
||||
export default withRouter(Form);
|
||||
|
@ -1,31 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Router, Route, IndexRoute, useRouterHistory } from 'react-router';
|
||||
import PropTypes from 'prop-types';
|
||||
import { createHashHistory } from 'history';
|
||||
import { Route, HashRouter } from 'react-router-dom';
|
||||
import FormList from './list.jsx';
|
||||
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const container = document.getElementById('forms_container');
|
||||
|
||||
if (container) {
|
||||
ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRoute component={FormList} />
|
||||
<Route path="*" component={FormList} />
|
||||
</Route>
|
||||
</Router>
|
||||
), container);
|
||||
ReactDOM.render(<HashRouter>
|
||||
<Route path="*" component={FormList} />
|
||||
</HashRouter>, container);
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ class FormList extends React.Component {
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
messages={messages}
|
||||
search={false}
|
||||
endpoint="forms"
|
||||
@ -212,7 +212,9 @@ class FormList extends React.Component {
|
||||
|
||||
FormList.propTypes = {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
module.exports = FormList;
|
||||
|
@ -1,39 +1,24 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Router, Route, IndexRedirect, useRouterHistory } from 'react-router';
|
||||
import { createHashHistory } from 'history';
|
||||
import PropTypes from 'prop-types';
|
||||
import { HashRouter, Route, Redirect, Switch } from 'react-router-dom';
|
||||
|
||||
import KnowledgeBase from 'help/knowledge_base.jsx';
|
||||
import SystemInfo from 'help/system_info.jsx';
|
||||
import SystemStatus from 'help/system_status.jsx';
|
||||
import YourPrivacy from 'help/your_privacy.jsx';
|
||||
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const container = document.getElementById('help_container');
|
||||
|
||||
if (container) {
|
||||
ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRedirect to="knowledgeBase" />
|
||||
{/* Pages */}
|
||||
<Route path="knowledgeBase(/)**" params={{ tab: 'knowledgeBase' }} component={KnowledgeBase} />
|
||||
<Route path="systemStatus(/)**" params={{ tab: 'systemStatus' }} component={SystemStatus} />
|
||||
<Route path="systemInfo(/)**" params={{ tab: 'systemInfo' }} component={SystemInfo} />
|
||||
<Route path="yourPrivacy(/)**" params={{ tab: 'yourPrivacy' }} component={YourPrivacy} />
|
||||
</Route>
|
||||
</Router>
|
||||
<HashRouter>
|
||||
<Switch>
|
||||
<Route exact path="/" render={() => <Redirect to="/knowledgeBase" />} />
|
||||
<Route path="/knowledgeBase" component={KnowledgeBase} />
|
||||
<Route path="/systemStatus" component={SystemStatus} />
|
||||
<Route path="/systemInfo" component={SystemInfo} />
|
||||
<Route path="/yourPrivacy" component={YourPrivacy} />
|
||||
</Switch>
|
||||
</HashRouter>
|
||||
), container);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classNames from 'classnames';
|
||||
import MailPoet from 'mailpoet';
|
||||
|
||||
|
@ -3,13 +3,19 @@ import MailPoet from 'mailpoet';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class ListingBulkActions extends React.Component {
|
||||
state = {
|
||||
action: false,
|
||||
extra: false,
|
||||
};
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.myRef = React.createRef();
|
||||
this.state = {
|
||||
action: false,
|
||||
extra: false,
|
||||
};
|
||||
this.handleApplyAction = this.handleApplyAction.bind(this);
|
||||
this.handleChangeAction = this.handleChangeAction.bind(this);
|
||||
}
|
||||
|
||||
getSelectedAction = () => {
|
||||
const selectedAction = this.action.value;
|
||||
getSelectedAction() {
|
||||
const selectedAction = this.myRef.current.value;
|
||||
if (selectedAction.length > 0) {
|
||||
const action = this.props.bulk_actions.filter(act => (act.name === selectedAction));
|
||||
|
||||
@ -18,9 +24,9 @@ class ListingBulkActions extends React.Component {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
handleApplyAction = (e) => {
|
||||
handleApplyAction(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const action = this.getSelectedAction();
|
||||
@ -55,9 +61,9 @@ class ListingBulkActions extends React.Component {
|
||||
action: false,
|
||||
extra: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
handleChangeAction = (e) => {
|
||||
handleChangeAction(e) {
|
||||
this.setState({
|
||||
action: e.target.value,
|
||||
extra: false,
|
||||
@ -71,7 +77,7 @@ class ListingBulkActions extends React.Component {
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.bulk_actions.length === 0) {
|
||||
@ -89,7 +95,7 @@ class ListingBulkActions extends React.Component {
|
||||
|
||||
<select
|
||||
name="bulk_actions"
|
||||
ref={(c) => { this.action = c; }}
|
||||
ref={this.myRef}
|
||||
value={this.state.action}
|
||||
onChange={this.handleChangeAction}
|
||||
>
|
||||
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import ListingColumn from './listing_column.jsx';
|
||||
|
||||
class ListingHeader extends React.Component {
|
||||
handleSelectItems = () => this.props.onSelectItems(this.toggle.checked);
|
||||
handleSelectItems = evt => this.props.onSelectItems(evt.target.checked);
|
||||
|
||||
render() {
|
||||
const columns = this.props.columns.map((column, index) => {
|
||||
@ -37,7 +37,6 @@ class ListingHeader extends React.Component {
|
||||
type="checkbox"
|
||||
name="select_all"
|
||||
id="select_all"
|
||||
ref={(c) => { this.toggle = c; }}
|
||||
checked={this.props.selection}
|
||||
onChange={this.handleSelectItems}
|
||||
/>
|
||||
|
@ -12,6 +12,7 @@ import ListingSearch from 'listing/search.jsx';
|
||||
import ListingGroups from 'listing/groups.jsx';
|
||||
import ListingFilters from 'listing/filters.jsx';
|
||||
import ListingItems from 'listing/listing_items.jsx';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
displayName: 'Listing',
|
||||
@ -44,13 +45,12 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
renderExtraActions: PropTypes.func,
|
||||
onBeforeSelectFilter: PropTypes.func,
|
||||
getListingItemKey: PropTypes.func,
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
},
|
||||
/* eslint-enable react/require-default-props */
|
||||
|
||||
contextTypes: {
|
||||
router: PropTypes.object.isRequired,
|
||||
},
|
||||
|
||||
getDefaultProps: () => ({
|
||||
limit: 10,
|
||||
sort_by: null,
|
||||
@ -145,7 +145,7 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
const url = this.getUrlWithParams(params);
|
||||
|
||||
if (this.props.location.pathname !== url) {
|
||||
this.context.router.push(`${url}`);
|
||||
this.props.history.push(`${url}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -177,7 +177,6 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
},
|
||||
|
||||
getParams: function getParams() {
|
||||
// get all route parameters (without the "splat")
|
||||
const params = _.omit(this.props.params, 'splat');
|
||||
// TODO:
|
||||
// find a way to set the "type" in the routes definition
|
||||
@ -191,6 +190,7 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
getParam: function getParam(param) {
|
||||
const regex = /(.*)\[(.*)\]/;
|
||||
const matches = regex.exec(param);
|
||||
if (!matches) return null;
|
||||
return [matches[1], matches[2]];
|
||||
},
|
||||
|
||||
@ -250,9 +250,13 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
initWithParams: function initWithParams(params) {
|
||||
const state = this.getInitialState();
|
||||
// check for url params
|
||||
if (params.splat) {
|
||||
params.splat.split('/').forEach((param) => {
|
||||
const [key, value] = this.getParam(param);
|
||||
_.mapObject(params, (param) => {
|
||||
if (!param) return;
|
||||
param.split('/').forEach((item) => {
|
||||
if (!item) return;
|
||||
const parsedParam = this.getParam(item);
|
||||
if (!parsedParam) return;
|
||||
const [key, value] = parsedParam;
|
||||
const filters = {};
|
||||
switch (key) {
|
||||
case 'filter':
|
||||
@ -267,7 +271,7 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
state[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// limit per page
|
||||
if (this.props.limit !== undefined) {
|
||||
@ -723,4 +727,4 @@ const Listing = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Listing;
|
||||
module.exports = withRouter(Listing);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import MailPoet from 'mailpoet';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class ListingItem extends React.Component {
|
||||
|
@ -3,15 +3,27 @@ import MailPoet from 'mailpoet';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class ListingSearch extends React.Component {
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.search.value = nextProps.search;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
search: '',
|
||||
};
|
||||
this.handleSearch = this.handleSearch.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({ search: nextProps.search });
|
||||
}
|
||||
|
||||
onChange(e) {
|
||||
this.setState({ search: e.target.value });
|
||||
}
|
||||
|
||||
handleSearch(e) {
|
||||
e.preventDefault();
|
||||
this.props.onSearch(
|
||||
this.search.value.trim()
|
||||
this.state.search.trim()
|
||||
);
|
||||
}
|
||||
|
||||
@ -28,13 +40,13 @@ class ListingSearch extends React.Component {
|
||||
<input
|
||||
type="search"
|
||||
id="search_input"
|
||||
ref={(c) => { this.search = c; }}
|
||||
name="s"
|
||||
defaultValue={this.props.search}
|
||||
onChange={this.onChange}
|
||||
value={this.state.search}
|
||||
/>
|
||||
<input
|
||||
type="submit"
|
||||
defaultValue={MailPoet.I18n.t('searchLabel')}
|
||||
value={MailPoet.I18n.t('searchLabel')}
|
||||
className="button"
|
||||
/>
|
||||
</p>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router';
|
||||
import PropTypes from 'prop-types';
|
||||
import MailPoet from 'mailpoet';
|
||||
|
||||
@ -11,7 +10,6 @@ class Breadcrumb extends React.Component {
|
||||
{
|
||||
name: 'type',
|
||||
label: MailPoet.I18n.t('selectType'),
|
||||
link: '/new',
|
||||
},
|
||||
{
|
||||
name: 'template',
|
||||
@ -39,18 +37,10 @@ class Breadcrumb extends React.Component {
|
||||
{ mailpoet_current: (this.props.step === step.name) }
|
||||
);
|
||||
|
||||
let label = step.label;
|
||||
|
||||
if (step.link !== undefined && this.props.step !== step.name) {
|
||||
label = (
|
||||
<Link to={step.link}>{ step.label }</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span key={`step-${step.label}`}>
|
||||
<span className={stepClasses}>
|
||||
{ label }
|
||||
{ step.label }
|
||||
</span>
|
||||
{ (index < (this.state.steps.length - 1)) ? ' > ' : '' }
|
||||
</span>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import MailPoet from 'mailpoet';
|
||||
import InAppAnnoucement from 'in_app_announcements/in_app_announcement.jsx';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactStringReplace from 'react-string-replace';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import MailPoet from 'mailpoet';
|
||||
import classNames from 'classnames';
|
||||
import moment from 'moment';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Listing from 'listing/listing.jsx';
|
||||
@ -165,7 +165,9 @@ const NewsletterListNotification = createReactClass({ // eslint-disable-line rea
|
||||
|
||||
propTypes: {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
mixins: [MailerMixin, CronMixin],
|
||||
@ -338,7 +340,7 @@ const NewsletterListNotification = createReactClass({ // eslint-disable-line rea
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
endpoint="newsletters"
|
||||
type="notification"
|
||||
base_url="notification"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classNames from 'classnames';
|
||||
import MailPoet from 'mailpoet';
|
||||
import Hooks from 'wp-js-hooks';
|
||||
@ -64,7 +64,9 @@ const NewsletterListNotificationHistory = createReactClass({ // eslint-disable-l
|
||||
|
||||
propTypes: {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin],
|
||||
@ -122,7 +124,7 @@ const NewsletterListNotificationHistory = createReactClass({ // eslint-disable-l
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
endpoint="newsletters"
|
||||
type="notification_history"
|
||||
base_url="notification/history/:parent_id"
|
||||
|
@ -179,7 +179,9 @@ const NewsletterListStandard = createReactClass({ // eslint-disable-line react/p
|
||||
|
||||
propTypes: {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
mixins: [QueueMixin, StatisticsMixin, MailerMixin, CronMixin],
|
||||
@ -233,7 +235,7 @@ const NewsletterListStandard = createReactClass({ // eslint-disable-line react/p
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
endpoint="newsletters"
|
||||
type="standard"
|
||||
base_url="standard"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import classNames from 'classnames';
|
||||
import MailPoet from 'mailpoet';
|
||||
import Hooks from 'wp-js-hooks';
|
||||
|
@ -160,7 +160,9 @@ const NewsletterListWelcome = createReactClass({ // eslint-disable-line react/pr
|
||||
|
||||
propTypes: {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
mixins: [StatisticsMixin, MailerMixin, CronMixin],
|
||||
@ -343,7 +345,7 @@ const NewsletterListWelcome = createReactClass({ // eslint-disable-line react/pr
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
endpoint="newsletters"
|
||||
type="welcome"
|
||||
base_url="welcome"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { IndexRedirect, Route, Router, useRouterHistory } from 'react-router';
|
||||
import { createHashHistory } from 'history';
|
||||
import { HashRouter, Switch, Route, Redirect } from 'react-router-dom';
|
||||
import Hooks from 'wp-js-hooks';
|
||||
import _ from 'underscore';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -19,8 +18,6 @@ import NewsletterListWelcome from 'newsletters/listings/welcome.jsx';
|
||||
import NewsletterListNotification from 'newsletters/listings/notification.jsx';
|
||||
import NewsletterListNotificationHistory from 'newsletters/listings/notification_history.jsx';
|
||||
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
return this.props.children;
|
||||
@ -50,54 +47,53 @@ if (container) {
|
||||
let routes = [
|
||||
/* Listings */
|
||||
{
|
||||
path: 'standard(/)**',
|
||||
params: { tab: 'standard' },
|
||||
path: '/standard(/)**',
|
||||
component: NewsletterListStandard,
|
||||
},
|
||||
{
|
||||
path: 'welcome(/)**',
|
||||
path: '/welcome(/)**',
|
||||
component: NewsletterListWelcome,
|
||||
},
|
||||
{
|
||||
path: 'notification/history/:parent_id(/)**',
|
||||
path: '/notification/history/:parent_id(/)**',
|
||||
component: NewsletterListNotificationHistory,
|
||||
},
|
||||
{
|
||||
path: 'notification(/)**',
|
||||
path: '/notification(/)**',
|
||||
component: NewsletterListNotification,
|
||||
},
|
||||
/* Newsletter: type selection */
|
||||
{
|
||||
path: 'new',
|
||||
component: NewsletterTypes,
|
||||
},
|
||||
/* New newsletter: types */
|
||||
{
|
||||
path: 'new/standard',
|
||||
path: '/new/standard',
|
||||
component: NewsletterTypeStandard,
|
||||
},
|
||||
{
|
||||
path: 'new/notification',
|
||||
path: '/new/notification',
|
||||
component: NewsletterTypeNotification,
|
||||
},
|
||||
{
|
||||
path: 'new/welcome',
|
||||
path: '/new/welcome',
|
||||
component: NewsletterTypeWelcome,
|
||||
},
|
||||
/* Newsletter: type selection */
|
||||
{
|
||||
path: '/new',
|
||||
component: NewsletterTypes,
|
||||
},
|
||||
/* Template selection */
|
||||
{
|
||||
name: 'template',
|
||||
path: 'template/:id',
|
||||
path: '/template/:id',
|
||||
component: NewsletterTemplates,
|
||||
},
|
||||
/* congratulate */
|
||||
{
|
||||
path: 'send/congratulate/:id',
|
||||
path: '/send/congratulate/:id',
|
||||
component: NewsletterCongratulate,
|
||||
},
|
||||
/* Sending options */
|
||||
{
|
||||
path: 'send/:id',
|
||||
path: '/send/:id',
|
||||
component: NewsletterSend,
|
||||
},
|
||||
];
|
||||
@ -105,20 +101,19 @@ if (container) {
|
||||
routes = Hooks.applyFilters('mailpoet_newsletters_before_router', [...routes, ...getAutomaticEmailsRoutes()]);
|
||||
|
||||
window.mailpoet_listing = ReactDOM.render(( // eslint-disable-line react/no-render-return-value
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRedirect to="standard" />
|
||||
<HashRouter>
|
||||
<Switch>
|
||||
<Route exact path="/" render={() => <Redirect to="/standard" />} />
|
||||
{routes.map(route => (
|
||||
<Route
|
||||
key={route.path}
|
||||
path={route.path}
|
||||
component={route.component}
|
||||
name={route.name || null}
|
||||
params={route.params || null}
|
||||
data={route.data || null}
|
||||
/>
|
||||
))}
|
||||
</Route>
|
||||
</Router>
|
||||
</Switch>
|
||||
</HashRouter>
|
||||
), container);
|
||||
}
|
||||
|
@ -12,18 +12,20 @@ import jQuery from 'jquery';
|
||||
import { fromUrl } from 'common/thumbnail.jsx';
|
||||
import Hooks from 'wp-js-hooks';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es6-class
|
||||
displayName: 'NewsletterSend',
|
||||
|
||||
propTypes: {
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
},
|
||||
|
||||
contextTypes: {
|
||||
router: PropTypes.object.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function getInitialState() {
|
||||
@ -35,12 +37,12 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
},
|
||||
|
||||
componentDidMount: function componentDidMount() {
|
||||
this.loadItem(this.props.params.id);
|
||||
this.loadItem(this.props.match.params.id);
|
||||
jQuery('#mailpoet_newsletter').parsley();
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function componentWillReceiveProps(props) {
|
||||
this.loadItem(props.params.id);
|
||||
this.loadItem(props.match.params.id);
|
||||
},
|
||||
|
||||
getFieldsByNewsletter: function getFieldsByNewsletter(newsletter) {
|
||||
@ -86,7 +88,7 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
loading: false,
|
||||
item: {},
|
||||
}, () => {
|
||||
this.context.router.push('/new');
|
||||
this.props.history.push('/new');
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -164,11 +166,11 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
this.saveTemplate(newsletter, () => {
|
||||
if (window.mailpoet_show_congratulate_after_first_newsletter) {
|
||||
MailPoet.Modal.loading(false);
|
||||
this.context.router.push(`/send/congratulate/${this.state.item.id}`);
|
||||
this.props.history.push(`/send/congratulate/${this.state.item.id}`);
|
||||
return;
|
||||
}
|
||||
// redirect to listing based on newsletter type
|
||||
this.context.router.push(Hooks.applyFilters('mailpoet_newsletters_send_server_request_response_redirect', `/${this.state.item.type || ''}`, this.state.item));
|
||||
this.props.history.push(Hooks.applyFilters('mailpoet_newsletters_send_server_request_response_redirect', `/${this.state.item.type || ''}`, this.state.item));
|
||||
const customResponse = Hooks.applyFilters('mailpoet_newsletters_send_server_request_response', this.state.item, response);
|
||||
if (_.isFunction(customResponse)) {
|
||||
customResponse();
|
||||
@ -204,7 +206,7 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
endpoint: 'newsletters',
|
||||
action: 'setStatus',
|
||||
data: {
|
||||
id: this.props.params.id,
|
||||
id: this.props.match.params.id,
|
||||
status: 'active',
|
||||
},
|
||||
}).done((response) => {
|
||||
@ -212,11 +214,11 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
this.saveTemplate(newsletter, () => {
|
||||
if (window.mailpoet_show_congratulate_after_first_newsletter) {
|
||||
MailPoet.Modal.loading(false);
|
||||
this.context.router.push(`/send/congratulate/${this.state.item.id}`);
|
||||
this.props.history.push(`/send/congratulate/${this.state.item.id}`);
|
||||
return;
|
||||
}
|
||||
// redirect to listing based on newsletter type
|
||||
this.context.router.push(`/${this.state.item.type || ''}`);
|
||||
this.props.history.push(`/${this.state.item.type || ''}`);
|
||||
const opts = this.state.item.options;
|
||||
// display success message depending on newsletter type
|
||||
if (response.data.type === 'welcome') {
|
||||
@ -262,7 +264,7 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
newsletter_id: this.state.item.id,
|
||||
},
|
||||
}).done(() => {
|
||||
this.context.router.push(`/${this.state.item.type || ''}`);
|
||||
this.props.history.push(`/${this.state.item.type || ''}`);
|
||||
MailPoet.Notice.success(
|
||||
MailPoet.I18n.t('newsletterSendingHasBeenResumed')
|
||||
);
|
||||
@ -293,7 +295,7 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
MailPoet.I18n.t('newsletterUpdated')
|
||||
);
|
||||
}).done(() => {
|
||||
this.context.router.push(`/${this.state.item.type || ''}`);
|
||||
this.props.history.push(`/${this.state.item.type || ''}`);
|
||||
}).fail((err) => {
|
||||
this.showError(err);
|
||||
});
|
||||
@ -419,7 +421,7 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
{MailPoet.I18n.t('orSimply')}
|
||||
<a
|
||||
href={
|
||||
`?page=mailpoet-newsletter-editor&id=${this.props.params.id}`
|
||||
`?page=mailpoet-newsletter-editor&id=${this.props.match.params.id}`
|
||||
}
|
||||
onClick={this.handleRedirectToDesign}
|
||||
>
|
||||
@ -438,4 +440,4 @@ const NewsletterSend = createReactClass({ // eslint-disable-line react/prefer-es
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NewsletterSend;
|
||||
module.exports = withRouter(NewsletterSend);
|
||||
|
@ -68,12 +68,12 @@ class Congratulate extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.loadNewsletter(this.props.params.id);
|
||||
this.loadNewsletter(this.props.match.params.id);
|
||||
this.tick();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
this.loadNewsletter(props.params.id);
|
||||
this.loadNewsletter(props.match.params.id);
|
||||
}
|
||||
|
||||
tick() {
|
||||
@ -81,7 +81,7 @@ class Congratulate extends React.Component {
|
||||
this.setState({ error: true, loading: false });
|
||||
}
|
||||
if (this.state.loading) {
|
||||
this.loadNewsletter(this.props.params.id);
|
||||
this.loadNewsletter(this.props.match.params.id);
|
||||
}
|
||||
if (moment().subtract(SECONDS_MINIMUIM_LOADING_SCREEN_DISPLAYED, 'seconds').isAfter(this.state.timeStart)) {
|
||||
this.setState({ minimumLoadingTimePassed: true });
|
||||
@ -128,8 +128,10 @@ class Congratulate extends React.Component {
|
||||
}
|
||||
|
||||
Congratulate.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
|
@ -67,8 +67,13 @@ const datepickerTranslations = {
|
||||
};
|
||||
|
||||
class DateText extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.dateInput = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const $element = jQuery(this.dateInput);
|
||||
const $element = jQuery(this.dateInput.current);
|
||||
const that = this;
|
||||
if ($element.datepicker) {
|
||||
// Override jQuery UI datepicker Date parsing and formatting
|
||||
@ -106,7 +111,7 @@ class DateText extends React.Component {
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.datepickerInitialized) {
|
||||
jQuery(this.dateInput).datepicker('destroy');
|
||||
jQuery(this.dateInput.current).datepicker('destroy');
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +153,7 @@ class DateText extends React.Component {
|
||||
readOnly
|
||||
disabled={this.props.disabled}
|
||||
onChange={this.onChange}
|
||||
ref={(c) => { this.dateInput = c; }}
|
||||
ref={this.dateInput}
|
||||
{...this.props.validation}
|
||||
/>
|
||||
);
|
||||
|
@ -34,7 +34,7 @@ class StandardScheduling extends React.Component {
|
||||
|
||||
handleCheckboxChange = (event) => {
|
||||
const changeEvent = event;
|
||||
changeEvent.target.value = this.isScheduledInput.checked ? '1' : '0';
|
||||
changeEvent.target.value = event.target.checked ? '1' : '0';
|
||||
return this.handleValueChange(changeEvent);
|
||||
};
|
||||
|
||||
@ -78,7 +78,6 @@ class StandardScheduling extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
ref={(c) => { this.isScheduledInput = c; }}
|
||||
type="checkbox"
|
||||
value="1"
|
||||
checked={this.isScheduled()}
|
||||
|
@ -141,7 +141,7 @@ class NewsletterTemplates extends React.Component {
|
||||
endpoint: 'newsletters',
|
||||
action: 'get',
|
||||
data: {
|
||||
id: this.props.params.id,
|
||||
id: this.props.match.params.id,
|
||||
},
|
||||
}).done((response) => {
|
||||
emailType = response.data.type;
|
||||
@ -226,7 +226,7 @@ class NewsletterTemplates extends React.Component {
|
||||
<TemplateBox
|
||||
key={template.id}
|
||||
index={index}
|
||||
newsletterId={this.props.params.id}
|
||||
newsletterId={this.props.match.params.id}
|
||||
beforeDelete={() => this.setState({ loading: true })}
|
||||
afterDelete={this.afterTemplateDelete}
|
||||
beforeSelect={() => this.setState({ loading: true })}
|
||||
@ -265,8 +265,10 @@ class NewsletterTemplates extends React.Component {
|
||||
}
|
||||
|
||||
NewsletterTemplates.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
|
||||
class ImportTemplate extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.fileRef = React.createRef();
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
@ -62,11 +63,11 @@ class ImportTemplate extends React.Component {
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (_.size(this.templateFile.files) <= 0) {
|
||||
if (_.size(this.fileRef.current.files) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const file = _.first(this.templateFile.files);
|
||||
const file = _.first(this.fileRef.current.files);
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (evt) => {
|
||||
@ -98,7 +99,7 @@ class ImportTemplate extends React.Component {
|
||||
<input
|
||||
type="file"
|
||||
placeholder={MailPoet.I18n.t('selectJsonFileToUpload')}
|
||||
ref={(c) => { this.templateFile = c; }}
|
||||
ref={this.fileRef}
|
||||
/>
|
||||
<p className="submit">
|
||||
<input
|
||||
|
@ -4,16 +4,18 @@ import MailPoet from 'mailpoet';
|
||||
import Breadcrumb from 'newsletters/breadcrumb.jsx';
|
||||
import Hooks from 'wp-js-hooks';
|
||||
import _ from 'underscore';
|
||||
import 'react-router';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
class NewsletterTypes extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
static propTypes = {
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
setupNewsletter = (type) => {
|
||||
if (type !== undefined) {
|
||||
this.context.router.push(`/new/${type}`);
|
||||
this.props.history.push(`/new/${type}`);
|
||||
MailPoet.trackEvent('Emails > Type selected', {
|
||||
'MailPoet Free version': window.mailpoet_version,
|
||||
'Email type': type,
|
||||
@ -58,7 +60,7 @@ class NewsletterTypes extends React.Component {
|
||||
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
||||
},
|
||||
}).done((response) => {
|
||||
this.context.router.push(`/template/${response.data.id}`);
|
||||
this.props.history.push(`/template/${response.data.id}`);
|
||||
}).fail((response) => {
|
||||
if (response.errors.length > 0) {
|
||||
MailPoet.Notice.error(
|
||||
@ -177,4 +179,4 @@ class NewsletterTypes extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NewsletterTypes;
|
||||
module.exports = withRouter(NewsletterTypes);
|
||||
|
@ -8,7 +8,6 @@ function AutomaticEmailsBreadcrumb(props) {
|
||||
{
|
||||
name: 'type',
|
||||
label: MailPoet.I18n.t('selectType'),
|
||||
link: '/new',
|
||||
},
|
||||
{
|
||||
name: 'events',
|
||||
|
@ -4,6 +4,7 @@ import MailPoet from 'mailpoet';
|
||||
import Breadcrumb from 'newsletters/breadcrumb.jsx';
|
||||
import _ from 'underscore';
|
||||
import Scheduling from 'newsletters/types/notification/scheduling.jsx';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
const field = {
|
||||
name: 'options',
|
||||
@ -12,8 +13,10 @@ const field = {
|
||||
};
|
||||
|
||||
class NewsletterNotification extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
static propTypes = {
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -54,7 +57,7 @@ class NewsletterNotification extends React.Component {
|
||||
};
|
||||
|
||||
showTemplateSelection = (newsletterId) => {
|
||||
this.context.router.push(`/template/${newsletterId}`);
|
||||
this.props.history.push(`/template/${newsletterId}`);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -84,5 +87,5 @@ class NewsletterNotification extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NewsletterNotification;
|
||||
module.exports = withRouter(NewsletterNotification);
|
||||
|
||||
|
@ -2,10 +2,13 @@ import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import MailPoet from 'mailpoet';
|
||||
import Breadcrumb from 'newsletters/breadcrumb.jsx';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
class NewsletterStandard extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
static propTypes = {
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@ -30,7 +33,7 @@ class NewsletterStandard extends React.Component {
|
||||
}
|
||||
|
||||
showTemplateSelection = (newsletterId) => {
|
||||
this.context.router.push(`/template/${newsletterId}`);
|
||||
this.props.history.push(`/template/${newsletterId}`);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -43,5 +46,5 @@ class NewsletterStandard extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NewsletterStandard;
|
||||
module.exports = withRouter(NewsletterStandard);
|
||||
|
||||
|
@ -5,6 +5,7 @@ import Select from 'form/fields/select.jsx';
|
||||
import Text from 'form/fields/text.jsx';
|
||||
import { timeDelayValues } from 'newsletters/scheduling/common.jsx';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
const availableRoles = window.mailpoet_roles || {};
|
||||
const availableSegments = _.filter(
|
||||
@ -49,10 +50,6 @@ const afterTimeTypeField = {
|
||||
};
|
||||
|
||||
class WelcomeScheduling extends React.Component {
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
getCurrentValue = () => this.props.item[this.props.field.name] || {};
|
||||
|
||||
handleValueChange = (name, value) => {
|
||||
@ -97,7 +94,7 @@ class WelcomeScheduling extends React.Component {
|
||||
};
|
||||
|
||||
showTemplateSelection = (newsletterId) => {
|
||||
this.context.router.push(`/template/${newsletterId}`);
|
||||
this.props.history.push(`/template/${newsletterId}`);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -155,6 +152,9 @@ class WelcomeScheduling extends React.Component {
|
||||
}
|
||||
|
||||
WelcomeScheduling.propTypes = {
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
field: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
@ -162,4 +162,4 @@ WelcomeScheduling.propTypes = {
|
||||
onValueChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
module.exports = WelcomeScheduling;
|
||||
module.exports = withRouter(WelcomeScheduling);
|
||||
|
@ -65,7 +65,7 @@ class NewsletterWelcome extends React.Component {
|
||||
}
|
||||
|
||||
showTemplateSelection(newsletterId) {
|
||||
this.props.router.push(`/template/${newsletterId}`);
|
||||
this.props.history.push(`/template/${newsletterId}`);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -96,7 +96,7 @@ class NewsletterWelcome extends React.Component {
|
||||
}
|
||||
|
||||
NewsletterWelcome.propTypes = {
|
||||
router: PropTypes.shape({
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import MailPoet from 'mailpoet';
|
||||
import Form from 'form/form.jsx';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -30,7 +30,7 @@ const messages = {
|
||||
},
|
||||
};
|
||||
|
||||
const SegmentForm = ({ params }) => (
|
||||
const SegmentForm = props => (
|
||||
<div>
|
||||
<h1 className="title">
|
||||
{MailPoet.I18n.t('segment')}
|
||||
@ -40,15 +40,17 @@ const SegmentForm = ({ params }) => (
|
||||
<Form
|
||||
endpoint="segments"
|
||||
fields={fields}
|
||||
params={params}
|
||||
params={props.match.params}
|
||||
messages={messages}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
SegmentForm.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import MailPoet from 'mailpoet';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -261,7 +261,7 @@ class SegmentList extends React.Component {
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
messages={messages}
|
||||
search={false}
|
||||
endpoint="segments"
|
||||
@ -279,7 +279,9 @@ class SegmentList extends React.Component {
|
||||
|
||||
SegmentList.propTypes = {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
module.exports = SegmentList;
|
||||
|
@ -1,35 +1,20 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Router, Route, IndexRoute, useRouterHistory } from 'react-router';
|
||||
import { createHashHistory } from 'history';
|
||||
import PropTypes from 'prop-types';
|
||||
import { HashRouter, Switch, Route } from 'react-router-dom';
|
||||
|
||||
import SegmentList from 'segments/list.jsx';
|
||||
import SegmentForm from 'segments/form.jsx';
|
||||
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const container = document.getElementById('segments_container');
|
||||
|
||||
if (container) {
|
||||
ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRoute component={SegmentList} />
|
||||
<Route path="new" component={SegmentForm} />
|
||||
<Route path="edit/:id" component={SegmentForm} />
|
||||
<HashRouter>
|
||||
<Switch>
|
||||
<Route path="/new" component={SegmentForm} />
|
||||
<Route path="/edit/:id" component={SegmentForm} />
|
||||
<Route path="*" component={SegmentList} />
|
||||
</Route>
|
||||
</Router>
|
||||
</Switch>
|
||||
</HashRouter>
|
||||
), container);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import MailPoet from 'mailpoet';
|
||||
import PropTypes from 'prop-types';
|
||||
import Form from 'form/form.jsx';
|
||||
@ -188,7 +188,7 @@ class SubscriberForm extends React.Component { // eslint-disable-line react/pref
|
||||
<Form
|
||||
endpoint="subscribers"
|
||||
fields={fields}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
messages={messages}
|
||||
beforeFormContent={beforeFormContent}
|
||||
afterFormContent={afterFormContent}
|
||||
@ -199,7 +199,11 @@ class SubscriberForm extends React.Component { // eslint-disable-line react/pref
|
||||
}
|
||||
|
||||
SubscriberForm.propTypes = {
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
module.exports = SubscriberForm;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
import MailPoet from 'mailpoet';
|
||||
@ -359,7 +359,7 @@ class SubscriberList extends React.Component {
|
||||
<Listing
|
||||
limit={window.mailpoet_listing_per_page}
|
||||
location={this.props.location}
|
||||
params={this.props.params}
|
||||
params={this.props.match.params}
|
||||
endpoint="subscribers"
|
||||
onRenderItem={this.renderItem}
|
||||
columns={columns}
|
||||
@ -376,7 +376,9 @@ class SubscriberList extends React.Component {
|
||||
|
||||
SubscriberList.propTypes = {
|
||||
location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
params: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
module.exports = SubscriberList;
|
||||
|
@ -1,34 +1,20 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Router, Route, IndexRoute, useRouterHistory } from 'react-router';
|
||||
import { createHashHistory } from 'history';
|
||||
import PropTypes from 'prop-types';
|
||||
import { HashRouter, Switch, Route } from 'react-router-dom';
|
||||
|
||||
import SubscriberList from 'subscribers/list.jsx';
|
||||
import SubscriberForm from 'subscribers/form.jsx';
|
||||
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const container = document.getElementById('subscribers_container');
|
||||
|
||||
if (container) {
|
||||
ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path="/" component={App}>
|
||||
<IndexRoute component={SubscriberList} />
|
||||
<Route path="new" component={SubscriberForm} />
|
||||
<Route path="edit/:id" component={SubscriberForm} />
|
||||
<HashRouter>
|
||||
<Switch>
|
||||
<Route path="/new" component={SubscriberForm} />
|
||||
<Route path="/edit/:id" component={SubscriberForm} />
|
||||
<Route path="*" component={SubscriberList} />
|
||||
</Route>
|
||||
</Router>
|
||||
</Switch>
|
||||
</HashRouter>
|
||||
), container);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ const WelcomeWizardHelpInfoStep = props => (
|
||||
className="mailpoet_form_iframe"
|
||||
marginWidth="0"
|
||||
marginHeight="0"
|
||||
allowTransparency="true"
|
||||
allowtransparency="true" // eslint-disable-line react/no-unknown-property
|
||||
/>
|
||||
</div>
|
||||
<button className="button button-primary" onClick={props.next}>{MailPoet.I18n.t('next')}</button>
|
||||
|
@ -29,9 +29,9 @@ class WelcomeWizardStepsController extends React.Component {
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const step = parseInt(this.props.params.step, 10);
|
||||
const step = parseInt(this.props.match.params.step, 10);
|
||||
if (step > this.state.stepsCount || step < 1) {
|
||||
this.props.router.push('steps/1');
|
||||
this.props.history.push('/steps/1');
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ class WelcomeWizardStepsController extends React.Component {
|
||||
|
||||
showWooCommerceStepOrFinish() {
|
||||
if (this.state.stepsCount === 4) {
|
||||
this.props.router.push('steps/4');
|
||||
this.props.history.push('/steps/4');
|
||||
} else {
|
||||
this.finishWizard();
|
||||
}
|
||||
@ -80,11 +80,11 @@ class WelcomeWizardStepsController extends React.Component {
|
||||
}
|
||||
|
||||
submitSender() {
|
||||
this.updateSettings({ sender: this.state.sender }).then(() => (this.props.router.push('steps/2')));
|
||||
this.updateSettings({ sender: this.state.sender }).then(() => (this.props.history.push('/steps/2')));
|
||||
}
|
||||
|
||||
render() {
|
||||
const step = parseInt(this.props.params.step, 10);
|
||||
const step = parseInt(this.props.match.params.step, 10);
|
||||
return (
|
||||
<div className="mailpoet_welcome_wizard_steps mailpoet_welcome_wizard_centered_column">
|
||||
<WelcomeWizardHeader
|
||||
@ -104,13 +104,13 @@ class WelcomeWizardStepsController extends React.Component {
|
||||
|
||||
{ step === 1 && !this.state.shouldSetSender ?
|
||||
<WelcomeWizardMigratedUserStep
|
||||
next={() => this.props.router.push('steps/2')}
|
||||
next={() => this.props.history.push('/steps/2')}
|
||||
/> : null
|
||||
}
|
||||
|
||||
{ step === 2 ?
|
||||
<WelcomeWizardHelpInfoStep
|
||||
next={() => this.props.router.push('steps/3')}
|
||||
next={() => this.props.history.push('/steps/3')}
|
||||
/> : null
|
||||
}
|
||||
|
||||
@ -137,10 +137,12 @@ class WelcomeWizardStepsController extends React.Component {
|
||||
}
|
||||
|
||||
WelcomeWizardStepsController.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
step: PropTypes.string.isRequired,
|
||||
match: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
step: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
router: PropTypes.shape({
|
||||
history: PropTypes.shape({
|
||||
push: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
@ -1,23 +1,17 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Router, Route, IndexRedirect, useRouterHistory } from 'react-router';
|
||||
import { createHashHistory } from 'history';
|
||||
import { Route, HashRouter, Redirect } from 'react-router-dom';
|
||||
import WelcomeWizardStepsController from './steps_controller.jsx';
|
||||
|
||||
const container = document.getElementById('welcome_wizard_container');
|
||||
|
||||
if (container) {
|
||||
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||
|
||||
ReactDOM.render((
|
||||
<Router history={history}>
|
||||
<Route path={'/'}>
|
||||
<IndexRedirect to={'steps/1'} />
|
||||
<Route
|
||||
path={'steps/:step'}
|
||||
component={WelcomeWizardStepsController}
|
||||
/>
|
||||
</Route>
|
||||
</Router>
|
||||
<HashRouter>
|
||||
<div>
|
||||
<Route exact path="/" render={() => <Redirect to="/steps/1" />} />
|
||||
<Route path={'/steps/:step'} component={WelcomeWizardStepsController} />
|
||||
</div>
|
||||
</HashRouter>
|
||||
), container);
|
||||
}
|
||||
|
2917
package-lock.json
generated
2917
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -18,7 +18,6 @@
|
||||
"create-react-class": "^15.6.3",
|
||||
"file-saver": "^1.3.8",
|
||||
"handlebars": "4.0.11",
|
||||
"history": "1.13.1",
|
||||
"html2canvas": "^1.0.0-alpha.12",
|
||||
"interact.js": "~1.2.8",
|
||||
"intro.js": "2.9.0",
|
||||
@ -27,11 +26,11 @@
|
||||
"papaparse": "4.1.1",
|
||||
"parsleyjs": "^2.8.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^15.5.0",
|
||||
"react-confirm-alert": "^1.0.8",
|
||||
"react-dom": "^15.5.0",
|
||||
"react-html-parser": "^1.0.3",
|
||||
"react-router": "~3.0.2",
|
||||
"react": "^16.6.3",
|
||||
"react-confirm-alert": "^2.0.6",
|
||||
"react-dom": "^16.6.3",
|
||||
"react-html-parser": "^2.0.2",
|
||||
"react-router-dom": "~4.3.1",
|
||||
"react-string-replace": "^0.3.2",
|
||||
"react-tooltip": "^3.5.1",
|
||||
"select2": "^4.0.5",
|
||||
|
@ -76,10 +76,6 @@ var baseConfig = {
|
||||
include: require.resolve('react-tooltip'),
|
||||
loader: 'expose-loader?' + globalPrefix + '.ReactTooltip',
|
||||
},
|
||||
{
|
||||
include: require.resolve('history'),
|
||||
loader: 'expose-loader?' + globalPrefix + '.History',
|
||||
},
|
||||
{
|
||||
include: require.resolve('react'),
|
||||
loader: 'expose-loader?' + globalPrefix + '.React',
|
||||
@ -89,7 +85,7 @@ var baseConfig = {
|
||||
loader: 'expose-loader?' + globalPrefix + '.ReactDOM',
|
||||
},
|
||||
{
|
||||
include: require.resolve('react-router'),
|
||||
include: require.resolve('react-router-dom'),
|
||||
use: 'expose-loader?' + globalPrefix + '.ReactRouter',
|
||||
},
|
||||
{
|
||||
@ -245,7 +241,7 @@ var adminConfig = {
|
||||
admin_vendor: [
|
||||
'react',
|
||||
'react-dom',
|
||||
require.resolve('react-router'),
|
||||
require.resolve('react-router-dom'),
|
||||
'react-string-replace',
|
||||
'prop-types',
|
||||
'listing/listing.jsx',
|
||||
@ -260,7 +256,6 @@ var adminConfig = {
|
||||
'newsletters/types/automatic_emails/breadcrumb.jsx',
|
||||
'newsletters/types/welcome/scheduling.jsx',
|
||||
'newsletter_editor/initializer.jsx',
|
||||
'history',
|
||||
'classnames'
|
||||
],
|
||||
admin: [
|
||||
|
Loading…
x
Reference in New Issue
Block a user