listing modifications + added description to segments
This commit is contained in:
@ -19,6 +19,8 @@ a:focus
|
||||
|
||||
// select 2
|
||||
.select2-container
|
||||
// textareas
|
||||
textarea.regular-text
|
||||
width: 25em !important
|
||||
|
||||
@media screen and (max-width: 782px)
|
||||
|
@ -70,10 +70,21 @@ define(
|
||||
|
||||
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({
|
||||
endpoint: this.props.endpoint,
|
||||
action: 'save',
|
||||
data: this.state.item
|
||||
data: item
|
||||
}).done(function(response) {
|
||||
this.setState({ loading: false });
|
||||
|
||||
|
@ -266,8 +266,26 @@ define(
|
||||
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() {
|
||||
if(this.props.limit !== undefined) {
|
||||
this.setState({
|
||||
limit: Math.abs(~~this.props.limit)
|
||||
}, function() {
|
||||
this.getItems();
|
||||
}.bind(this));
|
||||
} else {
|
||||
this.getItems();
|
||||
}
|
||||
},
|
||||
getItems: function() {
|
||||
this.setState({ loading: true });
|
||||
@ -504,6 +522,7 @@ define(
|
||||
var bulk_actions = this.props.bulk_actions || [];
|
||||
|
||||
if(this.state.group === 'trash') {
|
||||
|
||||
bulk_actions = [
|
||||
{
|
||||
name: 'restore',
|
||||
@ -531,15 +550,34 @@ define(
|
||||
'striped',
|
||||
{ '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
|
||||
groups={ this.state.groups }
|
||||
group={ this.state.group }
|
||||
onSelectGroup={ this.handleGroup } />
|
||||
<ListingSearch
|
||||
onSearch={ this.handleSearch }
|
||||
search={ this.state.search } />
|
||||
onSelectGroup={ this.handleGroup }
|
||||
/>
|
||||
);
|
||||
if(this.props.groups === false) {
|
||||
groups = false;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ groups }
|
||||
{ search }
|
||||
<div className="tablenav top clearfix">
|
||||
<ListingBulkActions
|
||||
bulk_actions={ bulk_actions }
|
||||
|
@ -40,23 +40,23 @@ define(['react', 'classnames'], function(React, classNames) {
|
||||
},
|
||||
render: function() {
|
||||
if(this.props.count === 0) {
|
||||
return (<div></div>);
|
||||
return false;
|
||||
} else {
|
||||
var pagination,
|
||||
firstPage = (
|
||||
var pagination = false;
|
||||
var firstPage = (
|
||||
<span aria-hidden="true" className="tablenav-pages-navspan">«</span>
|
||||
),
|
||||
previousPage = (
|
||||
);
|
||||
var previousPage = (
|
||||
<span aria-hidden="true" className="tablenav-pages-navspan">‹</span>
|
||||
),
|
||||
nextPage = (
|
||||
);
|
||||
var nextPage = (
|
||||
<span aria-hidden="true" className="tablenav-pages-navspan">›</span>
|
||||
),
|
||||
lastPage = (
|
||||
);
|
||||
var lastPage = (
|
||||
<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) {
|
||||
previousPage = (
|
||||
<a href="javascript:;"
|
||||
|
@ -8,6 +8,9 @@ define(['react'], function(React) {
|
||||
);
|
||||
},
|
||||
render: function() {
|
||||
if(this.props.search === false) {
|
||||
return false;
|
||||
} else {
|
||||
return (
|
||||
<form name="search" onSubmit={this.handleSearch}>
|
||||
<p className="search-box">
|
||||
@ -28,6 +31,7 @@ define(['react'], function(React) {
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ListingSearch;
|
||||
|
@ -17,6 +17,11 @@ define(
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
type: 'text'
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
type: 'textarea'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -18,21 +18,99 @@ define(
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: 'Created on',
|
||||
sortable: true
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name: 'updated_at',
|
||||
label: 'Last modified on',
|
||||
name: 'subscribed',
|
||||
label: 'Subscribed',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name: 'unconfirmed',
|
||||
label: 'Unconfirmed',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name: 'unsubscribed',
|
||||
label: 'Unsubscribed',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: 'Created on',
|
||||
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 = [
|
||||
{
|
||||
name: 'trash',
|
||||
label: 'Trash'
|
||||
label: 'Trash',
|
||||
getData: function() {
|
||||
return {
|
||||
confirm: false
|
||||
}
|
||||
},
|
||||
onSuccess: messages.onDelete
|
||||
}
|
||||
];
|
||||
|
||||
@ -54,11 +132,20 @@ define(
|
||||
</strong>
|
||||
{ actions }
|
||||
</td>
|
||||
<td className="column-date" data-colname="Subscribed on">
|
||||
<abbr>{ segment.created_at }</abbr>
|
||||
<td className="column-date" data-colname="Description">
|
||||
<abbr>{ segment.description }</abbr>
|
||||
</td>
|
||||
<td className="column-date" data-colname="Last modified on">
|
||||
<abbr>{ segment.updated_at }</abbr>
|
||||
<td className="column-date" data-colname="Subscribed">
|
||||
<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>
|
||||
</div>
|
||||
);
|
||||
@ -71,6 +158,9 @@ define(
|
||||
</h2>
|
||||
|
||||
<Listing
|
||||
messages={ messages }
|
||||
search={ false }
|
||||
limit={ 0 }
|
||||
endpoint="segments"
|
||||
onRenderItem={ this.renderItem }
|
||||
columns={ columns }
|
||||
|
@ -107,6 +107,7 @@ class Migrator {
|
||||
$attributes = array(
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'name varchar(90) NOT NULL,',
|
||||
'description varchar(250) NOT NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||
'deleted_at TIMESTAMP NULL DEFAULT NULL,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
|
@ -86,14 +86,19 @@ class Handler {
|
||||
}
|
||||
|
||||
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(
|
||||
'count' => $this->model->count(),
|
||||
'filters' => $this->model->filter('filters'),
|
||||
'groups' => $this->model->filter('groups'),
|
||||
'items' => $this->model
|
||||
->offset($this->data['offset'])
|
||||
->limit($this->data['limit'])
|
||||
->findArray()
|
||||
'items' => $items
|
||||
);
|
||||
}
|
||||
}
|
@ -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() {
|
||||
return $this->has_many_through(
|
||||
__NAMESPACE__.'\Subscriber',
|
||||
@ -41,12 +48,22 @@ class Segment extends Model {
|
||||
array(
|
||||
'name' => '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()) {
|
||||
@ -77,7 +94,45 @@ class Segment extends Model {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function trash($listing) {
|
||||
return $listing->getSelection()->deleteMany();
|
||||
static function trash($listing, $data = array()) {
|
||||
$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
|
||||
SubscriberSegment::where('subscriber_id', $this->id)->deleteMany();
|
||||
|
||||
parent::delete();
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
static function search($orm, $search = '') {
|
||||
|
@ -43,14 +43,31 @@ class Segments {
|
||||
}
|
||||
}
|
||||
|
||||
function delete($id) {
|
||||
function restore($id) {
|
||||
$segment = Segment::findOne($id);
|
||||
if($segment !== false) {
|
||||
$result = $segment->delete();
|
||||
$segment->set_expr('deleted_at', 'NULL');
|
||||
$result = array('segments' => (int)$segment->save());
|
||||
} else {
|
||||
$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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user