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:
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
);
|
||||
},
|
||||
|
Reference in New Issue
Block a user