Added "params" to the $data in Listing Handler

- moved "tab" to params
- improved url generation in listing.jsx to allow more flexibility
- added "parent_id" filter in newsletter model to get children of a given newsletter id
This commit is contained in:
Jonathan Labreuille
2016-07-13 16:58:48 +02:00
parent f5552847a3
commit ef0cbb3e9f
8 changed files with 81 additions and 49 deletions

View File

@@ -1,6 +1,7 @@
import MailPoet from 'mailpoet' import MailPoet from 'mailpoet'
import jQuery from 'jquery' import jQuery from 'jquery'
import React from 'react' import React from 'react'
import _ from 'underscore'
import { Router, Link } from 'react-router' import { Router, Link } from 'react-router'
import classNames from 'classnames' import classNames from 'classnames'
import ListingBulkActions from 'listing/bulk_actions.jsx' import ListingBulkActions from 'listing/bulk_actions.jsx'
@@ -13,7 +14,7 @@ import ListingFilters from 'listing/filters.jsx'
const ListingItem = React.createClass({ const ListingItem = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
toggled: true expanded: false
}; };
}, },
handleSelectItem: function(e) { handleSelectItem: function(e) {
@@ -34,7 +35,7 @@ const ListingItem = React.createClass({
this.props.onDeleteItem(id); this.props.onDeleteItem(id);
}, },
handleToggleItem: function(id) { handleToggleItem: function(id) {
this.setState({ toggled: !this.state.toggled }); this.setState({ expanded: !this.state.expanded });
}, },
render: function() { render: function() {
var checkbox = false; var checkbox = false;
@@ -182,7 +183,7 @@ const ListingItem = React.createClass({
); );
} }
const row_classes = classNames({ 'is-expanded': !this.state.toggled }); const row_classes = classNames({ 'is-expanded': this.state.expanded });
return ( return (
<tr className={ row_classes }> <tr className={ row_classes }>
@@ -303,13 +304,12 @@ const Listing = React.createClass({
getParam: function(param) { getParam: function(param) {
const regex = /(.*)\[(.*)\]/; const regex = /(.*)\[(.*)\]/;
const matches = regex.exec(param); const matches = regex.exec(param);
return [matches[1], matches[2]] return [matches[1], matches[2]];
}, },
initWithParams: function(params) { initWithParams: function(params) {
let state = this.getInitialState(); let state = this.getInitialState();
// check for url params // check for url params
if (params.splat !== undefined) { if (params.splat) {
params.splat.split('/').map(param => { params.splat.split('/').map(param => {
let [key, value] = this.getParam(param); let [key, value] = this.getParam(param);
switch(key) { switch(key) {
@@ -348,6 +348,16 @@ const Listing = React.createClass({
this.getItems(); this.getItems();
}.bind(this)); }.bind(this));
}, },
getExtraParams: function() {
// get all route parameters (without the "splat")
let extras = _.omit(this.props.params, 'splat');
// TO REFACTOR:
// set the "tab" in the routes definition
if (this.props.tab) {
extras.tab = this.props.tab;
}
return extras;
},
setParams: function() { setParams: function() {
if (this.props.location) { if (this.props.location) {
let params = Object.keys(this.state) let params = Object.keys(this.state)
@@ -378,26 +388,38 @@ const Listing = React.createClass({
.filter(key => { return (key !== undefined) }) .filter(key => { return (key !== undefined) })
.join('/'); .join('/');
// prepend url with "tab" if specified // set url
if (this.props.tab !== undefined || this.props.base_path !== undefined) { let url = this.getUrlWithParams(params);
let base_path = (this.props.base_path !== undefined)
? this.props.base_path
: this.props.tab;
// TODO: add method to replace dynamic path elements if (this.props.location.pathname !== url) {
base_path = base_path.replace(':id', this.props.params.id); this.context.router.push(`${url}`);
// /-TODO--
params = `/${ base_path }/${ params }`;
} else {
params = `/${ params }`;
}
if (this.props.location.pathname !== params) {
this.context.router.push(`${params}`);
} }
} }
}, },
getUrlWithParams: function(params) {
let base_url = (this.props.base_url !== undefined)
? this.props.base_url
: null;
if (base_url !== null) {
base_url = this.setBaseUrlParams(base_url);
return `/${ base_url }/${ params }`;
} else {
return `/${ params }`;
}
},
setBaseUrlParams: function(base_url) {
if (base_url.contains(':') === true) {
const params = this.getExtraParams();
Object.keys(params).map((key) => {
if (base_url.contains(':'+key)) {
base_url = base_url.replace(':'+key, params[key]);
}
});
}
return base_url;
},
componentDidMount: function() { componentDidMount: function() {
if (this.isMounted()) { if (this.isMounted()) {
const params = this.props.params || {}; const params = this.props.params || {};
@@ -424,7 +446,7 @@ const Listing = React.createClass({
endpoint: this.props.endpoint, endpoint: this.props.endpoint,
action: 'listing', action: 'listing',
data: { data: {
tab: (this.props.tab) ? this.props.tab : '', params: this.getExtraParams(),
offset: (this.state.page - 1) * this.state.limit, offset: (this.state.page - 1) * this.state.limit,
limit: this.state.limit, limit: this.state.limit,
group: this.state.group, group: this.state.group,
@@ -539,7 +561,7 @@ const Listing = React.createClass({
var data = params || {}; var data = params || {};
data.listing = { data.listing = {
tab: (this.props.tab) ? this.props.tab : '', params: this.getExtraParams(),
offset: 0, offset: 0,
limit: 0, limit: 0,
filter: this.state.filter, filter: this.state.filter,

View File

@@ -302,6 +302,7 @@ const NewsletterListNotification = React.createClass({
params={ this.props.params } params={ this.props.params }
endpoint="newsletters" endpoint="newsletters"
tab="notification" tab="notification"
base_url="notification"
onRenderItem={ this.renderItem } onRenderItem={ this.renderItem }
columns={ columns } columns={ columns }
bulk_actions={ bulk_actions } bulk_actions={ bulk_actions }

View File

@@ -192,8 +192,8 @@ const NewsletterListNotificationHistory = React.createClass({
<td className={ rowClasses }> <td className={ rowClasses }>
<strong> <strong>
<a <a
className="row-title" href={ newsletter.preview_url }
href={ `?page=mailpoet-newsletter-editor&id=${ newsletter.id }` } target="_blank"
>{ newsletter.subject }</a> >{ newsletter.subject }</a>
</strong> </strong>
{ actions } { actions }
@@ -235,7 +235,7 @@ const NewsletterListNotificationHistory = React.createClass({
params={ this.props.params } params={ this.props.params }
endpoint="newsletters" endpoint="newsletters"
tab="notification_history" tab="notification_history"
base_path="notification/history/:id" base_url="notification/history/:parent_id"
onRenderItem={ this.renderItem } onRenderItem={ this.renderItem }
columns={columns} columns={columns}
item_actions={ newsletter_actions } item_actions={ newsletter_actions }

View File

@@ -322,6 +322,7 @@ const NewsletterListStandard = React.createClass({
params={ this.props.params } params={ this.props.params }
endpoint="newsletters" endpoint="newsletters"
tab="standard" tab="standard"
base_url="standard"
onRenderItem={this.renderItem} onRenderItem={this.renderItem}
columns={columns} columns={columns}
bulk_actions={ bulk_actions } bulk_actions={ bulk_actions }

View File

@@ -344,6 +344,7 @@ const NewsletterListWelcome = React.createClass({
params={ this.props.params } params={ this.props.params }
endpoint="newsletters" endpoint="newsletters"
tab="welcome" tab="welcome"
base_url="welcome"
onRenderItem={ this.renderItem } onRenderItem={ this.renderItem }
columns={ columns } columns={ columns }
bulk_actions={ bulk_actions } bulk_actions={ bulk_actions }

View File

@@ -20,7 +20,7 @@ const history = useRouterHistory(createHashHistory)({ queryKey: false });
const App = React.createClass({ const App = React.createClass({
render() { render() {
return this.props.children return this.props.children;
} }
}); });
@@ -32,21 +32,16 @@ if(container) {
<Route path="/" component={ App }> <Route path="/" component={ App }>
<IndexRedirect to="standard" /> <IndexRedirect to="standard" />
{/* Listings */} {/* Listings */}
<Route name="listing/standard" path="standard" component={ NewsletterListStandard } /> <Route path="standard(/)**" params={{ tab: 'standard' }} component={ NewsletterListStandard } />
<Route name="listing/welcome" path="welcome" component={ NewsletterListWelcome } /> <Route path="welcome(/)**" component={ NewsletterListWelcome } />
<Route name="listing/notification" path="notification" component={ NewsletterListNotification } /> <Route path="notification/history/:parent_id(/)**" component={ NewsletterListNotificationHistory } />
<Route name="listing/notification/history" path="notification/history/:id" component={ NewsletterListNotificationHistory } /> <Route path="notification(/)**" component={ NewsletterListNotification } />
<Route path="standard/*" component={ NewsletterListStandard } />
<Route path="welcome/*" component={ NewsletterListWelcome } />
<Route path="notification/history/:id/*" component={ NewsletterListNotificationHistory } />
<Route path="notification/*" component={ NewsletterListNotification } />
{/* Newsletter: type selection */} {/* Newsletter: type selection */}
<Route path="new" component={ NewsletterTypes } /> <Route path="new" component={ NewsletterTypes } />
{/* New newsletter: types */} {/* New newsletter: types */}
<Route name="new/standard" path="new/standard" component={ NewsletterTypeStandard } /> <Route path="new/standard" component={ NewsletterTypeStandard } />
<Route name="new/welcome" path="new/welcome" component={ NewsletterTypeWelcome } /> <Route path="new/welcome" component={ NewsletterTypeWelcome } />
<Route name="new/notification" path="new/notification" component={ NewsletterTypeNotification } /> <Route path="new/notification" component={ NewsletterTypeNotification } />
{/* Template selection */} {/* Template selection */}
<Route name="template" path="template/:id" component={ NewsletterTemplates } /> <Route name="template" path="template/:id" component={ NewsletterTemplates } />
{/* Sending options */} {/* Sending options */}

View File

@@ -16,8 +16,8 @@ class Handler {
$this->model = \Model::factory($this->model_class); $this->model = \Model::factory($this->model_class);
$this->data = array( $this->data = array(
// tabs // extra parameters
'tab' => (isset($data['tab']) ? $data['tab'] : false), 'params' => (isset($data['params']) ? $data['params'] : array()),
// pagination // pagination
'offset' => (isset($data['offset']) ? (int)$data['offset'] : 0), 'offset' => (isset($data['offset']) ? (int)$data['offset'] : 0),
'limit' => (isset($data['limit']) 'limit' => (isset($data['limit'])

View File

@@ -20,7 +20,6 @@ class Newsletter extends Model {
// automatic newsletters status // automatic newsletters status
const STATUS_ACTIVE = 'active'; const STATUS_ACTIVE = 'active';
function __construct() { function __construct() {
parent::__construct(); parent::__construct();
@@ -260,7 +259,7 @@ class Newsletter extends Model {
} }
static function filters($data = array()) { static function filters($data = array()) {
$type = isset($data['tab']) ? $data['tab'] : null; $type = isset($data['params']['tab']) ? $data['params']['tab'] : null;
// newsletter types without filters // newsletter types without filters
if(in_array($type, array( if(in_array($type, array(
@@ -299,18 +298,32 @@ class Newsletter extends Model {
} }
static function filterBy($orm, $data = array()) { static function filterBy($orm, $data = array()) {
$type = isset($data['tab']) ? $data['tab'] : null; // apply filters
if(!empty($data['filter'])) { if(!empty($data['filter'])) {
foreach($data['filter'] as $key => $value) { foreach($data['filter'] as $key => $value) {
if($key === 'segment') { if($key === 'segment') {
$segment = Segment::findOne($value); $segment = Segment::findOne($value);
if($segment !== false) { if($segment !== false) {
$orm = $segment->newsletters()->filter('filterType', $type); $orm = $segment->newsletters();
} }
} }
} }
} }
// filter by type
$type = isset($data['params']['tab']) ? $data['params']['tab'] : null;
if($type !== null) {
$orm->filter('filterType', $type);
}
// filter by parent id
$parent_id = isset($data['params']['parent_id'])
? (int)$data['params']['parent_id']
: null;
if($parent_id !== null) {
$orm->where('parent_id', $parent_id);
}
return $orm; return $orm;
} }
@@ -345,7 +358,7 @@ class Newsletter extends Model {
} }
static function groups($data = array()) { static function groups($data = array()) {
$type = isset($data['tab']) ? $data['tab'] : null; $type = isset($data['params']['tab']) ? $data['params']['tab'] : null;
// newsletter types without groups // newsletter types without groups
if(in_array($type, array( if(in_array($type, array(
@@ -494,7 +507,6 @@ class Newsletter extends Model {
'updated_at', 'updated_at',
'deleted_at' 'deleted_at'
)) ))
->filter('filterType', $data['tab'])
->filter('filterBy', $data) ->filter('filterBy', $data)
->filter('groupBy', $data) ->filter('groupBy', $data)
->filter('search', $data['search']); ->filter('search', $data['search']);