lotta fixes for filtering + listing
This commit is contained in:
@@ -6,38 +6,48 @@ function(
|
|||||||
) {
|
) {
|
||||||
var ListingFilters = React.createClass({
|
var ListingFilters = React.createClass({
|
||||||
handleFilterAction: function() {
|
handleFilterAction: function() {
|
||||||
var filters = this.props.filters.map(function(filter, index) {
|
var filters = this.props.filters;
|
||||||
var value = this.refs['filter-'+index].value;
|
var selected_filters = Object.keys(filters)
|
||||||
if(value) {
|
.map(function(filter, index) {
|
||||||
return {
|
var value = this.refs.filter.value;
|
||||||
'name': filter.name,
|
if(value) {
|
||||||
'value': value
|
var output = {};
|
||||||
};
|
output[filter] = value;
|
||||||
}
|
return output;
|
||||||
}.bind(this));
|
}
|
||||||
return this.props.onSelectFilter(filters);
|
}.bind(this)
|
||||||
|
);
|
||||||
|
return this.props.onSelectFilter(selected_filters);
|
||||||
},
|
},
|
||||||
handleChangeAction: function() {
|
handleChangeAction: function() {
|
||||||
return true;
|
return this.refs.filter.value;
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var filters = this.props.filters
|
var filters = this.props.filters;
|
||||||
|
var selected_filters = this.props.filter;
|
||||||
|
|
||||||
|
var available_filters = Object.keys(filters)
|
||||||
.filter(function(filter) {
|
.filter(function(filter) {
|
||||||
return !(
|
return !(
|
||||||
filter.options.length === 0
|
filters[filter].length === 0
|
||||||
|| (
|
|| (
|
||||||
filter.options.length === 1
|
filters[filter].length === 1
|
||||||
&& !filter.options[0].value
|
&& !filters[filter][0].value
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.map(function(filter, i) {
|
.map(function(filter, i) {
|
||||||
|
var defaultValue = false;
|
||||||
|
if(selected_filters[filter] !== undefined) {
|
||||||
|
defaultValue = selected_filters[filter];
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
ref={ 'filter-'+i }
|
ref={ 'filter' }
|
||||||
key={ 'filter-'+i }
|
key={ 'filter-'+i }
|
||||||
|
defaultValue={ defaultValue }
|
||||||
onChange={ this.handleChangeAction }>
|
onChange={ this.handleChangeAction }>
|
||||||
{ filter.options.map(function(option, j) {
|
{ filters[filter].map(function(option, j) {
|
||||||
return (
|
return (
|
||||||
<option
|
<option
|
||||||
value={ option.value }
|
value={ option.value }
|
||||||
@@ -51,7 +61,7 @@ function(
|
|||||||
|
|
||||||
var button = false;
|
var button = false;
|
||||||
|
|
||||||
if(filters.length > 0) {
|
if(available_filters.length > 0) {
|
||||||
button = (
|
button = (
|
||||||
<input
|
<input
|
||||||
onClick={ this.handleFilterAction }
|
onClick={ this.handleFilterAction }
|
||||||
@@ -63,7 +73,7 @@ function(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alignleft actions actions">
|
<div className="alignleft actions actions">
|
||||||
{ filters }
|
{ available_filters }
|
||||||
{ button }
|
{ button }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -9,6 +9,9 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
render: function() {
|
render: function() {
|
||||||
var columns = this.props.columns.map(function(column, index) {
|
var columns = this.props.columns.map(function(column, index) {
|
||||||
column.is_primary = (index === 0);
|
column.is_primary = (index === 0);
|
||||||
|
column.sorted = (this.props.sort_by === column.name)
|
||||||
|
? this.props.sort_order
|
||||||
|
: 'asc';
|
||||||
return (
|
return (
|
||||||
<ListingColumn
|
<ListingColumn
|
||||||
onSort={this.props.onSort}
|
onSort={this.props.onSort}
|
||||||
|
@@ -77,12 +77,23 @@ define(
|
|||||||
|
|
||||||
if(custom_actions.length > 0) {
|
if(custom_actions.length > 0) {
|
||||||
item_actions = custom_actions.map(function(action, index) {
|
item_actions = custom_actions.map(function(action, index) {
|
||||||
return (
|
if(action.refresh) {
|
||||||
<span key={ 'action-'+index } className={ action.name }>
|
return (
|
||||||
{ action.link(this.props.item) }
|
<span
|
||||||
{(index < (custom_actions.length - 1)) ? ' | ' : ''}
|
onClick={ this.props.onRefreshItems }
|
||||||
</span>
|
key={ 'action-'+index } className={ action.name }>
|
||||||
);
|
{ action.link(this.props.item) }
|
||||||
|
{(index < (custom_actions.length - 1)) ? ' | ' : ''}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<span key={ 'action-'+index } className={ action.name }>
|
||||||
|
{ action.link(this.props.item) }
|
||||||
|
{(index < (custom_actions.length - 1)) ? ' | ' : ''}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
} else {
|
} else {
|
||||||
item_actions = (
|
item_actions = (
|
||||||
@@ -233,6 +244,7 @@ define(
|
|||||||
onRenderItem={ this.props.onRenderItem }
|
onRenderItem={ this.props.onRenderItem }
|
||||||
onDeleteItem={ this.props.onDeleteItem }
|
onDeleteItem={ this.props.onDeleteItem }
|
||||||
onRestoreItem={ this.props.onRestoreItem }
|
onRestoreItem={ this.props.onRestoreItem }
|
||||||
|
onRefreshItems={ this.props.onRefreshItems }
|
||||||
selection={ this.props.selection }
|
selection={ this.props.selection }
|
||||||
is_selectable={ this.props.is_selectable }
|
is_selectable={ this.props.is_selectable }
|
||||||
item_actions={ this.props.item_actions }
|
item_actions={ this.props.item_actions }
|
||||||
@@ -248,6 +260,9 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
var Listing = React.createClass({
|
var Listing = React.createClass({
|
||||||
|
mixins: [
|
||||||
|
Router.History
|
||||||
|
],
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
@@ -260,8 +275,8 @@ define(
|
|||||||
items: [],
|
items: [],
|
||||||
groups: [],
|
groups: [],
|
||||||
group: 'all',
|
group: 'all',
|
||||||
filters: [],
|
filters: {},
|
||||||
filter: [],
|
filter: {},
|
||||||
selected_ids: [],
|
selected_ids: [],
|
||||||
selection: false
|
selection: false
|
||||||
};
|
};
|
||||||
@@ -277,44 +292,61 @@ define(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
if(this.props.limit !== undefined) {
|
if(this.isMounted()) {
|
||||||
this.setState({
|
var state = this.state || {};
|
||||||
limit: Math.abs(~~this.props.limit)
|
var params = this.props.params || {};
|
||||||
}, function() {
|
|
||||||
|
// set filters
|
||||||
|
if(params.filter !== undefined) {
|
||||||
|
var filter = {};
|
||||||
|
var pairs = params.filter
|
||||||
|
.split('&')
|
||||||
|
.map(function(pair) {
|
||||||
|
var [key, value] = pair.split('=');
|
||||||
|
filter[key] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
state.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.props.limit !== undefined) {
|
||||||
|
state.limit = Math.abs(~~this.props.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(state, function() {
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
} else {
|
|
||||||
this.getItems();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getItems: function() {
|
getItems: function() {
|
||||||
this.setState({ loading: true });
|
if(this.isMounted()) {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
this.clearSelection();
|
this.clearSelection();
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'listing',
|
action: 'listing',
|
||||||
data: {
|
data: {
|
||||||
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,
|
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
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).done(function(response) {
|
||||||
if(this.isMounted()) {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
items: response.items || [],
|
items: response.items || [],
|
||||||
filters: response.filters || [],
|
filters: response.filters || {},
|
||||||
groups: response.groups || [],
|
groups: response.groups || [],
|
||||||
count: response.count || 0,
|
count: response.count || 0,
|
||||||
loading: false
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}.bind(this));
|
||||||
}.bind(this));
|
}
|
||||||
},
|
},
|
||||||
handleRestoreItem: function(id) {
|
handleRestoreItem: function(id) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -507,17 +539,14 @@ define(
|
|||||||
var render = this.props.onRenderItem(item, actions);
|
var render = this.props.onRenderItem(item, actions);
|
||||||
return render.props.children;
|
return render.props.children;
|
||||||
},
|
},
|
||||||
|
handleRefreshItems: function() {
|
||||||
|
this.getItems();
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var items = this.state.items,
|
var items = this.state.items,
|
||||||
sort_by = this.state.sort_by,
|
sort_by = this.state.sort_by,
|
||||||
sort_order = this.state.sort_order;
|
sort_order = this.state.sort_order;
|
||||||
|
|
||||||
// set sortable columns
|
|
||||||
columns = this.props.columns.map(function(column) {
|
|
||||||
column.sorted = (column.name === sort_by) ? sort_order : false;
|
|
||||||
return column;
|
|
||||||
});
|
|
||||||
|
|
||||||
// bulk actions
|
// bulk actions
|
||||||
var bulk_actions = this.props.bulk_actions || [];
|
var bulk_actions = this.props.bulk_actions || [];
|
||||||
|
|
||||||
@@ -573,9 +602,6 @@ define(
|
|||||||
groups = false;
|
groups = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filters
|
|
||||||
var filter = this.state.filter;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ groups }
|
{ groups }
|
||||||
@@ -588,7 +614,7 @@ define(
|
|||||||
onBulkAction={ this.handleBulkAction } />
|
onBulkAction={ this.handleBulkAction } />
|
||||||
<ListingFilters
|
<ListingFilters
|
||||||
filters={ this.state.filters }
|
filters={ this.state.filters }
|
||||||
filter={ filter }
|
filter={ this.state.filter }
|
||||||
onSelectFilter={ this.handleFilter } />
|
onSelectFilter={ this.handleFilter } />
|
||||||
<ListingPages
|
<ListingPages
|
||||||
count={ this.state.count }
|
count={ this.state.count }
|
||||||
@@ -612,6 +638,7 @@ define(
|
|||||||
onRenderItem={ this.handleRenderItem }
|
onRenderItem={ this.handleRenderItem }
|
||||||
onDeleteItem={ this.handleDeleteItem }
|
onDeleteItem={ this.handleDeleteItem }
|
||||||
onRestoreItem={ this.handleRestoreItem }
|
onRestoreItem={ this.handleRestoreItem }
|
||||||
|
onRefreshItems={ this.handleRefreshItems }
|
||||||
columns={ this.props.columns }
|
columns={ this.props.columns }
|
||||||
is_selectable={ bulk_actions.length > 0 }
|
is_selectable={ bulk_actions.length > 0 }
|
||||||
onSelectItem={ this.handleSelectItem }
|
onSelectItem={ this.handleSelectItem }
|
||||||
|
@@ -37,19 +37,82 @@ define(
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var messages = {
|
||||||
|
onDelete: function(response) {
|
||||||
|
var count = ~~response.newsletters;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1 || response === true) {
|
||||||
|
message = (
|
||||||
|
'1 newsletter was moved to the trash.'
|
||||||
|
);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d newsletters were moved to the trash.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message !== null) {
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onConfirmDelete: function(response) {
|
||||||
|
var count = ~~response.newsletters;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1 || response === true) {
|
||||||
|
message = (
|
||||||
|
'1 newsletter was permanently deleted.'
|
||||||
|
);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d newsletters were permanently deleted.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message !== null) {
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRestore: function(response) {
|
||||||
|
var count = ~~response.newsletters;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1 || response === true) {
|
||||||
|
message = (
|
||||||
|
'1 newsletter has been restored from the trash.'
|
||||||
|
);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d newsletters have been restored from the trash.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message !== null) {
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var bulk_actions = [
|
var bulk_actions = [
|
||||||
{
|
{
|
||||||
name: 'trash',
|
name: 'trash',
|
||||||
label: 'Trash'
|
label: 'Trash',
|
||||||
|
getData: function() {
|
||||||
|
return {
|
||||||
|
confirm: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: messages.onDelete
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var item_actions = [
|
var item_actions = [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
link: function(id) {
|
link: function(item) {
|
||||||
return (
|
return (
|
||||||
<a href={ '?page=mailpoet-newsletter-editor&id=' + id }>
|
<a href={ `?page=mailpoet-newsletter-editor&id=${ item.id }` }>
|
||||||
Edit
|
Edit
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
@@ -104,7 +167,8 @@ define(
|
|||||||
onRenderItem={this.renderItem}
|
onRenderItem={this.renderItem}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
item_actions={ item_actions } />
|
item_actions={ item_actions }
|
||||||
|
messages={ messages } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ if(container) {
|
|||||||
<Route path="new" component={ NewsletterTypes } />
|
<Route path="new" component={ NewsletterTypes } />
|
||||||
<Route path="new/:type" component={ NewsletterTemplates } />
|
<Route path="new/:type" component={ NewsletterTemplates } />
|
||||||
<Route path="send/:id" component={ NewsletterSend } />
|
<Route path="send/:id" component={ NewsletterSend } />
|
||||||
|
<Route path="filter[:filter]" component={ NewsletterList } />
|
||||||
<Route path="*" component={ NewsletterList } />
|
<Route path="*" component={ NewsletterList } />
|
||||||
</Route>
|
</Route>
|
||||||
</Router>
|
</Router>
|
||||||
|
@@ -115,6 +115,7 @@ define(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'duplicate_segment',
|
name: 'duplicate_segment',
|
||||||
|
refresh: true,
|
||||||
link: function(item) {
|
link: function(item) {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
@@ -233,7 +233,8 @@ define(
|
|||||||
var row_classes = classNames(
|
var row_classes = classNames(
|
||||||
'manage-column',
|
'manage-column',
|
||||||
'column-primary',
|
'column-primary',
|
||||||
'has-row-actions'
|
'has-row-actions',
|
||||||
|
'column-username'
|
||||||
);
|
);
|
||||||
|
|
||||||
var status = '';
|
var status = '';
|
||||||
@@ -258,9 +259,23 @@ define(
|
|||||||
return segment.name;
|
return segment.name;
|
||||||
}).join(', ');
|
}).join(', ');
|
||||||
|
|
||||||
|
var avatar = false;
|
||||||
|
if(subscriber.avatar_url) {
|
||||||
|
avatar = (
|
||||||
|
<img
|
||||||
|
className="avatar"
|
||||||
|
src={ subscriber.avatar_url }
|
||||||
|
title=""
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<td className={ row_classes }>
|
<td className={ row_classes }>
|
||||||
|
{ avatar }
|
||||||
<strong><Link to={ `/edit/${ subscriber.id }` }>
|
<strong><Link to={ `/edit/${ subscriber.id }` }>
|
||||||
{ subscriber.email }
|
{ subscriber.email }
|
||||||
</Link></strong>
|
</Link></strong>
|
||||||
@@ -295,6 +310,7 @@ define(
|
|||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<Listing
|
<Listing
|
||||||
|
params={ this.props.params }
|
||||||
endpoint="subscribers"
|
endpoint="subscribers"
|
||||||
onRenderItem={ this.renderItem }
|
onRenderItem={ this.renderItem }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
|
@@ -22,6 +22,7 @@ if(container) {
|
|||||||
<IndexRoute component={ SubscriberList } />
|
<IndexRoute component={ SubscriberList } />
|
||||||
<Route path="new" component={ SubscriberForm } />
|
<Route path="new" component={ SubscriberForm } />
|
||||||
<Route path="edit/:id" component={ SubscriberForm } />
|
<Route path="edit/:id" component={ SubscriberForm } />
|
||||||
|
<Route path="filter[:filter]" component={ SubscriberList } />
|
||||||
<Route path="*" component={ SubscriberList } />
|
<Route path="*" component={ SubscriberList } />
|
||||||
</Route>
|
</Route>
|
||||||
</Router>
|
</Router>
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "d72500818c46823a667d76239af98609",
|
"hash": "92704d2679fce692438b9e6f1dc6e02f",
|
||||||
"content-hash": "3297411fcec47a02bc4f456fbf3751d1",
|
"content-hash": "3297411fcec47a02bc4f456fbf3751d1",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
@@ -1274,16 +1274,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "4.8.14",
|
"version": "4.8.16",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "b4900675926860bef091644849305399b986efa2"
|
"reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b4900675926860bef091644849305399b986efa2",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/625f8c345606ed0f3a141dfb88f4116f0e22978e",
|
||||||
"reference": "b4900675926860bef091644849305399b986efa2",
|
"reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1342,7 +1342,7 @@
|
|||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2015-10-17 15:03:30"
|
"time": "2015-10-23 06:48:33"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit-mock-objects",
|
"name": "phpunit/phpunit-mock-objects",
|
||||||
|
@@ -66,7 +66,7 @@ class Handler {
|
|||||||
|
|
||||||
function getSelection() {
|
function getSelection() {
|
||||||
if(!empty($this->data['selection'])) {
|
if(!empty($this->data['selection'])) {
|
||||||
$this->model->whereIn('id', $this->data['selection']);
|
$this->model->whereIn($this->table_name.'.id', $this->data['selection']);
|
||||||
}
|
}
|
||||||
return $this->model;
|
return $this->model;
|
||||||
}
|
}
|
||||||
|
@@ -39,10 +39,10 @@ class Newsletter extends Model {
|
|||||||
'label' => __('All lists'),
|
'label' => __('All lists'),
|
||||||
'value' => ''
|
'value' => ''
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach($segments as $segment) {
|
foreach($segments as $segment) {
|
||||||
$newsletters_count = $segment->newsletters()->count();
|
$newsletters_count = $segment->newsletters()->count();
|
||||||
if($newsletters_count > 0) {
|
if($newsletters_count > 0) {
|
||||||
|
|
||||||
$segment_list[] = array(
|
$segment_list[] = array(
|
||||||
'label' => sprintf('%s (%d)', $segment->name, $newsletters_count),
|
'label' => sprintf('%s (%d)', $segment->name, $newsletters_count),
|
||||||
'value' => $segment->id()
|
'value' => $segment->id()
|
||||||
@@ -51,34 +51,21 @@ class Newsletter extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$filters = array(
|
$filters = array(
|
||||||
array(
|
'segment' => $segment_list
|
||||||
'name' => 'segment',
|
|
||||||
'options' => $segment_list
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $filters;
|
return $filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function filterBy($orm, $filters = null) {
|
static function filterBy($orm, $filters = null) {
|
||||||
if(empty($filters)) {
|
if(empty($filters)) {
|
||||||
return $orm;
|
return $orm;
|
||||||
}
|
}
|
||||||
|
foreach($filters as $key => $value) {
|
||||||
foreach($filters as $filter) {
|
if($key === 'segment') {
|
||||||
if($filter['name'] === 'segment') {
|
$segment = Segment::findOne($value);
|
||||||
|
|
||||||
$segment = Segment::findOne($filter['value']);
|
|
||||||
if($segment !== false) {
|
if($segment !== false) {
|
||||||
$orm = $orm
|
$orm = $segment->newsletters();
|
||||||
->select(MP_NEWSLETTERS_TABLE.'.*')
|
|
||||||
->select('newsletter_segment.id', 'newsletter_segment_id')
|
|
||||||
->join(
|
|
||||||
MP_NEWSLETTER_SEGMENT_TABLE,
|
|
||||||
MP_NEWSLETTERS_TABLE.'.id = newsletter_segment.newsletter_id',
|
|
||||||
'newsletter_segment'
|
|
||||||
)
|
|
||||||
->where('newsletter_segment.segment_id', (int)$filter['value']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,12 +99,21 @@ class Newsletter extends Model {
|
|||||||
array(
|
array(
|
||||||
'name' => 'all',
|
'name' => 'all',
|
||||||
'label' => __('All'),
|
'label' => __('All'),
|
||||||
'count' => Newsletter::count()
|
'count' => Newsletter::whereNull('deleted_at')->count()
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'trash',
|
||||||
|
'label' => __('Trash'),
|
||||||
|
'count' => Newsletter::whereNotNull('deleted_at')->count()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function group($orm, $group = null) {
|
static function groupBy($orm, $group = null) {
|
||||||
|
if($group === 'trash') {
|
||||||
|
return $orm->whereNotNull('deleted_at');
|
||||||
|
}
|
||||||
|
return $orm->whereNull('deleted_at');
|
||||||
}
|
}
|
||||||
|
|
||||||
static function createOrUpdate($data = array()) {
|
static function createOrUpdate($data = array()) {
|
||||||
@@ -148,8 +144,45 @@ class Newsletter extends Model {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function trash($listing) {
|
static function trash($listing, $data = array()) {
|
||||||
return $listing->getSelection()
|
$confirm_delete = filter_var($data['confirm'], FILTER_VALIDATE_BOOLEAN);
|
||||||
->deleteMany();
|
if($confirm_delete) {
|
||||||
|
// delete relations with all segments
|
||||||
|
$newsletters = $listing->getSelection()->findResultSet();
|
||||||
|
|
||||||
|
if(!empty($newsletters)) {
|
||||||
|
$newsletters_count = 0;
|
||||||
|
foreach($newsletters as $newsletter) {
|
||||||
|
if($newsletter->delete()) {
|
||||||
|
$newsletters_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'newsletters' => $newsletters_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// soft delete
|
||||||
|
$newsletters = $listing->getSelection()
|
||||||
|
->findResultSet()
|
||||||
|
->set_expr('deleted_at', 'NOW()')
|
||||||
|
->save();
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'newsletters' => $newsletters->count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static function restore($listing, $data = array()) {
|
||||||
|
$newsletters = $listing->getSelection()
|
||||||
|
->findResultSet()
|
||||||
|
->set_expr('deleted_at', 'NULL')
|
||||||
|
->save();
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'newsletters' => $newsletters->count()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,6 @@ class Subscriber extends Model {
|
|||||||
static function filters() {
|
static function filters() {
|
||||||
$segments = Segment::orderByAsc('name')->findMany();
|
$segments = Segment::orderByAsc('name')->findMany();
|
||||||
$segment_list = array();
|
$segment_list = array();
|
||||||
|
|
||||||
$segment_list[] = array(
|
$segment_list[] = array(
|
||||||
'label' => __('All lists'),
|
'label' => __('All lists'),
|
||||||
'value' => ''
|
'value' => ''
|
||||||
@@ -53,10 +52,7 @@ class Subscriber extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$filters = array(
|
$filters = array(
|
||||||
array(
|
'segment' => $segment_list
|
||||||
'name' => 'segment',
|
|
||||||
'options' => $segment_list
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $filters;
|
return $filters;
|
||||||
@@ -66,10 +62,9 @@ class Subscriber extends Model {
|
|||||||
if(empty($filters)) {
|
if(empty($filters)) {
|
||||||
return $orm;
|
return $orm;
|
||||||
}
|
}
|
||||||
|
foreach($filters as $key => $value) {
|
||||||
foreach($filters as $filter) {
|
if($key === 'segment') {
|
||||||
if($filter['name'] === 'segment') {
|
$segment = Segment::findOne($value);
|
||||||
$segment = Segment::findOne($filter['value']);
|
|
||||||
if($segment !== false) {
|
if($segment !== false) {
|
||||||
$orm = $segment->subscribers();
|
$orm = $segment->subscribers();
|
||||||
}
|
}
|
||||||
@@ -197,10 +192,9 @@ class Subscriber extends Model {
|
|||||||
static function moveToList($listing, $data = array()) {
|
static function moveToList($listing, $data = array()) {
|
||||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||||
$segment = Segment::findOne($segment_id);
|
$segment = Segment::findOne($segment_id);
|
||||||
|
|
||||||
if($segment !== false) {
|
if($segment !== false) {
|
||||||
$subscribers_count = 0;
|
$subscribers_count = 0;
|
||||||
$subscribers = $listing->getSelection()->findMany();
|
$subscribers = $listing->getSelection()->findResultSet();
|
||||||
foreach($subscribers as $subscriber) {
|
foreach($subscribers as $subscriber) {
|
||||||
// remove subscriber from all segments
|
// remove subscriber from all segments
|
||||||
SubscriberSegment::where('subscriber_id', $subscriber->id)->deleteMany();
|
SubscriberSegment::where('subscriber_id', $subscriber->id)->deleteMany();
|
||||||
|
@@ -60,10 +60,28 @@ class Newsletters {
|
|||||||
wp_send_json(($newsletter_id !== false));
|
wp_send_json(($newsletter_id !== false));
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete($id) {
|
function delete($data = array()) {
|
||||||
|
$newsletter = newsletter::findOne($data['id']);
|
||||||
|
$confirm_delete = filter_var($data['confirm'], FILTER_VALIDATE_BOOLEAN);
|
||||||
|
if($newsletter !== false) {
|
||||||
|
if($confirm_delete) {
|
||||||
|
$newsletter->delete();
|
||||||
|
$result = array('newsletters' => 1);
|
||||||
|
} else {
|
||||||
|
$newsletter->set_expr('deleted_at', 'NOW()');
|
||||||
|
$result = array('newsletters' => (int)$newsletter->save());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
wp_send_json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function restore($id) {
|
||||||
$newsletter = Newsletter::findOne($id);
|
$newsletter = Newsletter::findOne($id);
|
||||||
if($newsletter !== false) {
|
if($newsletter !== false) {
|
||||||
$result = $newsletter->delete();
|
$newsletter->set_expr('deleted_at', 'NULL');
|
||||||
|
$result = array('newsletters' => (int)$newsletter->save());
|
||||||
} else {
|
} else {
|
||||||
$result = false;
|
$result = false;
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ class Segments {
|
|||||||
$item = array_merge($item, $stats);
|
$item = array_merge($item, $stats);
|
||||||
|
|
||||||
$item['subscribers_url'] = admin_url(
|
$item['subscribers_url'] = admin_url(
|
||||||
'admin.php?page=mailpoet-subscribers#segment='.$item['id']
|
'admin.php?page=mailpoet-subscribers#/filter[segment='.$item['id'].']'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,12 @@ class Subscribers {
|
|||||||
|
|
||||||
// fetch segments relations for each returned item
|
// fetch segments relations for each returned item
|
||||||
foreach($listing_data['items'] as &$item) {
|
foreach($listing_data['items'] as &$item) {
|
||||||
|
// avatar
|
||||||
|
$item['avatar_url'] = get_avatar_url($item['email'], array(
|
||||||
|
'size' => 32
|
||||||
|
));
|
||||||
|
|
||||||
|
// subscriber's segments
|
||||||
$relations = SubscriberSegment::select('segment_id')
|
$relations = SubscriberSegment::select('segment_id')
|
||||||
->where('subscriber_id', $item['id'])
|
->where('subscriber_id', $item['id'])
|
||||||
->findMany();
|
->findMany();
|
||||||
|
@@ -36,9 +36,9 @@
|
|||||||
"underscore": "1.8.3"
|
"underscore": "1.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"export-loader": "webpack/exports-loader.git",
|
"expose-loader": "latest",
|
||||||
"import-loader": "webpack/imports-loader.git",
|
"exports-loader": "latest",
|
||||||
"expose-loader": "webpack/expose-loader.git",
|
"imports-loader": "latest",
|
||||||
"babel-core": "^5.8.22",
|
"babel-core": "^5.8.22",
|
||||||
"babel-loader": "^5.3.2",
|
"babel-loader": "^5.3.2",
|
||||||
"amd-inject-loader": "latest",
|
"amd-inject-loader": "latest",
|
||||||
|
Reference in New Issue
Block a user