Ivan - Add pagination to table [skip ci]
This commit is contained in:
parent
abea0bbb97
commit
65630d1b15
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue