Subscriber Edit page

This commit is contained in:
Jonathan Labreuille
2015-09-09 15:58:57 +02:00
parent bec7f3d5bf
commit 97db902529
9 changed files with 148 additions and 57 deletions

View File

@@ -1,4 +1,5 @@
.mailpoet_listing_loading tbody tr .mailpoet_listing_loading tbody tr,
.mailpoet_form_loading
opacity: 0.2; opacity: 0.2;
.widefat tfoot td.mailpoet_check_column, .widefat tfoot td.mailpoet_check_column,
@@ -20,3 +21,4 @@
.mailpoet_select_all td .mailpoet_select_all td
text-align: center text-align: center

View File

@@ -76,8 +76,8 @@ define(
className="colspanchange"> className="colspanchange">
{ {
(this.props.loading === true) (this.props.loading === true)
? MailPoetI18n.loading ? MailPoetI18n.loadingItems
: MailPoetI18n.noRecordFound : MailPoetI18n.noItemsFound
} }
</td> </td>
</tr> </tr>

View File

@@ -3,13 +3,15 @@ define(
'react', 'react',
'react-router', 'react-router',
'jquery', 'jquery',
'mailpoet' 'mailpoet',
'classnames',
], ],
function( function(
React, React,
Router, Router,
jQuery, jQuery,
MailPoet MailPoet,
classNames
) { ) {
var Form = React.createClass({ var Form = React.createClass({
@@ -19,9 +21,50 @@ define(
getInitialState: function() { getInitialState: function() {
return { return {
loading: false, loading: false,
errors: [] errors: [],
item: {}
}; };
}, },
componentDidMount: function() {
if(this.props.params.id !== undefined) {
if(this.isMounted()) {
this.loadItem(this.props.params.id);
}
}
},
componentWillReceiveProps: function(props) {
if(props.params.id === undefined) {
this.setState({
loading: false,
item: {}
});
} else {
this.loadItem(props.params.id);
}
},
loadItem: function(id) {
this.setState({ loading: true });
MailPoet.Ajax.post({
endpoint: 'subscribers',
action: 'get',
data: { id: id }
}).done(function(response) {
if(response === false) {
this.setState({
loading: false,
item: {}
}, function() {
this.transitionTo('/new');
}.bind(this));
} else {
this.setState({
loading: false,
item: response
});
}
}.bind(this));
},
handleSubmit: function(e) { handleSubmit: function(e) {
e.preventDefault(); e.preventDefault();
@@ -30,21 +73,31 @@ define(
MailPoet.Ajax.post({ MailPoet.Ajax.post({
endpoint: 'subscribers', endpoint: 'subscribers',
action: 'save', action: 'save',
data: { data: this.state.item
email: React.findDOMNode(this.refs.email).value,
first_name: React.findDOMNode(this.refs.first_name).value,
last_name: React.findDOMNode(this.refs.last_name).value
}
}).done(function(response) { }).done(function(response) {
this.setState({ loading: false }); this.setState({ loading: false });
if(response === true) { if(response === true) {
this.transitionTo('/'); this.transitionTo('/');
if(this.props.params.id !== undefined) {
MailPoet.Notice.success('Subscriber succesfully updated!');
} else {
MailPoet.Notice.success('Subscriber succesfully added!');
}
} else { } else {
this.setState({ errors: response }); this.setState({ errors: response });
} }
}.bind(this)); }.bind(this));
}, },
handleItemChange: function(e) {
var item = this.state.item;
item[e.target.name] = e.target.value;
this.setState({
item: item
});
return true;
},
render: function() { render: function() {
var errors = this.state.errors.map(function(error, index) { var errors = this.state.errors.map(function(error, index) {
return ( return (
@@ -52,17 +105,38 @@ define(
); );
}); });
var formClasses = classNames(
{ 'mailpoet_form_loading': this.state.loading }
);
return ( return (
<form onSubmit={ this.handleSubmit }> <form
className={ formClasses }
onSubmit={ this.handleSubmit }>
{ errors } { errors }
<p> <p>
<input type="text" placeholder="Email" ref="email" /> <input
type="text"
placeholder="Email"
name="email"
value={ this.state.item.email }
onChange={ this.handleItemChange }/>
</p> </p>
<p> <p>
<input type="text" placeholder="First name" ref="first_name" /> <input
type="text"
placeholder="First name"
name="first_name"
value={ this.state.item.first_name }
onChange={ this.handleItemChange }/>
</p> </p>
<p> <p>
<input type="text" placeholder="Last name" ref="last_name" /> <input
type="text"
placeholder="Last name"
name="last_name"
value={ this.state.item.last_name }
onChange={ this.handleItemChange }/>
</p> </p>
<input <input
className="button button-primary" className="button button-primary"

View File

@@ -1,19 +1,21 @@
define( define(
[ [
'react', 'react',
'jquery', 'react-router',
'mailpoet', 'mailpoet',
'listing/listing.jsx', 'listing/listing.jsx',
'classnames' 'classnames',
], ],
function( function(
React, React,
jQuery, Router,
MailPoet, MailPoet,
Listing, Listing,
classNames classNames
) { ) {
var Link = Router.Link;
var columns = [ var columns = [
{ {
name: 'email', name: 'email',
@@ -47,26 +49,10 @@ define(
}, },
]; ];
var item_actions = [
{
name: 'view',
label: 'View',
onClick: function() {
this.transitionTo('/');
}
}
];
var bulk_actions = [ var bulk_actions = [
{ {
name: 'move', name: 'move',
label: 'Move to list...', label: 'Move to list...'
onSelect: function(e) {
console.log(e);
},
onApply: function(selected) {
console.log(selected);
}
}, },
{ {
name: 'add', name: 'add',
@@ -82,7 +68,7 @@ define(
getItems: function(listing) { getItems: function(listing) {
MailPoet.Ajax.post({ MailPoet.Ajax.post({
endpoint: 'subscribers', endpoint: 'subscribers',
action: 'get', action: 'listing',
data: { data: {
offset: (listing.state.page - 1) * listing.state.limit, offset: (listing.state.page - 1) * listing.state.limit,
limit: listing.state.limit, limit: listing.state.limit,
@@ -133,6 +119,13 @@ define(
<strong> <strong>
<a>{ subscriber.email }</a> <a>{ subscriber.email }</a>
</strong> </strong>
<div className="row-actions">
<span className="edit">
<Link to="edit" params={{ id: subscriber.id }}>Edit</Link>
</span>
</div>
<button className="toggle-row" type="button"> <button className="toggle-row" type="button">
<span className="screen-reader-text">Show more details</span> <span className="screen-reader-text">Show more details</span>
</button> </button>
@@ -161,8 +154,7 @@ define(
onRenderItem={ this.renderItem } onRenderItem={ this.renderItem }
items={ this.getItems } items={ this.getItems }
columns={ columns } columns={ columns }
bulk_actions={ bulk_actions } bulk_actions={ bulk_actions } />
item_actions={ item_actions } />
); );
} }
}); });

View File

@@ -16,6 +16,7 @@ define(
var Link = Router.Link; var Link = Router.Link;
var Route = Router.Route; var Route = Router.Route;
var RouteHandler = Router.RouteHandler; var RouteHandler = Router.RouteHandler;
var NotFoundRoute = Router.NotFoundRoute;
var App = React.createClass({ var App = React.createClass({
render: function() { render: function() {
@@ -24,7 +25,7 @@ define(
<h1> <h1>
{ MailPoetI18n.pageTitle } { MailPoetI18n.pageTitle }
&nbsp; &nbsp;
<Link className="add-new-h2" to="form">New</Link> <Link className="add-new-h2" to="new">New</Link>
</h1> </h1>
<RouteHandler/> <RouteHandler/>
@@ -35,8 +36,9 @@ define(
var routes = ( var routes = (
<Route name="app" path="/" handler={App}> <Route name="app" path="/" handler={App}>
<Route name="list" handler={List} /> <Route name="new" path="/new" handler={Form} />
<Route name="form" handler={Form} /> <Route name="edit" path="/edit/:id" handler={Form} />
<NotFoundRoute handler={List} />
<DefaultRoute handler={List} /> <DefaultRoute handler={List} />
</Route> </Route>
); );

View File

@@ -10,6 +10,17 @@ class Subscribers {
} }
function get($data = array()) { function get($data = array()) {
$id = (isset($data['id']) ? (int)$data['id'] : 0);
$subscriber = Subscriber::findOne($id);
if($subscriber === false) {
wp_send_json(false);
} else {
wp_send_json($subscriber->asArray());
}
}
function listing($data = array()) {
$listing = new Listing\Handler( $listing = new Listing\Handler(
\Model::factory('\MailPoet\Models\Subscriber'), \Model::factory('\MailPoet\Models\Subscriber'),
$data $data
@@ -18,23 +29,33 @@ class Subscribers {
} }
function getAll() { function getAll() {
$collection = Subscriber::find_array(); $collection = Subscriber::findArray();
wp_send_json($collection); wp_send_json($collection);
} }
function save($args) { function save($data = array()) {
$model = Subscriber::create(); $id = (isset($data['id']) ? (int)$data['id'] : 0);
$model->hydrate($args);
$saved = $model->save();
if(!$saved) { if($id > 0) {
wp_send_json($model->getValidationErrors()); // update
$model = Subscriber::findOne($id);
$model->hydrate($data);
$saved = $model->save();
} else {
// new
$model = Subscriber::create();
$model->hydrate($data);
$saved = $model->save();
} }
if($saved === false) {
wp_send_json($model->getValidationErrors());
} else {
wp_send_json(true); wp_send_json(true);
} }
}
function update($args) { function update($data) {
} }

View File

@@ -6,7 +6,7 @@
<%= localize({ <%= localize({
'pageTitle': __('Newsletters'), 'pageTitle': __('Newsletters'),
'searchLabel': __('Search'), 'searchLabel': __('Search'),
'loading': __('Loading newsletters...'), 'loadingItems': __('Loading newsletters...'),
'noRecordFound': __('No newsletters found.') 'noItemsFound': __('No newsletters found.')
}) %> }) %>
<% endblock %> <% endblock %>

View File

@@ -6,7 +6,7 @@
<%= localize({ <%= localize({
'pageTitle': __('Segments'), 'pageTitle': __('Segments'),
'searchLabel': __('Search'), 'searchLabel': __('Search'),
'loading': __('Loading segments...'), 'loadingItems': __('Loading segments...'),
'noRecordFound': __('No segments found.') 'noItemsFound': __('No segments found.')
}) %> }) %>
<% endblock %> <% endblock %>

View File

@@ -6,8 +6,8 @@
<%= localize({ <%= localize({
'pageTitle': __('Subscribers'), 'pageTitle': __('Subscribers'),
'searchLabel': __('Search'), 'searchLabel': __('Search'),
'loading': __('Loading subscribers...'), 'loadingItems': __('Loading subscribers...'),
'noRecordFound': __('No subscribers found.'), 'noItemsFound': __('No subscribers found.'),
'selectAllLabel': __('All subscribers on this page are selected.'), 'selectAllLabel': __('All subscribers on this page are selected.'),
'selectAllLink': __('Select all pages.'), 'selectAllLink': __('Select all pages.'),
'clearSelection': __('Clear selection.') 'clearSelection': __('Clear selection.')