Segment listing
- fixed duplicate entry in Robofile for editor styles - added Segment menu - added Segment listing - added listing methods to Segment model - fixed syntax in both Segment & Subscriber models (MAX LINE 80!!!)
This commit is contained in:
@ -6,8 +6,7 @@ class RoboFile extends \Robo\Tasks {
|
|||||||
'assets/css/src/admin.styl',
|
'assets/css/src/admin.styl',
|
||||||
'assets/css/src/newsletter_editor/newsletter_editor.styl',
|
'assets/css/src/newsletter_editor/newsletter_editor.styl',
|
||||||
'assets/css/src/public.styl',
|
'assets/css/src/public.styl',
|
||||||
'assets/css/src/rtl.styl',
|
'assets/css/src/rtl.styl'
|
||||||
'assets/css/src/newsletter_editor/newsletter_editor.styl'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
private $js_files = array(
|
private $js_files = array(
|
||||||
|
101
assets/js/src/segments/list.jsx
Normal file
101
assets/js/src/segments/list.jsx
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
define(
|
||||||
|
'list',
|
||||||
|
[
|
||||||
|
'react',
|
||||||
|
'jquery',
|
||||||
|
'mailpoet',
|
||||||
|
'listing/listing.jsx',
|
||||||
|
'classnames'
|
||||||
|
],
|
||||||
|
function(
|
||||||
|
React,
|
||||||
|
jQuery,
|
||||||
|
MailPoet,
|
||||||
|
Listing,
|
||||||
|
classNames
|
||||||
|
) {
|
||||||
|
|
||||||
|
var columns = [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'created_at',
|
||||||
|
label: 'Created on',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updated_at',
|
||||||
|
label: 'Last modified on',
|
||||||
|
sortable: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var actions = [
|
||||||
|
];
|
||||||
|
|
||||||
|
var List = React.createClass({
|
||||||
|
getItems: function(listing) {
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
endpoint: 'segments',
|
||||||
|
action: 'get',
|
||||||
|
data: {
|
||||||
|
offset: (listing.state.page - 1) * listing.state.limit,
|
||||||
|
limit: listing.state.limit,
|
||||||
|
group: listing.state.group,
|
||||||
|
search: listing.state.search,
|
||||||
|
sort_by: listing.state.sort_by,
|
||||||
|
sort_order: listing.state.sort_order
|
||||||
|
},
|
||||||
|
onSuccess: function(response) {
|
||||||
|
if(listing.isMounted()) {
|
||||||
|
listing.setState({
|
||||||
|
items: response.items || [],
|
||||||
|
filters: response.filters || [],
|
||||||
|
groups: response.groups || [],
|
||||||
|
count: response.count || 0,
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}.bind(listing)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
renderItem: function(segment) {
|
||||||
|
var rowClasses = classNames(
|
||||||
|
'manage-column',
|
||||||
|
'column-primary',
|
||||||
|
'has-row-actions'
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<td className={ rowClasses }>
|
||||||
|
<strong>
|
||||||
|
<a>{ segment.name }</a>
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname="Subscribed on">
|
||||||
|
<abbr>{ segment.created_at }</abbr>
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname="Last modified on">
|
||||||
|
<abbr>{ segment.updated_at }</abbr>
|
||||||
|
</td>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<Listing
|
||||||
|
onRenderItem={this.renderItem}
|
||||||
|
items={this.getItems}
|
||||||
|
columns={columns}
|
||||||
|
actions={actions} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return List;
|
||||||
|
}
|
||||||
|
);
|
54
assets/js/src/segments/segments.jsx
Normal file
54
assets/js/src/segments/segments.jsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
define(
|
||||||
|
'segments',
|
||||||
|
[
|
||||||
|
'react',
|
||||||
|
'react-router',
|
||||||
|
'segments/list.jsx'
|
||||||
|
],
|
||||||
|
function(
|
||||||
|
React,
|
||||||
|
Router,
|
||||||
|
List
|
||||||
|
) {
|
||||||
|
|
||||||
|
var DefaultRoute = Router.DefaultRoute;
|
||||||
|
var Link = Router.Link;
|
||||||
|
var Route = Router.Route;
|
||||||
|
var RouteHandler = Router.RouteHandler;
|
||||||
|
|
||||||
|
var App = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
{ MailPoetI18n.pageTitle }
|
||||||
|
<span>
|
||||||
|
<Link className="add-new-h2" to="list">
|
||||||
|
{ MailPoetI18n.pageTitle }
|
||||||
|
</Link>
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<RouteHandler/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var routes = (
|
||||||
|
<Route name="app" path="/" handler={App}>
|
||||||
|
<Route name="list" handler={List} />
|
||||||
|
<DefaultRoute handler={List} />
|
||||||
|
</Route>
|
||||||
|
);
|
||||||
|
|
||||||
|
var hook = document.getElementById('segments');
|
||||||
|
if (hook) {
|
||||||
|
Router.run(routes, function(Handler, state) {
|
||||||
|
React.render(
|
||||||
|
<Handler params={state.params} query={state.query} />,
|
||||||
|
hook
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -23,7 +23,9 @@ define(
|
|||||||
<h1>
|
<h1>
|
||||||
{ MailPoetI18n.pageTitle }
|
{ MailPoetI18n.pageTitle }
|
||||||
<span>
|
<span>
|
||||||
<Link className="add-new-h2" to="list">Subscribers</Link>
|
<Link className="add-new-h2" to="list">
|
||||||
|
{ MailPoetI18n.pageTitle }
|
||||||
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
@ -28,32 +28,40 @@ class Menu {
|
|||||||
);
|
);
|
||||||
add_submenu_page(
|
add_submenu_page(
|
||||||
'mailpoet',
|
'mailpoet',
|
||||||
'Newsletters',
|
__('Newsletters'),
|
||||||
'Newsletters',
|
__('Newsletters'),
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mailpoet-newsletters',
|
'mailpoet-newsletters',
|
||||||
array($this, 'newsletters')
|
array($this, 'newsletters')
|
||||||
);
|
);
|
||||||
add_submenu_page(
|
add_submenu_page(
|
||||||
'mailpoet',
|
'mailpoet',
|
||||||
'Subscribers',
|
__('Subscribers'),
|
||||||
'Subscribers',
|
__('Subscribers'),
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mailpoet-subscribers',
|
'mailpoet-subscribers',
|
||||||
array($this, 'subscribers')
|
array($this, 'subscribers')
|
||||||
);
|
);
|
||||||
add_submenu_page(
|
add_submenu_page(
|
||||||
'mailpoet',
|
'mailpoet',
|
||||||
'Settings',
|
__('Segments'),
|
||||||
'Settings',
|
__('Segments'),
|
||||||
|
'manage_options',
|
||||||
|
'mailpoet-segments',
|
||||||
|
array($this, 'segments')
|
||||||
|
);
|
||||||
|
add_submenu_page(
|
||||||
|
'mailpoet',
|
||||||
|
__('Settings'),
|
||||||
|
__('Settings'),
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mailpoet-settings',
|
'mailpoet-settings',
|
||||||
array($this, 'settings')
|
array($this, 'settings')
|
||||||
);
|
);
|
||||||
add_submenu_page(
|
add_submenu_page(
|
||||||
'mailpoet',
|
'mailpoet',
|
||||||
'Newsletter editor',
|
__('Newsletter editor'),
|
||||||
'Newsletter editor',
|
__('Newsletter editor'),
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mailpoet-newsletter-editor',
|
'mailpoet-newsletter-editor',
|
||||||
array($this, 'newsletterEditor')
|
array($this, 'newsletterEditor')
|
||||||
@ -75,6 +83,11 @@ class Menu {
|
|||||||
echo $this->renderer->render('subscribers.html', $data);
|
echo $this->renderer->render('subscribers.html', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function segments() {
|
||||||
|
$data = array();
|
||||||
|
echo $this->renderer->render('segments.html', $data);
|
||||||
|
}
|
||||||
|
|
||||||
function newsletters() {
|
function newsletters() {
|
||||||
$data = array();
|
$data = array();
|
||||||
echo $this->renderer->render('newsletters.html', $data);
|
echo $this->renderer->render('newsletters.html', $data);
|
||||||
|
@ -30,6 +30,28 @@ class Segment extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function subscribers() {
|
public function subscribers() {
|
||||||
return $this->has_many_through(__NAMESPACE__ . '\Subscriber', __NAMESPACE__ . '\SubscriberSegment', 'segment_id', 'subscriber_id');
|
return $this->has_many_through(
|
||||||
|
__NAMESPACE__.'\Subscriber',
|
||||||
|
__NAMESPACE__.'\SubscriberSegment',
|
||||||
|
'segment_id',
|
||||||
|
'subscriber_id'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function search($orm, $search = '') {
|
||||||
|
return $orm->where_like('name', '%'.$search.'%');
|
||||||
|
}
|
||||||
|
|
||||||
|
static function groups() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'name' => 'all',
|
||||||
|
'label' => __('All'),
|
||||||
|
'count' => Segment::count()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function group($orm, $group = null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,11 @@ class Subscriber extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function segments() {
|
public function segments() {
|
||||||
return $this->has_many_through(__NAMESPACE__ . '\Segment', __NAMESPACE__ . '\SubscriberSegment', 'subscriber_id', 'segment_id');
|
return $this->has_many_through(
|
||||||
|
__NAMESPACE__.'\Segment',
|
||||||
|
__NAMESPACE__.'\SubscriberSegment',
|
||||||
|
'subscriber_id',
|
||||||
|
'segment_id'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
lib/Router/Segments.php
Normal file
44
lib/Router/Segments.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Router;
|
||||||
|
use \MailPoet\Models\Segment;
|
||||||
|
use \MailPoet\Listing;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Segments {
|
||||||
|
function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($data = array()) {
|
||||||
|
$listing = new Listing\Handler(
|
||||||
|
\Model::factory('\MailPoet\Models\Segment'),
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
wp_send_json($listing->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAll() {
|
||||||
|
$collection = Segment::find_array();
|
||||||
|
wp_send_json($collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save($args) {
|
||||||
|
$model = Segment::create();
|
||||||
|
$model->hydrate($args);
|
||||||
|
$saved = $model->save();
|
||||||
|
|
||||||
|
if(!$saved) {
|
||||||
|
wp_send_json($model->getValidationErrors());
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update($args) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
12
views/segments.html
Normal file
12
views/segments.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<% extends 'layout.html' %>
|
||||||
|
|
||||||
|
<% block content %>
|
||||||
|
<div id="segments"></div>
|
||||||
|
|
||||||
|
<%= localize({
|
||||||
|
'pageTitle': __('Segments'),
|
||||||
|
'searchLabel': __('Search'),
|
||||||
|
'loading': __('Loading segments...'),
|
||||||
|
'noRecordFound': __('No segments found.')
|
||||||
|
}) %>
|
||||||
|
<% endblock %>
|
@ -62,7 +62,8 @@ config.push(_.extend({}, baseConfig, {
|
|||||||
admin: [
|
admin: [
|
||||||
'settings.jsx',
|
'settings.jsx',
|
||||||
'subscribers/subscribers.jsx',
|
'subscribers/subscribers.jsx',
|
||||||
'newsletters/newsletters.jsx'
|
'newsletters/newsletters.jsx',
|
||||||
|
'segments/segments.jsx'
|
||||||
],
|
],
|
||||||
newsletter_editor: [
|
newsletter_editor: [
|
||||||
'underscore',
|
'underscore',
|
||||||
|
Reference in New Issue
Block a user