Ivan - Add pagination to table [skip ci]

This commit is contained in:
ivan 2016-12-15 18:33:54 -03:00
parent abea0bbb97
commit 65630d1b15
4 changed files with 118 additions and 15 deletions

View File

@ -1,6 +1,6 @@
const Menu = ReactMock();
const Pagination = ReactMock();
const Table = requireUnit('core-components/table', {
'core-components/menu': Menu
'core-components/pagination': Pagination
});
describe('Table component', function () {
@ -26,7 +26,7 @@ describe('Table component', function () {
<Table headers={headers} rows={rows} {...props} />
);
menu = TestUtils.scryRenderedComponentsWithType(table, Menu)[0];
menu = TestUtils.scryRenderedComponentsWithType(table, Pagination)[0];
tr = TestUtils.scryRenderedDOMComponentsWithTag(table, 'tr');
th = TestUtils.scryRenderedDOMComponentsWithTag(table, 'th');
}
@ -82,10 +82,9 @@ describe('Table component', function () {
expect(tr[3].children[0].textContent).to.equal('Row3 header1');
expect(tr[3].children[1].textContent).to.equal('Row3 header2');
expect(menu.props.type).to.equal('navigation');
expect(menu.props.items).to.deep.equal([{content: 1}, {content: 2}, {content: 3}]);
expect(menu.props.pages).to.equal(3);
menu.props.onItemClick(1);
menu.props.onChange(2);
tr = TestUtils.scryRenderedDOMComponentsWithTag(table, 'tr');
expect(tr.length).to.equal(4);
@ -96,7 +95,7 @@ describe('Table component', function () {
expect(tr[3].children[0].textContent).to.equal('Row6 header1');
expect(tr[3].children[1].textContent).to.equal('Row6 header2');
menu.props.onItemClick(2);
menu.props.onChange(3);
tr = TestUtils.scryRenderedDOMComponentsWithTag(table, 'tr');
expect(tr.length).to.equal(3);

View File

@ -69,6 +69,10 @@ $transition: background-color 0.3s ease, color 0.3s ease;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
&:focus {
outline: none;
}
}
.menu__list-item_selected {

View File

@ -0,0 +1,101 @@
import React from 'react';
import _ from 'lodash';
import Menu from 'core-components/menu';
class Pagination extends React.Component {
static propTypes = {
pages: React.PropTypes.number.isRequired,
pageRangeDisplayed: React.PropTypes.number,
marginPagesDisplayed: React.PropTypes.number,
page: React.PropTypes.number
};
static defaultProps = {
pageRangeDisplayed: 5,
marginPagesDisplayed: 2
};
state = {
page: 1
};
render() {
return (
<Menu {...this.getProps()}/>
);
}
getProps() {
let props = _.clone(this.props);
let pageList = this.getItems();
props.items = pageList.map(page => {return {content: page}});
props.selectedIndex = _.indexOf(pageList, this.getPage());
props.onItemClick = this.onItemClick.bind(this);
props.type = 'navigation';
delete props.page;
delete props.pages;
delete props.pageRangeDisplayed;
delete props.marginPagesDisplayed;
return props;
}
getItems() {
const pages = this.props.pages;
const pageRangeDisplayed = this.props.pageRangeDisplayed;
const marginPagesDisplayed = this.props.marginPagesDisplayed;
const page = this.getPage();
let totalItems = [];
if(pages <= pageRangeDisplayed + 2 * marginPagesDisplayed) {
return _.range(1, pages + 1);
}
if (page <= pageRangeDisplayed) {
totalItems = totalItems.concat(_.range(1, (page > pageRangeDisplayed - marginPagesDisplayed + 1) ? pageRangeDisplayed +1 + marginPagesDisplayed : pageRangeDisplayed + 1));
totalItems.push('...');
totalItems = totalItems.concat(_.range(pages - marginPagesDisplayed + 1, pages + 1));
} else {
totalItems = totalItems.concat(_.range(1, marginPagesDisplayed + 1));
totalItems.push('...');
if(page > pages - pageRangeDisplayed) {
totalItems = totalItems.concat(_.range((page < pages - pageRangeDisplayed + marginPagesDisplayed) ? pages - pageRangeDisplayed - marginPagesDisplayed + 1 : pages - pageRangeDisplayed + 1, pages + 1));
} else {
totalItems = totalItems.concat(_.range(page - Math.floor(pageRangeDisplayed / 2), page + Math.floor(pageRangeDisplayed / 2) + 1));
totalItems.push('...');
totalItems = totalItems.concat(_.range(pages - marginPagesDisplayed + 1, pages + 1));
}
}
return totalItems;
}
onItemClick(index) {
let items = this.getItems();
let page;
if(items[index] === '...') {
page = Math.floor((items[index-1] + items[index+1]) / 2);
} else {
page = items[index];
}
this.setState({page});
if(this.props.onChange) {
this.props.onChange(page);
}
}
getPage() {
return (this.props.page !== undefined) ? this.props.page : this.state.page;
}
}
export default Pagination;

View File

@ -2,7 +2,7 @@ import React from 'react';
import _ from 'lodash';
import classNames from 'classnames';
import Menu from 'core-components/menu';
import Pagination from 'core-components/pagination';
import Icon from 'core-components/icon';
import Loading from 'core-components/loading';
@ -97,6 +97,7 @@ class Table extends React.Component {
};
return (
<td className={classNames(classes)} key={key}>{row[key]}</td>
);
}
@ -106,10 +107,8 @@ class Table extends React.Component {
}
renderNavigation() {
const items = _.range(1, this.getPages()).map((index) => {return {content: index};});
return (
<Menu className="table__navigation" type="navigation" items={items} selectedIndex={this.getPageNumber() - 1} onItemClick={this.onNavigationItemClick.bind(this)} tabbable/>
<Pagination className="table__navigation" page={this.getPageNumber()} pages={this.getPages()} onChange={this.onNavigationChange.bind(this)} tabbable/>
);
}
@ -131,13 +130,13 @@ class Table extends React.Component {
return classNames(classes);
}
onNavigationItemClick(index) {
onNavigationChange(index) {
this.setState({
page: index + 1
page: index
});
if(this.props.onPageChange) {
this.props.onPageChange({target: {value: index + 1}});
this.props.onPageChange({target: {value: index}});
}
}
@ -158,7 +157,7 @@ class Table extends React.Component {
}
getPages() {
return (this.props.pages !== undefined) ? this.props.pages + 1 : Math.ceil(this.props.rows.length / this.props.pageSize) + 1;
return (this.props.pages !== undefined) ? this.props.pages : Math.ceil(this.props.rows.length / this.props.pageSize);
}
getPageNumber() {