listing modifications + added description to segments
This commit is contained in:
@ -19,6 +19,8 @@ a:focus
|
|||||||
|
|
||||||
// select 2
|
// select 2
|
||||||
.select2-container
|
.select2-container
|
||||||
|
// textareas
|
||||||
|
textarea.regular-text
|
||||||
width: 25em !important
|
width: 25em !important
|
||||||
|
|
||||||
@media screen and (max-width: 782px)
|
@media screen and (max-width: 782px)
|
||||||
|
@ -70,10 +70,21 @@ define(
|
|||||||
|
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
// only get values from displayed fields
|
||||||
|
item = {};
|
||||||
|
this.props.fields.map(function(field) {
|
||||||
|
item[field.name] = this.state.item[field.name];
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
// set id if specified
|
||||||
|
if(this.props.params.id !== undefined) {
|
||||||
|
item.id = this.props.params.id;
|
||||||
|
}
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: this.state.item
|
data: item
|
||||||
}).done(function(response) {
|
}).done(function(response) {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
|
|
||||||
|
@ -266,8 +266,26 @@ define(
|
|||||||
selection: false
|
selection: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
componentDidUpdate: function(prevProps, prevState) {
|
||||||
|
// set group to "all" if trash gets emptied
|
||||||
|
if(
|
||||||
|
(prevState.group === 'trash' && prevState.count > 0)
|
||||||
|
&&
|
||||||
|
(this.state.group === 'trash' && this.state.count === 0)
|
||||||
|
) {
|
||||||
|
this.handleGroup('all');
|
||||||
|
}
|
||||||
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
if(this.props.limit !== undefined) {
|
||||||
|
this.setState({
|
||||||
|
limit: Math.abs(~~this.props.limit)
|
||||||
|
}, function() {
|
||||||
this.getItems();
|
this.getItems();
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
this.getItems();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getItems: function() {
|
getItems: function() {
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
@ -504,6 +522,7 @@ define(
|
|||||||
var bulk_actions = this.props.bulk_actions || [];
|
var bulk_actions = this.props.bulk_actions || [];
|
||||||
|
|
||||||
if(this.state.group === 'trash') {
|
if(this.state.group === 'trash') {
|
||||||
|
|
||||||
bulk_actions = [
|
bulk_actions = [
|
||||||
{
|
{
|
||||||
name: 'restore',
|
name: 'restore',
|
||||||
@ -531,15 +550,34 @@ define(
|
|||||||
'striped',
|
'striped',
|
||||||
{ 'mailpoet_listing_loading': this.state.loading }
|
{ 'mailpoet_listing_loading': this.state.loading }
|
||||||
);
|
);
|
||||||
return (
|
|
||||||
<div>
|
// search
|
||||||
|
var search = (
|
||||||
|
<ListingSearch
|
||||||
|
onSearch={ this.handleSearch }
|
||||||
|
search={ this.state.search }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
if(this.props.search === false) {
|
||||||
|
search = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// groups
|
||||||
|
var groups = (
|
||||||
<ListingGroups
|
<ListingGroups
|
||||||
groups={ this.state.groups }
|
groups={ this.state.groups }
|
||||||
group={ this.state.group }
|
group={ this.state.group }
|
||||||
onSelectGroup={ this.handleGroup } />
|
onSelectGroup={ this.handleGroup }
|
||||||
<ListingSearch
|
/>
|
||||||
onSearch={ this.handleSearch }
|
);
|
||||||
search={ this.state.search } />
|
if(this.props.groups === false) {
|
||||||
|
groups = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{ groups }
|
||||||
|
{ search }
|
||||||
<div className="tablenav top clearfix">
|
<div className="tablenav top clearfix">
|
||||||
<ListingBulkActions
|
<ListingBulkActions
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
|
@ -40,23 +40,23 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
if(this.props.count === 0) {
|
if(this.props.count === 0) {
|
||||||
return (<div></div>);
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var pagination,
|
var pagination = false;
|
||||||
firstPage = (
|
var firstPage = (
|
||||||
<span aria-hidden="true" className="tablenav-pages-navspan">«</span>
|
<span aria-hidden="true" className="tablenav-pages-navspan">«</span>
|
||||||
),
|
);
|
||||||
previousPage = (
|
var previousPage = (
|
||||||
<span aria-hidden="true" className="tablenav-pages-navspan">‹</span>
|
<span aria-hidden="true" className="tablenav-pages-navspan">‹</span>
|
||||||
),
|
);
|
||||||
nextPage = (
|
var nextPage = (
|
||||||
<span aria-hidden="true" className="tablenav-pages-navspan">›</span>
|
<span aria-hidden="true" className="tablenav-pages-navspan">›</span>
|
||||||
),
|
);
|
||||||
lastPage = (
|
var lastPage = (
|
||||||
<span aria-hidden="true" className="tablenav-pages-navspan">»</span>
|
<span aria-hidden="true" className="tablenav-pages-navspan">»</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
if(this.props.count > this.props.limit) {
|
if(this.props.limit > 0 && this.props.count > this.props.limit) {
|
||||||
if(this.props.page > 1) {
|
if(this.props.page > 1) {
|
||||||
previousPage = (
|
previousPage = (
|
||||||
<a href="javascript:;"
|
<a href="javascript:;"
|
||||||
|
@ -8,6 +8,9 @@ define(['react'], function(React) {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
|
if(this.props.search === false) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
<form name="search" onSubmit={this.handleSearch}>
|
<form name="search" onSubmit={this.handleSearch}>
|
||||||
<p className="search-box">
|
<p className="search-box">
|
||||||
@ -28,6 +31,7 @@ define(['react'], function(React) {
|
|||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ListingSearch;
|
return ListingSearch;
|
||||||
|
@ -17,6 +17,11 @@ define(
|
|||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
type: 'text'
|
type: 'text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
type: 'textarea'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -18,21 +18,99 @@ define(
|
|||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'created_at',
|
name: 'description',
|
||||||
label: 'Created on',
|
label: 'Description',
|
||||||
sortable: true
|
sortable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'updated_at',
|
name: 'subscribed',
|
||||||
label: 'Last modified on',
|
label: 'Subscribed',
|
||||||
|
sortable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unconfirmed',
|
||||||
|
label: 'Unconfirmed',
|
||||||
|
sortable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unsubscribed',
|
||||||
|
label: 'Unsubscribed',
|
||||||
|
sortable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'created_at',
|
||||||
|
label: 'Created on',
|
||||||
sortable: true
|
sortable: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var messages = {
|
||||||
|
onDelete: function(response) {
|
||||||
|
var count = ~~response.segments;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1) {
|
||||||
|
message = (
|
||||||
|
'1 segment was moved to the trash.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d segments were moved to the trash.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message !== null) {
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onConfirmDelete: function(response) {
|
||||||
|
var count = ~~response.segments;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1) {
|
||||||
|
message = (
|
||||||
|
'1 segment was permanently deleted.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d segments were permanently deleted.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message !== null) {
|
||||||
|
MailPoet.Notice.success(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRestore: function(response) {
|
||||||
|
var count = ~~response.segments;
|
||||||
|
var message = null;
|
||||||
|
|
||||||
|
if(count === 1) {
|
||||||
|
message = (
|
||||||
|
'1 segment has been restored from the trash.'
|
||||||
|
).replace('%$1d', count);
|
||||||
|
} else if(count > 1) {
|
||||||
|
message = (
|
||||||
|
'%$1d segments 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
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -54,11 +132,20 @@ define(
|
|||||||
</strong>
|
</strong>
|
||||||
{ actions }
|
{ actions }
|
||||||
</td>
|
</td>
|
||||||
<td className="column-date" data-colname="Subscribed on">
|
<td className="column-date" data-colname="Description">
|
||||||
<abbr>{ segment.created_at }</abbr>
|
<abbr>{ segment.description }</abbr>
|
||||||
</td>
|
</td>
|
||||||
<td className="column-date" data-colname="Last modified on">
|
<td className="column-date" data-colname="Subscribed">
|
||||||
<abbr>{ segment.updated_at }</abbr>
|
<abbr>{ segment.subscribed || 0 }</abbr>
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname="Unconfirmed">
|
||||||
|
<abbr>{ segment.unconfirmed || 0 }</abbr>
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname="Unsubscribed">
|
||||||
|
<abbr>{ segment.unsubscribed || 0 }</abbr>
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname="Created on">
|
||||||
|
<abbr>{ segment.created_at }</abbr>
|
||||||
</td>
|
</td>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -71,9 +158,12 @@ define(
|
|||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<Listing
|
<Listing
|
||||||
|
messages={ messages }
|
||||||
|
search={ false }
|
||||||
|
limit={ 0 }
|
||||||
endpoint="segments"
|
endpoint="segments"
|
||||||
onRenderItem={this.renderItem}
|
onRenderItem={ this.renderItem }
|
||||||
columns={columns}
|
columns={ columns }
|
||||||
bulk_actions={ bulk_actions } />
|
bulk_actions={ bulk_actions } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -107,6 +107,7 @@ class Migrator {
|
|||||||
$attributes = array(
|
$attributes = array(
|
||||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||||
'name varchar(90) NOT NULL,',
|
'name varchar(90) NOT NULL,',
|
||||||
|
'description varchar(250) NOT NULL,',
|
||||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||||
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
||||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||||
|
@ -86,14 +86,19 @@ class Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
$items = $this->model;
|
||||||
|
if($this->data['limit'] > 0) {
|
||||||
|
$items = $items
|
||||||
|
->offset($this->data['offset'])
|
||||||
|
->limit($this->data['limit']);
|
||||||
|
} else
|
||||||
|
$items = $items->findArray();
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'count' => $this->model->count(),
|
'count' => $this->model->count(),
|
||||||
'filters' => $this->model->filter('filters'),
|
'filters' => $this->model->filter('filters'),
|
||||||
'groups' => $this->model->filter('groups'),
|
'groups' => $this->model->filter('groups'),
|
||||||
'items' => $this->model
|
'items' => $items
|
||||||
->offset($this->data['offset'])
|
|
||||||
->limit($this->data['limit'])
|
|
||||||
->findArray()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,6 +14,13 @@ class Segment extends Model {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delete() {
|
||||||
|
// delete all relations to subscribers
|
||||||
|
SubscriberSegment::where('segment_id', $this->id)->deleteMany();
|
||||||
|
|
||||||
|
return parent::delete();
|
||||||
|
}
|
||||||
|
|
||||||
function subscribers() {
|
function subscribers() {
|
||||||
return $this->has_many_through(
|
return $this->has_many_through(
|
||||||
__NAMESPACE__.'\Subscriber',
|
__NAMESPACE__.'\Subscriber',
|
||||||
@ -41,12 +48,22 @@ class Segment extends Model {
|
|||||||
array(
|
array(
|
||||||
'name' => 'all',
|
'name' => 'all',
|
||||||
'label' => __('All'),
|
'label' => __('All'),
|
||||||
'count' => Segment::count()
|
'count' => Segment::whereNull('deleted_at')->count()
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'trash',
|
||||||
|
'label' => __('Trash'),
|
||||||
|
'count' => Segment::whereNotNull('deleted_at')->count()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function group($orm, $group = null) {
|
static function groupBy($orm, $group = null) {
|
||||||
|
if($group === 'trash') {
|
||||||
|
return $orm->whereNotNull('deleted_at');
|
||||||
|
} else {
|
||||||
|
$orm = $orm->whereNull('deleted_at');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function createOrUpdate($data = array()) {
|
static function createOrUpdate($data = array()) {
|
||||||
@ -77,7 +94,45 @@ class Segment extends Model {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function trash($listing) {
|
static function trash($listing, $data = array()) {
|
||||||
return $listing->getSelection()->deleteMany();
|
$confirm_delete = filter_var($data['confirm'], FILTER_VALIDATE_BOOLEAN);
|
||||||
|
if($confirm_delete) {
|
||||||
|
// delete relations with all segments
|
||||||
|
$segments = $listing->getSelection()->findResultSet();
|
||||||
|
|
||||||
|
if(!empty($segments)) {
|
||||||
|
$segments_count = 0;
|
||||||
|
foreach($segments as $segment) {
|
||||||
|
if($segment->delete()) {
|
||||||
|
$segments_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'segments' => $segments_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// soft delete
|
||||||
|
$segments = $listing->getSelection()
|
||||||
|
->findResultSet()
|
||||||
|
->set_expr('deleted_at', 'NOW()')
|
||||||
|
->save();
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'segments' => $segments->count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static function restore($listing, $data = array()) {
|
||||||
|
$segments = $listing->getSelection()
|
||||||
|
->findResultSet()
|
||||||
|
->set_expr('deleted_at', 'NULL')
|
||||||
|
->save();
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'segments' => $segments->count()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class Subscriber extends Model {
|
|||||||
// delete all relations to segments
|
// delete all relations to segments
|
||||||
SubscriberSegment::where('subscriber_id', $this->id)->deleteMany();
|
SubscriberSegment::where('subscriber_id', $this->id)->deleteMany();
|
||||||
|
|
||||||
parent::delete();
|
return parent::delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function search($orm, $search = '') {
|
static function search($orm, $search = '') {
|
||||||
|
@ -43,14 +43,31 @@ class Segments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete($id) {
|
function restore($id) {
|
||||||
$segment = Segment::findOne($id);
|
$segment = Segment::findOne($id);
|
||||||
if($segment !== false) {
|
if($segment !== false) {
|
||||||
$result = $segment->delete();
|
$segment->set_expr('deleted_at', 'NULL');
|
||||||
|
$result = array('segments' => (int)$segment->save());
|
||||||
} else {
|
} else {
|
||||||
$result = false;
|
$result = false;
|
||||||
}
|
}
|
||||||
|
wp_send_json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($data = array()) {
|
||||||
|
$segment = Segment::findOne($data['id']);
|
||||||
|
$confirm_delete = filter_var($data['confirm'], FILTER_VALIDATE_BOOLEAN);
|
||||||
|
if($segment !== false) {
|
||||||
|
if($confirm_delete) {
|
||||||
|
$segment->delete();
|
||||||
|
$result = array('segments' => 1);
|
||||||
|
} else {
|
||||||
|
$segment->set_expr('deleted_at', 'NOW()');
|
||||||
|
$result = array('segments' => (int)$segment->save());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
wp_send_json($result);
|
wp_send_json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user