Listing & Form & Refactoring
- finished implementing forms - fixed form reset when clicking on new - fixed responsive for select all checkbox and toggle item details - refactored listing items' actions - added Trash action - cleaned up validations on models - fixed syntax - fixed tests
This commit is contained in:
@ -34,7 +34,7 @@ define(
|
||||
name={ this.props.field.name }
|
||||
id={ 'field_'+this.props.field.name }
|
||||
value={ this.props.item[this.props.field.name] }
|
||||
onChange={ this.props.onValueChange } >
|
||||
onChange={ this.props.onValueChange }>
|
||||
{options}
|
||||
</select>
|
||||
);
|
||||
@ -228,6 +228,7 @@ define(
|
||||
loading: false,
|
||||
item: {}
|
||||
});
|
||||
this.refs.form.getDOMNode().reset();
|
||||
} else {
|
||||
this.loadItem(props.params.id);
|
||||
}
|
||||
@ -315,6 +316,7 @@ define(
|
||||
|
||||
return (
|
||||
<form
|
||||
ref="form"
|
||||
className={ formClasses }
|
||||
onSubmit={ this.handleSubmit }>
|
||||
|
||||
|
@ -22,7 +22,8 @@ define(['react', 'classnames'], function(React, classNames) {
|
||||
|
||||
if(this.props.is_selectable === true) {
|
||||
checkbox = (
|
||||
<td className="manage-column column-cb mailpoet_check_column">
|
||||
<td
|
||||
className="manage-column column-cb check-column">
|
||||
<label className="screen-reader-text">
|
||||
{ 'Select All' }
|
||||
</label>
|
||||
|
@ -3,6 +3,7 @@ define(
|
||||
'mailpoet',
|
||||
'jquery',
|
||||
'react',
|
||||
'react-router',
|
||||
'classnames',
|
||||
'listing/bulk_actions.jsx',
|
||||
'listing/header.jsx',
|
||||
@ -15,6 +16,7 @@ define(
|
||||
MailPoet,
|
||||
jQuery,
|
||||
React,
|
||||
Router,
|
||||
classNames,
|
||||
ListingBulkActions,
|
||||
ListingHeader,
|
||||
@ -23,7 +25,14 @@ define(
|
||||
ListingGroups,
|
||||
ListingFilters
|
||||
) {
|
||||
var ListingItem = React.createClass({
|
||||
var Link = Router.Link;
|
||||
|
||||
var ListingItem = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
toggled: true
|
||||
};
|
||||
},
|
||||
handleSelectItem: function(e) {
|
||||
var is_checked = jQuery(e.target).is(':checked');
|
||||
|
||||
@ -34,13 +43,18 @@ define(
|
||||
|
||||
return !e.target.checked;
|
||||
},
|
||||
handleDeleteItem: function(id) {
|
||||
this.props.onDeleteItem(id);
|
||||
},
|
||||
handleToggleItem: function(id) {
|
||||
this.setState({ toggled: !this.state.toggled });
|
||||
},
|
||||
render: function() {
|
||||
|
||||
var checkbox = false;
|
||||
|
||||
if(this.props.is_selectable === true) {
|
||||
checkbox = (
|
||||
<th className="mailpoet_check_column" scope="row">
|
||||
<th className="check-column" scope="row">
|
||||
<label className="screen-reader-text">
|
||||
{ 'Select ' + this.props.item.email }</label>
|
||||
<input
|
||||
@ -55,10 +69,35 @@ define(
|
||||
);
|
||||
}
|
||||
|
||||
var item_actions = (
|
||||
<div>
|
||||
<div className="row-actions">
|
||||
<span className="edit">
|
||||
<Link to="edit" params={{ id: this.props.item.id }}>Edit</Link>
|
||||
</span>
|
||||
|
|
||||
<span className="trash">
|
||||
<a
|
||||
href="javascript:;"
|
||||
onClick={ this.handleDeleteItem.bind(null, this.props.item.id) }>
|
||||
Trash
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
|
||||
className="toggle-row" type="button">
|
||||
<span className="screen-reader-text">Show more details</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
var row_classes = classNames({ 'is-expanded': !this.state.toggled })
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<tr className={ row_classes }>
|
||||
{ checkbox }
|
||||
{ this.props.onRenderItem(this.props.item) }
|
||||
{ this.props.onRenderItem(this.props.item, item_actions) }
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
@ -124,6 +163,7 @@ define(
|
||||
columns={ this.props.columns }
|
||||
onSelectItem={ this.props.onSelectItem }
|
||||
onRenderItem={ this.props.onRenderItem }
|
||||
onDeleteItem={ this.props.onDeleteItem }
|
||||
selection={ this.props.selection }
|
||||
is_selectable={ this.props.is_selectable }
|
||||
key={ 'item-' + item.id }
|
||||
@ -170,19 +210,29 @@ define(
|
||||
search: this.state.search,
|
||||
sort_by: this.state.sort_by,
|
||||
sort_order: this.state.sort_order
|
||||
},
|
||||
onSuccess: function(response) {
|
||||
if(this.isMounted()) {
|
||||
this.setState({
|
||||
items: response.items || [],
|
||||
filters: response.filters || [],
|
||||
groups: response.groups || [],
|
||||
count: response.count || 0,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}.bind(this)
|
||||
});
|
||||
}
|
||||
}).done(function(response) {
|
||||
if(this.isMounted()) {
|
||||
this.setState({
|
||||
items: response.items || [],
|
||||
filters: response.filters || [],
|
||||
groups: response.groups || [],
|
||||
count: response.count || 0,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
handleDeleteItem: function(id) {
|
||||
this.setState({ loading: true });
|
||||
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: this.props.endpoint,
|
||||
action: 'delete',
|
||||
data: id
|
||||
}).done(function() {
|
||||
this.getItems();
|
||||
}.bind(this));
|
||||
},
|
||||
handleSearch: function(search) {
|
||||
this.setState({
|
||||
@ -269,8 +319,8 @@ define(
|
||||
this.getItems();
|
||||
}.bind(this));
|
||||
},
|
||||
handleRenderItem: function(item) {
|
||||
return this.props.onRenderItem(item);
|
||||
handleRenderItem: function(item, actions) {
|
||||
return this.props.onRenderItem(item, actions);
|
||||
},
|
||||
render: function() {
|
||||
var items = this.state.items,
|
||||
@ -326,6 +376,7 @@ define(
|
||||
|
||||
<ListingItems
|
||||
onRenderItem={ this.handleRenderItem }
|
||||
onDeleteItem={ this.handleDeleteItem }
|
||||
columns={ this.props.columns }
|
||||
is_selectable={ bulk_actions.length > 0 }
|
||||
onSelectItem={ this.handleSelectItem }
|
||||
|
@ -34,7 +34,6 @@ define(
|
||||
|
||||
var NewsletterForm = React.createClass({
|
||||
render: function() {
|
||||
|
||||
return (
|
||||
<Form
|
||||
endpoint="newsletters"
|
||||
|
@ -1,18 +1,14 @@
|
||||
define(
|
||||
[
|
||||
'react',
|
||||
'react-router',
|
||||
'listing/listing.jsx',
|
||||
'classnames',
|
||||
'classnames'
|
||||
],
|
||||
function(
|
||||
React,
|
||||
Router,
|
||||
Listing,
|
||||
classNames
|
||||
) {
|
||||
var Link = Router.Link;
|
||||
|
||||
var columns = [
|
||||
{
|
||||
name: 'subject',
|
||||
@ -32,7 +28,7 @@ define(
|
||||
];
|
||||
|
||||
var NewsletterList = React.createClass({
|
||||
renderItem: function(newsletter) {
|
||||
renderItem: function(newsletter, actions) {
|
||||
var rowClasses = classNames(
|
||||
'manage-column',
|
||||
'column-primary',
|
||||
@ -45,12 +41,7 @@ define(
|
||||
<strong>
|
||||
<a>{ newsletter.subject }</a>
|
||||
</strong>
|
||||
|
||||
<div className="row-actions">
|
||||
<span className="edit">
|
||||
<Link to="edit" params={{ id: newsletter.id }}>Edit</Link>
|
||||
</span>
|
||||
</div>
|
||||
{ actions }
|
||||
</td>
|
||||
<td className="column-date" data-colname="Subscribed on">
|
||||
<abbr>{ newsletter.created_at }</abbr>
|
||||
|
@ -1,18 +1,14 @@
|
||||
define(
|
||||
[
|
||||
'react',
|
||||
'react-router',
|
||||
'listing/listing.jsx',
|
||||
'classnames',
|
||||
'classnames'
|
||||
],
|
||||
function(
|
||||
React,
|
||||
Router,
|
||||
Listing,
|
||||
classNames
|
||||
) {
|
||||
var Link = Router.Link;
|
||||
|
||||
var columns = [
|
||||
{
|
||||
name: 'name',
|
||||
@ -32,7 +28,7 @@ define(
|
||||
];
|
||||
|
||||
var SegmentList = React.createClass({
|
||||
renderItem: function(segment) {
|
||||
renderItem: function(segment, actions) {
|
||||
var rowClasses = classNames(
|
||||
'manage-column',
|
||||
'column-primary',
|
||||
@ -45,12 +41,7 @@ define(
|
||||
<strong>
|
||||
<a>{ segment.name }</a>
|
||||
</strong>
|
||||
|
||||
<div className="row-actions">
|
||||
<span className="edit">
|
||||
<Link to="edit" params={{ id: segment.id }}>Edit</Link>
|
||||
</span>
|
||||
</div>
|
||||
{ actions }
|
||||
</td>
|
||||
<td className="column-date" data-colname="Subscribed on">
|
||||
<abbr>{ segment.created_at }</abbr>
|
||||
|
@ -31,8 +31,8 @@ define(
|
||||
label: 'Status',
|
||||
type: 'select',
|
||||
values: {
|
||||
'subscribed': 'Subscribed',
|
||||
'unconfirmed': 'Unconfirmed',
|
||||
'subscribed': 'Subscribed',
|
||||
'unsubscribed': 'Unsubscribed'
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,14 @@
|
||||
define(
|
||||
[
|
||||
'react',
|
||||
'react-router',
|
||||
'listing/listing.jsx',
|
||||
'classnames',
|
||||
'classnames'
|
||||
],
|
||||
function(
|
||||
React,
|
||||
Router,
|
||||
Listing,
|
||||
classNames
|
||||
) {
|
||||
var Link = Router.Link;
|
||||
|
||||
var columns = [
|
||||
{
|
||||
name: 'email',
|
||||
@ -62,8 +58,8 @@ define(
|
||||
];
|
||||
|
||||
var List = React.createClass({
|
||||
renderItem: function(subscriber) {
|
||||
var rowClasses = classNames(
|
||||
renderItem: function(subscriber, actions) {
|
||||
var row_classes = classNames(
|
||||
'manage-column',
|
||||
'column-primary',
|
||||
'has-row-actions'
|
||||
@ -87,20 +83,11 @@ define(
|
||||
|
||||
return (
|
||||
<div>
|
||||
<td className={ rowClasses }>
|
||||
<td className={ row_classes }>
|
||||
<strong>
|
||||
<a>{ subscriber.email }</a>
|
||||
</strong>
|
||||
|
||||
<div className="row-actions">
|
||||
<span className="edit">
|
||||
<Link to="edit" params={{ id: subscriber.id }}>Edit</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button className="toggle-row" type="button">
|
||||
<span className="screen-reader-text">Show more details</span>
|
||||
</button>
|
||||
{ actions }
|
||||
</td>
|
||||
<td className="column" data-colname="First name">
|
||||
{ subscriber.first_name }
|
||||
@ -125,7 +112,6 @@ define(
|
||||
<Listing
|
||||
endpoint="subscribers"
|
||||
onRenderItem={ this.renderItem }
|
||||
items={ this.getItems }
|
||||
columns={ columns }
|
||||
bulk_actions={ bulk_actions } />
|
||||
);
|
||||
|
Reference in New Issue
Block a user