Sorting for all listings & bugfixes for all listings except Newsletters

- newsletters listing now uses hash history
- newsletters are sorted by Subject (a->z)
- segments are sorted by Name (a->z)
- re-added WordPress Users list as a segment you can send a newsletter to
- added explicit error messages when an auto newsletter isn't fully configured
- added missing strings for "selectAll" in Segments listing
- fixed filters() in Subscribers listing (wrong count as it was not taking groups/filters/search into account)
This commit is contained in:
Jonathan Labreuille
2016-06-20 16:23:27 +02:00
parent 7af2775972
commit 68c09b8678
15 changed files with 136 additions and 95 deletions

View File

@@ -13,8 +13,7 @@ const columns = [
},
{
name: 'segments',
label: MailPoet.I18n.t('segments'),
sortable: false
label: MailPoet.I18n.t('segments')
},
{
name: 'created_at',

View File

@@ -379,21 +379,26 @@ const Listing = React.createClass({
)
})
.map(key => {
let value = this.state[key]
let value = this.state[key];
if (value === Object(value)) {
value = jQuery.param(value)
} else if (value === Boolean(value)) {
value = value.toString()
}
if (value !== '') {
if (value !== '' && value !== null) {
return `${key}[${value}]`
}
})
.filter(key => { return (key !== undefined) })
.join('/');
params = '/' + params;
// prepend with tab is specified
if (this.props.tab !== undefined) {
params = `/${ this.props.tab }/${ params }`;
} else {
params = `/${ params }`;
}
if (this.props.location) {
if (this.props.location.pathname !== params) {

View File

@@ -189,53 +189,62 @@ const NewsletterListNotification = React.createClass({
let sendingFrequency;
let sendingToSegments;
// set sending frequency
switch (newsletter.options.intervalType) {
case 'daily':
sendingFrequency = MailPoet.I18n.t('sendDaily').replace(
'%$1s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'weekly':
sendingFrequency = MailPoet.I18n.t('sendWeekly').replace(
'%$1s', weekDayValues[newsletter.options.weekDay]
).replace(
'%$2s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'monthly':
sendingFrequency = MailPoet.I18n.t('sendMonthly').replace(
'%$1s', monthDayValues[newsletter.options.monthDay]
).replace(
'%$2s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'nthWeekDay':
sendingFrequency = MailPoet.I18n.t('sendNthWeekDay').replace(
'%$1s', nthWeekDayValues[newsletter.options.nthWeekDay]
).replace(
'%$2s', weekDayValues[newsletter.options.weekDay]
).replace(
'%$3s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'immediately':
sendingFrequency = MailPoet.I18n.t('sendImmediately');
break;
}
// set segments
// get list of segments' name
const segments = newsletter.segments.map(function(segment) {
return segment.name
}).join(', ');
});
sendingToSegments = MailPoet.I18n.t('ifNewContentToSegments').replace(
'%$1s', segments
);
// check if the user has specified segments to send to
if(segments.length === 0) {
return (
<span className="mailpoet_error">
{ MailPoet.I18n.t('sendingToSegmentsNotSpecified') }
</span>
);
} else {
sendingToSegments = MailPoet.I18n.t('ifNewContentToSegments').replace(
'%$1s', segments.join(', ')
);
// set sending frequency
switch (newsletter.options.intervalType) {
case 'daily':
sendingFrequency = MailPoet.I18n.t('sendDaily').replace(
'%$1s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'weekly':
sendingFrequency = MailPoet.I18n.t('sendWeekly').replace(
'%$1s', weekDayValues[newsletter.options.weekDay]
).replace(
'%$2s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'monthly':
sendingFrequency = MailPoet.I18n.t('sendMonthly').replace(
'%$1s', monthDayValues[newsletter.options.monthDay]
).replace(
'%$2s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'nthWeekDay':
sendingFrequency = MailPoet.I18n.t('sendNthWeekDay').replace(
'%$1s', nthWeekDayValues[newsletter.options.nthWeekDay]
).replace(
'%$2s', weekDayValues[newsletter.options.weekDay]
).replace(
'%$3s', timeOfDayValues[newsletter.options.timeOfDay]
);
break;
case 'immediately':
sendingFrequency = MailPoet.I18n.t('sendImmediately');
break;
}
}
return (
<span>
@@ -286,6 +295,7 @@ const NewsletterListNotification = React.createClass({
<Listing
limit={ mailpoet_listing_per_page }
location={ this.props.location }
params={ this.props.params }
endpoint="newsletters"
tab="notification"
@@ -295,6 +305,8 @@ const NewsletterListNotification = React.createClass({
item_actions={ newsletter_actions }
messages={ messages }
auto_refresh={ true }
sort_by="subject"
sort_order="asc"
/>
</div>
);

View File

@@ -1,14 +1,12 @@
import React from 'react'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import Listing from 'listing/listing.jsx'
import ListingTabs from 'newsletters/listings/tabs.jsx'
import { Router, Link } from 'react-router'
import classNames from 'classnames'
import jQuery from 'jquery'
import MailPoet from 'mailpoet'
import Listing from 'listing/listing.jsx'
import ListingTabs from 'newsletters/listings/tabs.jsx'
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
const messages = {
@@ -319,6 +317,7 @@ const NewsletterListStandard = React.createClass({
<Listing
limit={ mailpoet_listing_per_page }
location={ this.props.location }
params={ this.props.params }
endpoint="newsletters"
tab="standard"
@@ -328,6 +327,8 @@ const NewsletterListStandard = React.createClass({
item_actions={ newsletter_actions }
messages={ messages }
auto_refresh={ true }
sort_by="subject"
sort_order="asc"
/>
</div>
);

View File

@@ -11,6 +11,7 @@ import MailPoet from 'mailpoet'
import _ from 'underscore'
const mailpoet_roles = window.mailpoet_roles || {};
const mailpoet_segments = window.mailpoet_segments || {};
const mailpoet_tracking_enabled = (!!(window['mailpoet_tracking_enabled']));
const messages = {
@@ -216,39 +217,51 @@ const NewsletterListWelcome = React.createClass({
return (~~(segment.id) === ~~(newsletter.options.segment));
});
sendingEvent = MailPoet.I18n.t('welcomeEventSegment').replace(
if (segment === undefined) {
return (
<span className="mailpoet_error">
{ MailPoet.I18n.t('sendingToSegmentsNotSpecified') }
</span>
);
} else {
sendingEvent = MailPoet.I18n.t('welcomeEventSegment').replace(
'%$1s', segment.name
);
}
break;
}
// set sending delay
if (newsletter.options.afterTimeType !== 'immediate') {
switch (newsletter.options.afterTimeType) {
case 'hours':
sendingDelay = MailPoet.I18n.t('sendingDelayHours').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
if (sendingEvent) {
if (newsletter.options.afterTimeType !== 'immediate') {
switch (newsletter.options.afterTimeType) {
case 'hours':
sendingDelay = MailPoet.I18n.t('sendingDelayHours').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
case 'days':
sendingDelay = MailPoet.I18n.t('sendingDelayDays').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
case 'days':
sendingDelay = MailPoet.I18n.t('sendingDelayDays').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
case 'weeks':
sendingDelay = MailPoet.I18n.t('sendingDelayWeeks').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
case 'weeks':
sendingDelay = MailPoet.I18n.t('sendingDelayWeeks').replace(
'%$1d', newsletter.options.afterTimeNumber
);
break;
}
sendingEvent += ' [' + sendingDelay + ']';
}
sendingEvent += ' [' + sendingDelay + ']';
// add a "period" at the end if we do have a sendingEvent
sendingEvent += '.';
}
return (
<span>
{ sendingEvent }.
{ sendingEvent }
</span>
);
},
@@ -326,6 +339,7 @@ const NewsletterListWelcome = React.createClass({
<Listing
limit={ mailpoet_listing_per_page }
location={ this.props.location }
params={ this.props.params }
endpoint="newsletters"
tab="welcome"
@@ -335,6 +349,8 @@ const NewsletterListWelcome = React.createClass({
item_actions={ newsletter_actions }
messages={ messages }
auto_refresh={ true }
sort_by="subject"
sort_order="asc"
/>
</div>
);

View File

@@ -1,6 +1,6 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { Router, Route, IndexRedirect, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import NewsletterTypes from 'newsletters/types.jsx'
@@ -29,11 +29,14 @@ if(container) {
ReactDOM.render((
<Router history={ history }>
<Route path="/" component={ App }>
<IndexRoute component={ NewsletterListStandard } />
<IndexRedirect to="standard" />
{/* Listings */}
<Route name="listing/standard" path="standard" component={ NewsletterListStandard } />
<Route name="listing/welcome" path="welcome" component={ NewsletterListWelcome } />
<Route name="listing/notification" path="notification" component={ NewsletterListNotification } />
<Route path="standard/*" component={ NewsletterListStandard } />
<Route path="welcome/*" component={ NewsletterListWelcome } />
<Route path="notification/*" component={ NewsletterListNotification } />
{/* Newsletter: type selection */}
<Route path="new" component={ NewsletterTypes } />
{/* New newsletter: types */}
@@ -44,8 +47,6 @@ if(container) {
<Route name="template" path="template/:id" component={ NewsletterTemplates } />
{/* Sending options */}
<Route path="send/:id" component={ NewsletterSend } />
<Route path="*" component={ NewsletterListStandard } />
</Route>
</Router>
), container);

View File

@@ -1,6 +1,5 @@
import React from 'react'
import { Router, Link } from 'react-router'
import jQuery from 'jquery'
import MailPoet from 'mailpoet'
import classNames from 'classnames'
@@ -15,23 +14,19 @@ var columns = [
},
{
name: 'description',
label: MailPoet.I18n.t('description'),
sortable: false
label: MailPoet.I18n.t('description')
},
{
name: 'subscribed',
label: MailPoet.I18n.t('subscribed'),
sortable: false
label: MailPoet.I18n.t('subscribed')
},
{
name: 'unconfirmed',
label: MailPoet.I18n.t('unconfirmed'),
sortable: false
label: MailPoet.I18n.t('unconfirmed')
},
{
name: 'unsubscribed',
label: MailPoet.I18n.t('unsubscribed'),
sortable: false
label: MailPoet.I18n.t('unsubscribed')
},
{
name: 'created_at',

View File

@@ -2,6 +2,7 @@ import React from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
import SegmentList from 'segments/list.jsx'
import SegmentForm from 'segments/form.jsx'

View File

@@ -21,8 +21,7 @@ const columns = [
},
{
name: 'segments',
label: MailPoet.I18n.t('lists'),
sortable: false
label: MailPoet.I18n.t('lists')
},
{