diff --git a/assets/js/src/listing/listing.jsx b/assets/js/src/listing/listing.jsx index 0d5922e478..9964ef1fac 100644 --- a/assets/js/src/listing/listing.jsx +++ b/assets/js/src/listing/listing.jsx @@ -1,6 +1,7 @@ import MailPoet from 'mailpoet' import jQuery from 'jquery' import React from 'react' +import _ from 'underscore' import { Router, Link } from 'react-router' import classNames from 'classnames' import ListingBulkActions from 'listing/bulk_actions.jsx' @@ -13,7 +14,7 @@ import ListingFilters from 'listing/filters.jsx' const ListingItem = React.createClass({ getInitialState: function() { return { - toggled: true + expanded: false }; }, handleSelectItem: function(e) { @@ -34,7 +35,7 @@ const ListingItem = React.createClass({ this.props.onDeleteItem(id); }, handleToggleItem: function(id) { - this.setState({ toggled: !this.state.toggled }); + this.setState({ expanded: !this.state.expanded }); }, render: function() { 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 ( @@ -303,13 +304,12 @@ const Listing = React.createClass({ getParam: function(param) { const regex = /(.*)\[(.*)\]/; const matches = regex.exec(param); - return [matches[1], matches[2]] + return [matches[1], matches[2]]; }, initWithParams: function(params) { let state = this.getInitialState(); - // check for url params - if (params.splat !== undefined) { + if (params.splat) { params.splat.split('/').map(param => { let [key, value] = this.getParam(param); switch(key) { @@ -348,6 +348,16 @@ const Listing = React.createClass({ this.getItems(); }.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() { if (this.props.location) { let params = Object.keys(this.state) @@ -378,26 +388,38 @@ const Listing = React.createClass({ .filter(key => { return (key !== undefined) }) .join('/'); - // prepend url with "tab" if specified - if (this.props.tab !== undefined || this.props.base_path !== undefined) { - let base_path = (this.props.base_path !== undefined) - ? this.props.base_path - : this.props.tab; + // set url + let url = this.getUrlWithParams(params); - // TODO: add method to replace dynamic path elements - base_path = base_path.replace(':id', this.props.params.id); - // /-TODO-- - - params = `/${ base_path }/${ params }`; - } else { - params = `/${ params }`; - } - - if (this.props.location.pathname !== params) { - this.context.router.push(`${params}`); + if (this.props.location.pathname !== url) { + this.context.router.push(`${url}`); } } }, + 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() { if (this.isMounted()) { const params = this.props.params || {}; @@ -424,7 +446,7 @@ const Listing = React.createClass({ endpoint: this.props.endpoint, action: 'listing', data: { - tab: (this.props.tab) ? this.props.tab : '', + params: this.getExtraParams(), offset: (this.state.page - 1) * this.state.limit, limit: this.state.limit, group: this.state.group, @@ -539,7 +561,7 @@ const Listing = React.createClass({ var data = params || {}; data.listing = { - tab: (this.props.tab) ? this.props.tab : '', + params: this.getExtraParams(), offset: 0, limit: 0, filter: this.state.filter, diff --git a/assets/js/src/newsletters/listings/notification.jsx b/assets/js/src/newsletters/listings/notification.jsx index 363b3879d2..56948384e8 100644 --- a/assets/js/src/newsletters/listings/notification.jsx +++ b/assets/js/src/newsletters/listings/notification.jsx @@ -302,6 +302,7 @@ const NewsletterListNotification = React.createClass({ params={ this.props.params } endpoint="newsletters" tab="notification" + base_url="notification" onRenderItem={ this.renderItem } columns={ columns } bulk_actions={ bulk_actions } diff --git a/assets/js/src/newsletters/listings/notification_history.jsx b/assets/js/src/newsletters/listings/notification_history.jsx index c0420c0a6e..df9f5be705 100644 --- a/assets/js/src/newsletters/listings/notification_history.jsx +++ b/assets/js/src/newsletters/listings/notification_history.jsx @@ -192,8 +192,8 @@ const NewsletterListNotificationHistory = React.createClass({ { newsletter.subject } { actions } @@ -235,7 +235,7 @@ const NewsletterListNotificationHistory = React.createClass({ params={ this.props.params } endpoint="newsletters" tab="notification_history" - base_path="notification/history/:id" + base_url="notification/history/:parent_id" onRenderItem={ this.renderItem } columns={columns} item_actions={ newsletter_actions } diff --git a/assets/js/src/newsletters/listings/standard.jsx b/assets/js/src/newsletters/listings/standard.jsx index 1e7ac7f7d9..384a8148ef 100644 --- a/assets/js/src/newsletters/listings/standard.jsx +++ b/assets/js/src/newsletters/listings/standard.jsx @@ -322,6 +322,7 @@ const NewsletterListStandard = React.createClass({ params={ this.props.params } endpoint="newsletters" tab="standard" + base_url="standard" onRenderItem={this.renderItem} columns={columns} bulk_actions={ bulk_actions } diff --git a/assets/js/src/newsletters/listings/welcome.jsx b/assets/js/src/newsletters/listings/welcome.jsx index c04a7abe6e..857e520bc5 100644 --- a/assets/js/src/newsletters/listings/welcome.jsx +++ b/assets/js/src/newsletters/listings/welcome.jsx @@ -344,6 +344,7 @@ const NewsletterListWelcome = React.createClass({ params={ this.props.params } endpoint="newsletters" tab="welcome" + base_url="welcome" onRenderItem={ this.renderItem } columns={ columns } bulk_actions={ bulk_actions } diff --git a/assets/js/src/newsletters/newsletters.jsx b/assets/js/src/newsletters/newsletters.jsx index 55e980a26d..0ed787054e 100644 --- a/assets/js/src/newsletters/newsletters.jsx +++ b/assets/js/src/newsletters/newsletters.jsx @@ -20,7 +20,7 @@ const history = useRouterHistory(createHashHistory)({ queryKey: false }); const App = React.createClass({ render() { - return this.props.children + return this.props.children; } }); @@ -32,21 +32,16 @@ if(container) { {/* Listings */} - - - - - - - - - + + + + {/* Newsletter: type selection */} {/* New newsletter: types */} - - - + + + {/* Template selection */} {/* Sending options */} diff --git a/lib/Listing/Handler.php b/lib/Listing/Handler.php index 0f5917518f..8bb37fd4eb 100644 --- a/lib/Listing/Handler.php +++ b/lib/Listing/Handler.php @@ -16,8 +16,8 @@ class Handler { $this->model = \Model::factory($this->model_class); $this->data = array( - // tabs - 'tab' => (isset($data['tab']) ? $data['tab'] : false), + // extra parameters + 'params' => (isset($data['params']) ? $data['params'] : array()), // pagination 'offset' => (isset($data['offset']) ? (int)$data['offset'] : 0), 'limit' => (isset($data['limit']) diff --git a/lib/Models/Newsletter.php b/lib/Models/Newsletter.php index 89676c1a74..b8752698a6 100644 --- a/lib/Models/Newsletter.php +++ b/lib/Models/Newsletter.php @@ -20,7 +20,6 @@ class Newsletter extends Model { // automatic newsletters status const STATUS_ACTIVE = 'active'; - function __construct() { parent::__construct(); @@ -260,7 +259,7 @@ class Newsletter extends Model { } 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 if(in_array($type, array( @@ -299,18 +298,32 @@ class Newsletter extends Model { } static function filterBy($orm, $data = array()) { - $type = isset($data['tab']) ? $data['tab'] : null; - + // apply filters if(!empty($data['filter'])) { foreach($data['filter'] as $key => $value) { if($key === 'segment') { $segment = Segment::findOne($value); 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; } @@ -345,7 +358,7 @@ class Newsletter extends Model { } 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 if(in_array($type, array( @@ -494,7 +507,6 @@ class Newsletter extends Model { 'updated_at', 'deleted_at' )) - ->filter('filterType', $data['tab']) ->filter('filterBy', $data) ->filter('groupBy', $data) ->filter('search', $data['search']);