Conditional display of statistics column (for standard)

- improved duplicate action (for standard)
- moved STATUS_COMPLETED constant from worker to SendingQueue model where it belongs
This commit is contained in:
Jonathan Labreuille
2016-06-14 13:18:27 +02:00
parent cabfd8a946
commit ee6e261c42
10 changed files with 209 additions and 109 deletions

View File

@@ -676,6 +676,12 @@ define(
sort_by = this.state.sort_by,
sort_order = this.state.sort_order;
// columns
var columns = this.props.columns || [];
columns = columns.filter(function(column) {
return (column.display === undefined || !!(column.display) === true);
});
// bulk actions
var bulk_actions = this.props.bulk_actions || [];
@@ -761,7 +767,7 @@ define(
selection={ this.state.selection }
sort_by={ sort_by }
sort_order={ sort_order }
columns={ this.props.columns }
columns={ columns }
is_selectable={ bulk_actions.length > 0 } />
</thead>
@@ -771,7 +777,7 @@ define(
onRestoreItem={ this.handleRestoreItem }
onTrashItem={ this.handleTrashItem }
onRefreshItems={ this.handleRefreshItems }
columns={ this.props.columns }
columns={ columns }
is_selectable={ bulk_actions.length > 0 }
onSelectItem={ this.handleSelectItem }
onSelectAll={ this.handleSelectAll }
@@ -791,7 +797,7 @@ define(
selection={ this.state.selection }
sort_by={ sort_by }
sort_order={ sort_order }
columns={ this.props.columns }
columns={ columns }
is_selectable={ bulk_actions.length > 0 } />
</tfoot>

View File

@@ -68,17 +68,12 @@ var columns = [
label: MailPoet.I18n.t('status')
},
{
name: 'segments',
label: MailPoet.I18n.t('lists')
name: 'settings',
label: MailPoet.I18n.t('settings')
},
{
name: 'statistics',
label: MailPoet.I18n.t('statistics')
},
{
name: 'created_at',
label: MailPoet.I18n.t('createdOn'),
sortable: true
name: 'history',
label: MailPoet.I18n.t('history')
},
{
name: 'updated_at',
@@ -96,6 +91,16 @@ var bulk_actions = [
];
var newsletter_actions = [
{
name: 'view',
link: function(newsletter) {
return (
<a href={ newsletter.preview_url } target="_blank">
{MailPoet.I18n.t('preview')}
</a>
);
}
},
{
name: 'edit',
link: function(newsletter) {
@@ -106,6 +111,26 @@ var newsletter_actions = [
);
}
},
{
name: 'duplicate',
label: MailPoet.I18n.t('duplicate'),
onClick: function(newsletter, refresh) {
return MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'duplicate',
data: newsletter.id
}).done(function(response) {
if (response !== false && response.subject !== undefined) {
MailPoet.Notice.success(
(MailPoet.I18n.t('newsletterDuplicated')).replace(
'%$1s', response.subject
)
);
}
refresh();
});
}
},
{
name: 'trash'
}
@@ -158,31 +183,6 @@ const NewsletterListNotification = React.createClass({
</span>
);
},
renderStatistics: function(newsletter) {
if (!newsletter.statistics || !newsletter.queue || newsletter.queue.count_processed == 0 || newsletter.queue.status === 'scheduled') {
return (
<span>
{MailPoet.I18n.t('notSentYet')}
</span>
);
}
var percentage_clicked = Math.round(
(newsletter.statistics.clicked * 100) / (newsletter.queue.count_processed)
);
var percentage_opened = Math.round(
(newsletter.statistics.opened * 100) / (newsletter.queue.count_processed)
);
var percentage_unsubscribed = Math.round(
(newsletter.statistics.unsubscribed * 100) / (newsletter.queue.count_processed)
);
return (
<span>
{ percentage_opened }%, { percentage_clicked }%, { percentage_unsubscribed }%
</span>
);
},
renderItem: function(newsletter, actions) {
var rowClasses = classNames(
'manage-column',
@@ -190,10 +190,6 @@ const NewsletterListNotification = React.createClass({
'has-row-actions'
);
var segments = newsletter.segments.map(function(segment) {
return segment.name
}).join(', ');
return (
<div>
<td className={ rowClasses }>
@@ -207,14 +203,11 @@ const NewsletterListNotification = React.createClass({
<td className="column" data-colname={ MailPoet.I18n.t('status') }>
{ this.renderStatus(newsletter) }
</td>
<td className="column" data-colname={ MailPoet.I18n.t('lists') }>
{ segments }
<td className="column" data-colname={ MailPoet.I18n.t('settings') }>
{ this.renderSettings(newsletter) }
</td>
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
{ this.renderStatistics(newsletter) }
</td>
<td className="column-date" data-colname={ MailPoet.I18n.t('createdOn') }>
<abbr>{ MailPoet.Date.format(newsletter.created_at) }</abbr>
<td className="column" data-colname={ MailPoet.I18n.t('history') }>
<a href="#TODO">{ MailPoet.I18n.t('viewHistory') }</a>
</td>
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>
<abbr>{ MailPoet.Date.format(newsletter.updated_at) }</abbr>

View File

@@ -9,6 +9,8 @@ import classNames from 'classnames'
import jQuery from 'jquery'
import MailPoet from 'mailpoet'
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
const messages = {
onTrash(response) {
const count = ~~response;
@@ -73,7 +75,8 @@ var columns = [
},
{
name: 'statistics',
label: MailPoet.I18n.t('statistics')
label: MailPoet.I18n.t('statistics'),
display: mailpoet_tracking_enabled
},
{
name: 'updated_at',
@@ -82,6 +85,7 @@ var columns = [
}
];
var bulk_actions = [
{
name: 'trash',
@@ -231,30 +235,33 @@ const NewsletterListStandard = React.createClass({
);
}
},
renderStatistics: function(item) {
if(!item.statistics || !item.queue || item.queue.count_processed == 0 || item.queue.status === 'scheduled') {
return (
<span>
{MailPoet.I18n.t('notSentYet')}
</span>
);
renderStatistics: function(newsletter) {
if (mailpoet_tracking_enabled === false) {
return;
}
var percentage_clicked = Math.round(
(item.statistics.clicked * 100) / (item.queue.count_processed)
);
var percentage_opened = Math.round(
(item.statistics.opened * 100) / (item.queue.count_processed)
);
var percentage_unsubscribed = Math.round(
(item.statistics.unsubscribed * 100) / (item.queue.count_processed)
);
if(newsletter.statistics && newsletter.queue && newsletter.queue.status !== 'scheduled') {
const total_sent = ~~(newsletter.queue.count_processed);
const percentage_clicked = Math.round(
(~~(newsletter.statistics.clicked) * 100) / total_sent
);
const percentage_opened = Math.round(
(~~(newsletter.statistics.opened) * 100) / total_sent
);
const percentage_unsubscribed = Math.round(
(~~(newsletter.statistics.unsubscribed) * 100) / total_sent
);
return (
<span>
{ percentage_opened }%, { percentage_clicked }%, { percentage_unsubscribed }%
</span>
);
return (
<span>
{ percentage_opened }%, { percentage_clicked }%, { percentage_unsubscribed }%
</span>
);
} else {
return (
<span>{MailPoet.I18n.t('notSentYet')}</span>
);
}
},
renderItem: function(newsletter, actions) {
var rowClasses = classNames(
@@ -283,9 +290,11 @@ const NewsletterListStandard = React.createClass({
<td className="column" data-colname={ MailPoet.I18n.t('lists') }>
{ segments }
</td>
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
{ this.renderStatistics(newsletter) }
</td>
{(mailpoet_tracking_enabled === true) ? (
<td className="column" data-colname={ MailPoet.I18n.t('statistics') }>
{ this.renderStatistics(newsletter) }
</td>
) : null }
<td className="column-date" data-colname={ MailPoet.I18n.t('lastModifiedOn') }>
<abbr>{ MailPoet.Date.format(newsletter.updated_at) }</abbr>
</td>

View File

@@ -8,6 +8,7 @@ import ListingTabs from 'newsletters/listings/tabs.jsx'
import classNames from 'classnames'
import jQuery from 'jquery'
import MailPoet from 'mailpoet'
import _ from 'underscore'
const messages = {
onTrash(response) {
@@ -165,21 +166,48 @@ const NewsletterListWelcome = React.createClass({
}.bind(this));
},
renderStatus: function(newsletter) {
let total_sent;
total_sent = (
MailPoet.I18n.t('sentToXSubscribers')
.replace('%$1d', newsletter.total_sent)
);
return (
<select
data-id={ newsletter.id }
defaultValue={ newsletter.status }
onChange={ this.updateStatus }
>
<option value="active">{ MailPoet.I18n.t('active') }</option>
<option value="draft">{ MailPoet.I18n.t('inactive') }</option>
</select>
<div>
<select
data-id={ newsletter.id }
defaultValue={ newsletter.status }
onChange={ this.updateStatus }
>
<option value="active">{ MailPoet.I18n.t('active') }</option>
<option value="draft">{ MailPoet.I18n.t('inactive') }</option>
</select>
<p>{ total_sent }</p>
</div>
);
},
renderSettings: function(newsletter) {
let settings;
switch (newsletter.options.event) {
case 'user':
// WP User
settings = MailPoet.I18n.t('onWordpressUserRegistration');
break;
case 'segment':
// get segment
const segment = _.find(mailpoet_segments, function(segment) {
return (~~(segment.id) === ~~(newsletter.options.segment));
});
settings = MailPoet.I18n.t('onSubscriptionToList') + ' ' +segment.name;
break;
}
return (
<span>
Settings...
{ settings }
</span>
);
},