Listing filters
This commit is contained in:
@ -1,10 +1,8 @@
|
|||||||
define([
|
define([
|
||||||
'react',
|
'react'
|
||||||
'mailpoet'
|
|
||||||
],
|
],
|
||||||
function(
|
function(
|
||||||
React,
|
React
|
||||||
MailPoet
|
|
||||||
) {
|
) {
|
||||||
var ListingBulkActions = React.createClass({
|
var ListingBulkActions = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -1,8 +1,72 @@
|
|||||||
define(['react'], function(React) {
|
define([
|
||||||
|
'react'
|
||||||
|
],
|
||||||
|
function(
|
||||||
|
React
|
||||||
|
) {
|
||||||
var ListingFilters = React.createClass({
|
var ListingFilters = React.createClass({
|
||||||
|
handleFilterAction: function() {
|
||||||
|
var filters = this.props.filters.map(function(filter, index) {
|
||||||
|
var value = this.refs['filter-'+index].getDOMNode().value;
|
||||||
|
if(value) {
|
||||||
|
return {
|
||||||
|
'name': filter.name,
|
||||||
|
'value': value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
return this.props.onSelectFilter(filters);
|
||||||
|
},
|
||||||
|
handleChangeAction: function() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return null;
|
var filters = this.props.filters
|
||||||
|
.filter(function(filter) {
|
||||||
|
return !(
|
||||||
|
filter.options.length === 0
|
||||||
|
|| (
|
||||||
|
filter.options.length === 1
|
||||||
|
&& !filter.options[0].value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map(function(filter, i) {
|
||||||
|
return (
|
||||||
|
<select
|
||||||
|
ref={ 'filter-'+i }
|
||||||
|
key={ 'filter-'+i }
|
||||||
|
onChange={ this.handleChangeAction }>
|
||||||
|
{ filter.options.map(function(option, j) {
|
||||||
|
return (
|
||||||
|
<option
|
||||||
|
value={ option.value }
|
||||||
|
key={ 'filter-option-' + j }
|
||||||
|
>{ option.label }</option>
|
||||||
|
);
|
||||||
|
}.bind(this)) }
|
||||||
|
</select>
|
||||||
|
);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
var button = false;
|
||||||
|
|
||||||
|
if(filters.length > 0) {
|
||||||
|
button = (
|
||||||
|
<input
|
||||||
|
onClick={ this.handleFilterAction }
|
||||||
|
type="submit"
|
||||||
|
defaultValue="Filter"
|
||||||
|
className="button" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="alignleft actions actions">
|
||||||
|
{ filters }
|
||||||
|
{ button }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -209,6 +209,7 @@ define(
|
|||||||
groups: [],
|
groups: [],
|
||||||
group: 'all',
|
group: 'all',
|
||||||
filters: [],
|
filters: [],
|
||||||
|
filter: [],
|
||||||
selected_ids: [],
|
selected_ids: [],
|
||||||
selection: false
|
selection: false
|
||||||
};
|
};
|
||||||
@ -228,6 +229,7 @@ define(
|
|||||||
offset: (this.state.page - 1) * this.state.limit,
|
offset: (this.state.page - 1) * this.state.limit,
|
||||||
limit: this.state.limit,
|
limit: this.state.limit,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
|
filter: this.state.filter,
|
||||||
search: this.state.search,
|
search: this.state.search,
|
||||||
sort_by: this.state.sort_by,
|
sort_by: this.state.sort_by,
|
||||||
sort_order: this.state.sort_order
|
sort_order: this.state.sort_order
|
||||||
@ -270,6 +272,7 @@ define(
|
|||||||
data.listing = {
|
data.listing = {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
|
filter: this.state.filter,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
search: this.state.search,
|
search: this.state.search,
|
||||||
selection: selected_ids
|
selection: selected_ids
|
||||||
@ -350,13 +353,21 @@ define(
|
|||||||
selected_ids: []
|
selected_ids: []
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleFilter: function(filters) {
|
||||||
|
this.setState({
|
||||||
|
filter: filters,
|
||||||
|
page: 1
|
||||||
|
}, function() {
|
||||||
|
this.getItems();
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
handleGroup: function(group) {
|
handleGroup: function(group) {
|
||||||
// reset search
|
// reset search
|
||||||
jQuery('#search_input').val('');
|
jQuery('#search_input').val('');
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
group: group,
|
group: group,
|
||||||
filters: [],
|
filter: [],
|
||||||
search: '',
|
search: '',
|
||||||
page: 1
|
page: 1
|
||||||
}, function() {
|
}, function() {
|
||||||
@ -414,7 +425,10 @@ define(
|
|||||||
selection={ this.state.selection }
|
selection={ this.state.selection }
|
||||||
selected_ids={ this.state.selected_ids }
|
selected_ids={ this.state.selected_ids }
|
||||||
onBulkAction={ this.handleBulkAction } />
|
onBulkAction={ this.handleBulkAction } />
|
||||||
<ListingFilters filters={ this.state.filters } />
|
<ListingFilters
|
||||||
|
filters={ this.state.filters }
|
||||||
|
filter={ this.state.filter }
|
||||||
|
onSelectFilter={ this.handleFilter } />
|
||||||
<ListingPages
|
<ListingPages
|
||||||
count={ this.state.count }
|
count={ this.state.count }
|
||||||
page={ this.state.page }
|
page={ this.state.page }
|
||||||
|
@ -21,13 +21,16 @@ class Handler {
|
|||||||
'sort_order' => (isset($data['sort_order']) ? $data['sort_order'] : 'asc'),
|
'sort_order' => (isset($data['sort_order']) ? $data['sort_order'] : 'asc'),
|
||||||
// grouping
|
// grouping
|
||||||
'group' => (isset($data['group']) ? $data['group'] : null),
|
'group' => (isset($data['group']) ? $data['group'] : null),
|
||||||
|
// filters
|
||||||
|
'filter' => (isset($data['filter']) ? $data['filter'] : null),
|
||||||
// selection
|
// selection
|
||||||
'selection' => (isset($data['selection']) ? $data['selection'] : null)
|
'selection' => (isset($data['selection']) ? $data['selection'] : null)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->setSearch();
|
$this->setSearch();
|
||||||
$this->setOrder();
|
|
||||||
$this->setGroup();
|
$this->setGroup();
|
||||||
|
$this->setFilter();
|
||||||
|
$this->setOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setSearch() {
|
private function setSearch() {
|
||||||
@ -39,25 +42,35 @@ class Handler {
|
|||||||
|
|
||||||
private function setOrder() {
|
private function setOrder() {
|
||||||
return $this->model
|
return $this->model
|
||||||
->{'order_by_'.$this->data['sort_order']}($this->data['sort_by']);
|
->tableAlias('model')
|
||||||
|
->{'order_by_'.$this->data['sort_order']}(
|
||||||
|
'model.'.$this->data['sort_by']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setGroup() {
|
private function setGroup() {
|
||||||
if($this->data['group'] === null) {
|
if($this->data['group'] === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return $this->model->filter('group', $this->data['group']);
|
return $this->model->filter('groupBy', $this->data['group']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setFilter() {
|
||||||
|
if($this->data['filter'] === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return $this->model->filter('filterBy', $this->data['filter']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelection() {
|
function getSelection() {
|
||||||
if(!empty($this->data['selection'])) {
|
if(!empty($this->data['selection'])) {
|
||||||
$this->model->whereIn('id', $this->data['selection']);
|
$this->model->whereIn('model.id', $this->data['selection']);
|
||||||
}
|
}
|
||||||
return $this->model;
|
return $this->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectionIds() {
|
function getSelectionIds() {
|
||||||
$models = $this->getSelection()->select('id')->findMany();
|
$models = $this->getSelection()->select('model.id')->findMany();
|
||||||
return array_map(function($model) {
|
return array_map(function($model) {
|
||||||
return (int)$model->id;
|
return (int)$model->id;
|
||||||
}, $models);
|
}, $models);
|
||||||
@ -66,7 +79,7 @@ class Handler {
|
|||||||
function get() {
|
function get() {
|
||||||
return array(
|
return array(
|
||||||
'count' => $this->model->count(),
|
'count' => $this->model->count(),
|
||||||
'filters' => [],
|
'filters' => $this->model->filter('filters'),
|
||||||
'groups' => $this->model->filter('groups'),
|
'groups' => $this->model->filter('groups'),
|
||||||
'items' => $this->model
|
'items' => $this->model
|
||||||
->offset($this->data['offset'])
|
->offset($this->data['offset'])
|
||||||
|
@ -33,6 +33,52 @@ class Subscriber extends Model {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function filters() {
|
||||||
|
$segments = Segment::orderByAsc('name')->findMany();
|
||||||
|
$segment_list = array();
|
||||||
|
|
||||||
|
$segment_list[] = array(
|
||||||
|
'label' => __('All lists'),
|
||||||
|
'value' => ''
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach($segments as $segment) {
|
||||||
|
$subscribers_count = $segment->subscribers()->count();
|
||||||
|
if($subscribers_count > 0) {
|
||||||
|
$segment_list[] = array(
|
||||||
|
'label' => sprintf('%s (%d)', $segment->name, $subscribers_count),
|
||||||
|
'value' => $segment->id()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$filters = array(
|
||||||
|
array(
|
||||||
|
'name' => 'segment',
|
||||||
|
'options' => $segment_list
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function filterBy($orm, $filters = null) {
|
||||||
|
if(empty($filters)) {
|
||||||
|
return $orm;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($filters as $filter) {
|
||||||
|
if($filter['name'] === 'segment') {
|
||||||
|
$segment = Segment::findOne($filter['value']);
|
||||||
|
if($segment !== false) {
|
||||||
|
$orm = $segment->subscribers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orm;
|
||||||
|
}
|
||||||
|
|
||||||
static function groups() {
|
static function groups() {
|
||||||
return array(
|
return array(
|
||||||
array(
|
array(
|
||||||
@ -58,7 +104,7 @@ class Subscriber extends Model {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function group($orm, $group = null) {
|
static function groupBy($orm, $group = null) {
|
||||||
if($group === null or !in_array(
|
if($group === null or !in_array(
|
||||||
$group,
|
$group,
|
||||||
array('subscribed', 'unconfirmed', 'unsubscribed')
|
array('subscribed', 'unconfirmed', 'unsubscribed')
|
||||||
|
@ -28,7 +28,6 @@ class Subscribers {
|
|||||||
$data
|
$data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
$listing_data = $listing->get();
|
$listing_data = $listing->get();
|
||||||
|
|
||||||
// fetch segments relations for each returned item
|
// fetch segments relations for each returned item
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"sticky-kit": "leafo/sticky-kit.git",
|
"sticky-kit": "leafo/sticky-kit.git",
|
||||||
"interact.js": "taye/interact.js.git"
|
"interact.js": "taye/interact.js.git",
|
||||||
|
"export-loader": "webpack/exports-loader.git",
|
||||||
|
"import-loader": "webpack/imports-loader.git",
|
||||||
|
"expose-loader": "webpack/expose-loader.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"backbone": "1.2.3",
|
"backbone": "1.2.3",
|
||||||
@ -36,9 +39,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^5.8.22",
|
"babel-core": "^5.8.22",
|
||||||
"babel-loader": "^5.3.2",
|
"babel-loader": "^5.3.2",
|
||||||
"export-loader": "webpack/exports-loader.git",
|
|
||||||
"import-loader": "webpack/imports-loader.git",
|
|
||||||
"expose-loader": "webpack/expose-loader.git",
|
|
||||||
"amd-inject-loader": "latest",
|
"amd-inject-loader": "latest",
|
||||||
"chai": "2.2.0",
|
"chai": "2.2.0",
|
||||||
"chai-jq": "0.0.8",
|
"chai-jq": "0.0.8",
|
||||||
|
@ -84,17 +84,17 @@ class SubscriberCest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function itHasAGroupFilter() {
|
function itHasAGroupFilter() {
|
||||||
$subscribers = Subscriber::filter('group', 'unconfirmed')->findMany();
|
$subscribers = Subscriber::filter('groupBy', 'unconfirmed')->findMany();
|
||||||
foreach($subscribers as $subscriber) {
|
foreach($subscribers as $subscriber) {
|
||||||
expect($subscriber->status)->equals('unconfirmed');
|
expect($subscriber->status)->equals('unconfirmed');
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscribers = Subscriber::filter('group', 'subscribed')->findMany();
|
$subscribers = Subscriber::filter('groupBy', 'subscribed')->findMany();
|
||||||
foreach($subscribers as $subscriber) {
|
foreach($subscribers as $subscriber) {
|
||||||
expect($subscriber->status)->equals('subscribed');
|
expect($subscriber->status)->equals('subscribed');
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscribers = Subscriber::filter('group', 'unsubscribed')->findMany();
|
$subscribers = Subscriber::filter('groupBy', 'unsubscribed')->findMany();
|
||||||
foreach($subscribers as $subscriber) {
|
foreach($subscribers as $subscriber) {
|
||||||
expect($subscriber->status)->equals('unsubscribed');
|
expect($subscriber->status)->equals('unsubscribed');
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user