Subscribers Listing
- sortable - searchable
This commit is contained in:
committed by
marco
parent
3c46c3cd3a
commit
f721119c9f
@ -1,6 +1,7 @@
|
||||
define('subscribers.listing',
|
||||
['react/addons', 'jquery', 'mailpoet', 'classnames'],
|
||||
function(React, jQuery, MailPoet, classNames) {
|
||||
|
||||
var ListingGroups = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
@ -62,28 +63,52 @@ define('subscribers.listing',
|
||||
});
|
||||
|
||||
var ListingColumn = React.createClass({
|
||||
handleSort: function() {
|
||||
var sort_by = this.props.column.name,
|
||||
sort_order = (this.props.column.sorted === 'asc') ? 'desc' : 'asc';
|
||||
this.props.onSort(sort_by, sort_order);
|
||||
},
|
||||
render: function() {
|
||||
var order = '';
|
||||
if(this.props.column.sortable) {
|
||||
order = this.props.column.order || 'asc';
|
||||
}
|
||||
var classes = classNames(
|
||||
'manage-column',
|
||||
{ 'sortable': this.props.column.sortable },
|
||||
order
|
||||
this.props.column.sorted
|
||||
);
|
||||
|
||||
var label;
|
||||
|
||||
if(this.props.column.sortable === true) {
|
||||
label = (
|
||||
<a onClick={this.handleSort}>
|
||||
<span>{ this.props.column.label }</span>
|
||||
<span className="sorting-indicator"></span>
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
label = this.props.column.label;
|
||||
}
|
||||
return (
|
||||
<th
|
||||
className={ classes }
|
||||
id={ this.props.column.name }
|
||||
scope="col">{ this.props.column.label }</th>
|
||||
id={this.props.column.name }
|
||||
scope="col">
|
||||
{label}
|
||||
</th>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ListingHeader = React.createClass({
|
||||
render: function() {
|
||||
var columns = this.props.columns.map(function(column) {
|
||||
return (
|
||||
<ListingColumn
|
||||
onSort={this.props.onSort}
|
||||
sort_by={this.props.sort_by}
|
||||
key={column.name}
|
||||
column={column} />
|
||||
);
|
||||
}.bind(this));
|
||||
|
||||
return (
|
||||
<tr>
|
||||
@ -93,9 +118,7 @@ define('subscribers.listing',
|
||||
</label>
|
||||
<input type="checkbox" id="cb-select-all-1" />
|
||||
</td>
|
||||
{ this.props.columns.map(function(column) {
|
||||
return (<ListingColumn key={column.name} column={column} />);
|
||||
})}
|
||||
{columns}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
@ -115,10 +138,7 @@ define('subscribers.listing',
|
||||
</th>
|
||||
<td className="title column-title has-row-actions column-primary page-title">
|
||||
<strong>
|
||||
<a
|
||||
title="Edit “{ this.props.item.email }”"
|
||||
href="#"
|
||||
className="row-title">{ this.props.item.email }</a>
|
||||
<a className="row-title">{ this.props.item.email }</a>
|
||||
</strong>
|
||||
</td>
|
||||
<td></td>
|
||||
@ -135,6 +155,15 @@ define('subscribers.listing',
|
||||
|
||||
var ListingItems = React.createClass({
|
||||
render: function() {
|
||||
if(this.props.items.length === 0) {
|
||||
return (
|
||||
<tbody>
|
||||
<td
|
||||
colSpan={this.props.columns.length + 1}
|
||||
className="colspanchange">No subscribers found.</td>
|
||||
</tbody>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<tbody>
|
||||
{this.props.items.map(function(item) {
|
||||
@ -148,6 +177,7 @@ define('subscribers.listing',
|
||||
</tbody>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var Listing = React.createClass({
|
||||
@ -156,6 +186,8 @@ define('subscribers.listing',
|
||||
search: '',
|
||||
page: 1,
|
||||
limit: 10,
|
||||
sort_by: 'email',
|
||||
sort_order: 'asc',
|
||||
items: []
|
||||
};
|
||||
},
|
||||
@ -166,9 +198,6 @@ define('subscribers.listing',
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'subscribers',
|
||||
action: 'get',
|
||||
data: {
|
||||
search: this.state.search
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
if(this.isMounted()) {
|
||||
this.setState({
|
||||
@ -179,11 +208,45 @@ define('subscribers.listing',
|
||||
});
|
||||
},
|
||||
handleSearch: function(search) {
|
||||
this.setState({ search: search }, function() {
|
||||
this.getItems();
|
||||
}.bind(this));
|
||||
this.setState({ search: search });
|
||||
},
|
||||
handleSort: function(sort_by, sort_order = 'asc') {
|
||||
this.setState({
|
||||
sort_by: sort_by,
|
||||
sort_order: sort_order
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var items = this.state.items,
|
||||
search = this.state.search.trim().toLowerCase(),
|
||||
sort_by = this.state.sort_by,
|
||||
sort_order = this.state.sort_order;
|
||||
|
||||
// search
|
||||
if(search.length > 0) {
|
||||
items = items.filter(function(item){
|
||||
return item.email.toLowerCase().match(search);
|
||||
});
|
||||
}
|
||||
|
||||
// sorting
|
||||
items = items.sort(function(a, b) {
|
||||
if(a[sort_by] === b[sort_by]) {
|
||||
return 0;
|
||||
} else {
|
||||
if(sort_order === 'asc') {
|
||||
return (a[sort_by] > b[sort_by]) ? 1 : -1;
|
||||
} else {
|
||||
return (a[sort_by] < b[sort_by]) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
columns = columns.map(function(column) {
|
||||
column.sorted = (column.name === sort_by) ? sort_order : false;
|
||||
return column;
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ListingSearch onSearch={this.handleSearch} />
|
||||
@ -193,15 +256,21 @@ define('subscribers.listing',
|
||||
<table className="wp-list-table widefat fixed">
|
||||
<thead>
|
||||
<ListingHeader
|
||||
onSort={this.handleSort}
|
||||
sort_by={this.state.sort_by}
|
||||
sort_order={this.state.sort_order}
|
||||
columns={this.props.columns} />
|
||||
</thead>
|
||||
|
||||
<ListingItems
|
||||
columns={this.props.columns}
|
||||
items={this.state.items} />
|
||||
items={items} />
|
||||
|
||||
<tfoot>
|
||||
<ListingHeader
|
||||
onSort={this.handleSort}
|
||||
sort_by={this.state.sort_by}
|
||||
sort_order={this.state.sort_order}
|
||||
columns={this.props.columns} />
|
||||
</tfoot>
|
||||
|
||||
@ -223,16 +292,17 @@ define('subscribers.listing',
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: 'Status',
|
||||
sortable: true
|
||||
label: 'Status'
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: 'Subscribed on'
|
||||
label: 'Subscribed on',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'updated_at',
|
||||
label: 'Last modified on'
|
||||
label: 'Last modified on',
|
||||
sortable: true
|
||||
},
|
||||
];
|
||||
|
||||
|
40
composer.lock
generated
40
composer.lock
generated
@ -309,25 +309,29 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.20.0",
|
||||
"version": "v1.21.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844"
|
||||
"reference": "913d282caca9ee0e8d05940c6caa486d58810dd4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
|
||||
"reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/913d282caca9ee0e8d05940c6caa486d58810dd4",
|
||||
"reference": "913d282caca9ee0e8d05940c6caa486d58810dd4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/debug": "~2.7",
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.20-dev"
|
||||
"dev-master": "1.21-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -362,7 +366,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2015-08-12 15:56:39"
|
||||
"time": "2015-08-24 09:51:18"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -1211,16 +1215,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.8.5",
|
||||
"version": "4.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "9b7417edaf28059ea63d86be941e6004dbfcc0cc"
|
||||
"reference": "2246830f4a1a551c67933e4171bf2126dc29d357"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b7417edaf28059ea63d86be941e6004dbfcc0cc",
|
||||
"reference": "9b7417edaf28059ea63d86be941e6004dbfcc0cc",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2246830f4a1a551c67933e4171bf2126dc29d357",
|
||||
"reference": "2246830f4a1a551c67933e4171bf2126dc29d357",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1279,7 +1283,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-08-19 09:20:57"
|
||||
"time": "2015-08-24 04:09:38"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
@ -2801,20 +2805,20 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/extensions",
|
||||
"version": "v1.2.0",
|
||||
"version": "v1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig-extensions.git",
|
||||
"reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd"
|
||||
"reference": "449e3c8a9ffad7c2479c7864557275a32b037499"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/8cf4b9fe04077bd54fc73f4fde83347040c3b8cd",
|
||||
"reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/449e3c8a9ffad7c2479c7864557275a32b037499",
|
||||
"reference": "449e3c8a9ffad7c2479c7864557275a32b037499",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"twig/twig": "~1.12"
|
||||
"twig/twig": "~1.20|~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/translation": "~2.3"
|
||||
@ -2825,7 +2829,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -2849,7 +2853,7 @@
|
||||
"i18n",
|
||||
"text"
|
||||
],
|
||||
"time": "2014-10-30 14:30:03"
|
||||
"time": "2015-08-22 16:38:35"
|
||||
},
|
||||
{
|
||||
"name": "umpirsky/twig-gettext-extractor",
|
||||
|
@ -9,17 +9,7 @@ class Subscribers {
|
||||
}
|
||||
|
||||
function get() {
|
||||
if(isset($_POST['data'])) {
|
||||
// search filter
|
||||
$search = (isset($_POST['data']['search']))
|
||||
? $_POST['data']['search']
|
||||
: '';
|
||||
|
||||
$collection = Subscriber::where_like('email', '%'.$search.'%')->find_array();
|
||||
} else {
|
||||
$collection = Subscriber::find_array();
|
||||
}
|
||||
|
||||
wp_send_json($collection);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user