listing modifications + added description to segments

This commit is contained in:
Jonathan Labreuille
2015-10-22 19:19:40 +02:00
parent b9b17a59a3
commit 4bde705f04
12 changed files with 289 additions and 61 deletions

View File

@ -19,6 +19,8 @@ a:focus
// select 2
.select2-container
// textareas
textarea.regular-text
width: 25em !important
@media screen and (max-width: 782px)

View File

@ -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 });

View File

@ -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 }

View File

@ -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:;"

View File

@ -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;

View File

@ -17,6 +17,11 @@ define(
name: 'name',
label: 'Name',
type: 'text'
},
{
name: 'description',
label: 'Description',
type: 'textarea'
}
];

View File

@ -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 }

View File

@ -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,',

View File

@ -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
);
}
}

View File

@ -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()
);
}
}

View File

@ -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 = '') {

View File

@ -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);
}