Skip to content

Commit

Permalink
RestTableComponent is now using mobx, no more isMounted
Browse files Browse the repository at this point in the history
  • Loading branch information
FredericHeem committed Aug 29, 2016
1 parent 734a43a commit c1fd87f
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 164 deletions.
8 changes: 4 additions & 4 deletions client/.eslintrc
Expand Up @@ -52,16 +52,16 @@
"vars-on-top": 2,
"camelcase": [2, {"properties": "never"}],
"semi": [0, "always"],
"react/prop-types": 1,
"react/prop-types": 0,
"react/jsx-no-undef": 2,
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/no-did-mount-set-state": 1,
"react/no-did-update-set-state": 1,
"react/no-did-mount-set-state": 2,
"react/no-did-update-set-state": 2,
"react/jsx-wrap-multilines": 1,
"react/react-in-jsx-scope": 1,
"react/no-unknown-property": 2,
"react/no-is-mounted": 0,
"react/no-is-mounted": 2,
"jsx-extras/jsx-no-string-literals": 1,

"promise/param-names": 1,
Expand Down
7 changes: 3 additions & 4 deletions client/src/app/components/alertAjax.js
Expand Up @@ -13,10 +13,9 @@ export default (context) => {
return null;
}
debug('error:', error);
const status = _.get(error, 'response.status');
const message = _.get(error, 'response.data.error.message');
if (!message || !_.includes([401, 422], status)) {
return null;
let message = _.get(error, 'response.data.error.message');
if (!message) {
message = error.message
}
return (<Alert type="danger" className={className} message={message}/>)
}
Expand Down
275 changes: 125 additions & 150 deletions client/src/app/components/restTableComponent.js
@@ -1,163 +1,138 @@
import React, {PropTypes} from 'react';
import React from 'react';
import {
Table
Table
} from 'reactabular';
import tr from 'i18next';
import mobx from 'mobx';
import {observer} from 'mobx-react';
import Paginator from 'react-pagify';
import segmentize from 'segmentize';
import Spinner from 'components/spinner';
import Alert from 'components/alert'
import alertAjax from 'components/alertAjax';
import Debug from 'debug';
let debug = new Debug("components:resttable");

import 'react-pagify/style.css';

export default React.createClass({
propTypes: {
getData: PropTypes.func.isRequired,
columns: PropTypes.array.isRequired,
onRow: PropTypes.func
export default (context, {getData, columns}) => {
const {tr} = context;
const AlertAjax = alertAjax(context);
const store = mobx.observable({
loading: false,
count: 0,
data: [],
error: null,
pagination: {
page: 1,
perPage: 100
},
getInitialState () {
return {
loading: false,
count: 0,
data: [],
pagination: {
page: 1,
perPage: 100
}
};
},
componentDidMount () {
//debug('componentDidMount ', this.props);
this.onSelectPage(1, this.props);
},
componentWillReceiveProps(props){
//debug('componentWillReceiveProps ', props);
this.onSelectPage(1, props);
},
renderLoading(){
if(this.state.loading){
return (<Spinner/>);
}
},
renderError(){
let {error} = this.state;
if(!error) return;
return (
<Alert
type="danger"
name={error.name}
message={error.statusText}
code={error.status}
/>
);
},
render() {
//debug('render ', this.state);
return (
<div>
{this.renderError()}
{this.renderTable()}
{this.renderLoading()}
</div>
);
},
renderPagination(){
let {count, pagination} = this.state;
let pages = Math.ceil(count / pagination.perPage);
if(pages <= 1){
return;
}
return (
<div className='controls'>
<div className='pagination'>
<Paginator.Context
className="pagify-pagination"
segments={segmentize({
page: pagination.page,
pages: pages,
beginPages: 3,
endPages: 3,
sidePages: 2
})}
onSelect={this.onSelectPage}>
<Paginator.Button page={pagination.page - 1}>{tr.t('Previous')}</Paginator.Button>

<Paginator.Segment field="beginPages" />

<Paginator.Ellipsis className="ellipsis"
previousField="beginPages" nextField="previousPages" />

<Paginator.Segment field="previousPages" />
<Paginator.Segment field="centerPage" className="selected" />
<Paginator.Segment field="nextPages" />

<Paginator.Ellipsis className="ellipsis"
previousField="nextPages" nextField="endPages" />

<Paginator.Segment field="endPages" />

<Paginator.Button page={pagination.page + 1}>{tr.t('Next')}</Paginator.Button>
</Paginator.Context>

</div>
</div>
);
},
renderTable () {
let {data} = this.state;
//console.log("renderTable props:", this.props)
//console.log("renderTable state:", this.state)
if(this.state.error) return;
return (
<div>
{this.renderPagination()}
<Table.Provider
className="table"
columns={this.props.columns}
>
<Table.Header />
<Table.Body rows={data} rowKey="id" onRow={this.props.onRow}/>
</Table.Provider>
</div>
);
},
onSelectPage(page){
this.setSelectPage(page, this.props);
},
setSelectPage(page, props){
debug('onSelectPage ', page);
let {pagination} = this.state;
if(page <= 0){
return;
}
this.setState({loading: true});
props.getData({
offset: pagination.perPage * (page - 1),
limit: pagination.perPage
})
.then(result => {
pagination.page = page;
if (this.isMounted()) {
this.setState({
count: result.count,
data: result.data,
pagination: pagination,
loading: false
});
}
return true;
selectPage: mobx.action(async function (page) {
debug('onSelectPage ', page);
if (page <= 0) {
return;
}
this.loading = true;

try {
const result = await getData({
offset: this.pagination.perPage * (page - 1),
limit: this.pagination.perPage
})
.catch(err => {
debug('error: ', err);
if (this.isMounted()) {
this.setState({
error: err,
loading: false
});
}
});
console.log("rx DATA ", result.data.length)
this.pagination.page = page;
this.count = result.count;
this.data = result.data;
this.loading = false;
} catch (error) {
this.error = error;
this.loading = false;
}
}),
})

store.selectPage(1);

const Loading = observer(() => {
return store.loading ? <Spinner/> : null;
})

const Error = observer(() => {
let {error} = store;
if (!error) return null;
return <AlertAjax error={error} className='rest-table-error-view'/>
})

const Pagination = observer(() => {
console.log("Pagination:", store.count)
let {count, pagination} = store;
let pages = Math.ceil(count / pagination.perPage);
if (pages <= 1) {
return null;
}
});
return (
<div className='controls'>
<div className='pagination'>
<Paginator.Context
className="pagify-pagination"
segments={segmentize({
page: pagination.page,
pages: pages,
beginPages: 3,
endPages: 3,
sidePages: 2
}) }
onSelect={page => store.selectPage(page, getData)}>
<Paginator.Button page={pagination.page - 1}>{tr.t('Previous') }</Paginator.Button>

<Paginator.Segment field="beginPages" />

<Paginator.Ellipsis className="ellipsis"
previousField="beginPages" nextField="previousPages" />

<Paginator.Segment field="previousPages" />
<Paginator.Segment field="centerPage" className="selected" />
<Paginator.Segment field="nextPages" />

<Paginator.Ellipsis className="ellipsis"
previousField="nextPages" nextField="endPages" />

<Paginator.Segment field="endPages" />

<Paginator.Button page={pagination.page + 1}>{tr.t('Next') }</Paginator.Button>
</Paginator.Context>

</div>
</div>
);
})

const TableView = observer(({onRow}) => {
const {error} = store;
const data = mobx.toJS(store.data)
if (error) return null;
return (
<div>
<Pagination/>
<Table.Provider
className="table"
columns={columns}
>
<Table.Header />
{data && <Table.Body rows={data} rowKey="id" onRow={onRow}/>}
</Table.Provider>
</div>
);
})

function RestTable(props) {
debug('RestTable: ', props)
return (
<div>
<Error/>
<Loading/>
<TableView {...props}/>
</div>
)
}

return observer(RestTable);
}
9 changes: 6 additions & 3 deletions client/src/app/parts/admin/usersComponent.js
@@ -1,6 +1,6 @@
import React, {PropTypes} from 'react';
import moment from 'moment';
import RestTableComponent from 'components/restTableComponent';
import restTableComponent from 'components/restTableComponent';

import Debug from 'debug';
let debug = new Debug("components:users");
Expand Down Expand Up @@ -40,18 +40,21 @@ const columns = [
}
];

export default({tr, resources}) => {
export default(context) => {
const {tr, resources} = context
UsersComponent.propTypes = {
actions: PropTypes.object.isRequired
};

const RestTableComponent = restTableComponent(context, {getData: resources.getAll, columns})

function UsersComponent(props) {
debug(props);
return (
<div className="panel panel-default">
<div className="panel-heading">{tr.t('Users')}</div>
<div className="panel-body">
<RestTableComponent columns={columns} getData={resources.getAll} onRow={row => ({
<RestTableComponent onRow={row => ({
onClick: () => props.actions.selectOne(row.id)
})} rowKey='id'/>
</div>
Expand Down
1 change: 0 additions & 1 deletion client/src/app/parts/auth/authModule.js
@@ -1,6 +1,5 @@
import trim from 'lodash/trim';
import pick from 'lodash/pick';
import {bindActionCreators} from 'redux';
import {createActionAsync, createReducerAsync} from 'redux-act-async';
import {createAction, createReducer} from 'redux-act';
import {connect} from 'react-redux';
Expand Down
1 change: 0 additions & 1 deletion client/src/app/parts/auth/views/resetPasswordView.js
Expand Up @@ -51,7 +51,6 @@ export default (context) => {
}

function ResetPasswordForm({store, verifyResetPasswordToken, params}) {
const {errors} = store;
return (
<div id="forgot">
<DocTitle title="Reset password"/>
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/parts/profile/components/profileForm.js
@@ -1,4 +1,4 @@
import React, {PropTypes} from 'react';
import React from 'react';

import TextField from 'material-ui/TextField';
import LaddaButton from 'react-ladda';
Expand Down

0 comments on commit c1fd87f

Please sign in to comment.