Compare commits

...

15 Commits

Author SHA1 Message Date
AllenFang
345cb83493 Publish
- react-bootstrap-table2-example@1.0.2
 - react-bootstrap-table2-paginator@1.0.2
 - react-bootstrap-table2-toolkit@1.0.2
 - react-bootstrap-table-next@1.1.2
2018-08-21 17:05:08 +08:00
Allen
6e526f455b Merge pull request #500 from react-bootstrap-table/develop
20180821 release
2018-08-21 17:03:00 +08:00
AllenFang
b05cf48f36 Merge branch 'COzero-issue-363' into develop 2018-08-20 23:36:42 +08:00
AllenFang
28249c9089 fixed version 2018-08-20 23:36:22 +08:00
AllenFang
2b6081ab31 Merge branch 'issue-363' of https://github.com/COzero/react-bootstrap-table2 into COzero-issue-363 2018-08-20 23:23:32 +08:00
AllenFang
c935447266 Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-08-20 22:59:36 +08:00
AllenFang
ba1d6fa3ed fix #498 2018-08-20 22:59:14 +08:00
Allen
1b3b68f8a7 fix controlled page state will effect the internal page state when internal table rerender (#492) 2018-08-19 12:43:52 +08:00
copas2
4a3486cc3c fix #488
* updated test for pagination fix

* suspected bug in page.js

Local pagination aligning returns start page when eg editing cell locally. This results in state change, too. Not really getting the purpose of the original idea. Please consider this modification. It only checks if page fits in the data size range. As I saw, this alignment only affects local pagination, not remote.

* modified fix w/ pageStartIndex

I forgot to mind pageStartIndex
2018-08-16 17:16:47 +08:00
Allen
cb49455a4e Merge pull request #489 from react-bootstrap-table/bugfix/infinite-remote-search
Bugfix/infinite remote search
2018-08-15 23:16:52 +08:00
AllenFang
5e63d6ae59 avoid infinite remote search 2018-08-15 23:08:46 +08:00
AllenFang
e3ca6f2c24 Publish
- react-bootstrap-table-next@1.1.1
2018-08-13 22:01:15 +08:00
Jeremy Nagel
96d33a60ba Add snapshot tests 2018-08-13 16:50:43 +10:00
Jeremy Nagel
03389aece0 Merge branch 'master' of github.com:react-bootstrap-table/react-bootstrap-table2 into issue-363 2018-08-13 16:45:34 +10:00
Jeremy Nagel
f35d644608 [BUGFIX] Fix issue with missing onChange prop for selection checkbox 2018-07-16 11:18:02 +10:00
18 changed files with 150 additions and 182 deletions

View File

@@ -52,6 +52,7 @@
"css-loader": "0.28.1",
"enzyme": "3.3.0",
"enzyme-adapter-react-16": "1.1.1",
"enzyme-to-json": "3.3.4",
"eslint": "4.5.0",
"eslint-config-airbnb": "15.1.0",
"eslint-loader": "1.9.0",

View File

@@ -22,8 +22,19 @@ const columns = [{
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
// ...
const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
const NoDataIndication = () => (
<div className="spinner">
<div className="rect1" />
<div className="rect2" />
<div className="rect3" />
<div className="rect4" />
<div className="rect5" />
</div>
);
const Table = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
<div>
<BootstrapTable
remote
@@ -32,12 +43,13 @@ const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize })
columns={ columns }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
noDataIndication={ () => <NoDataIndication /> }
/>
<Code>{ sourceCode }</Code>
</div>
);
class Container extends React.Component {
class EmptyTableOverlay extends React.Component {
constructor(props) {
super(props);
this.state = {
@@ -47,7 +59,7 @@ class Container extends React.Component {
};
}
handleTableChange = ({ page, sizePerPage }) => {
handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({
@@ -55,13 +67,14 @@ class Container extends React.Component {
data: products.slice(currentIndex, currentIndex + sizePerPage),
sizePerPage
}));
}, 2000);
}, 3000);
this.setState(() => ({ data: [] }));
}
render() {
const { data, sizePerPage, page } = this.state;
return (
<RemotePagination
<Table
data={ data }
page={ page }
sizePerPage={ sizePerPage }

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-example",
"version": "1.0.1",
"version": "1.0.2",
"description": "",
"main": "index.js",
"private": true,

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-paginator",
"version": "1.0.1",
"version": "1.0.2",
"description": "it's the pagination addon for react-bootstrap-table2",
"main": "./lib/index.js",
"repository": {

View File

@@ -54,16 +54,13 @@ export default (
componentWillReceiveProps(nextProps) {
let needNewState = false;
let { currPage, currSizePerPage } = this;
const { page, sizePerPage, onPageChange } = nextProps.pagination.options;
let { currPage } = this;
const { currSizePerPage } = this;
const { onPageChange } = nextProps.pagination.options;
const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
if (typeof page !== 'undefined' && currPage !== page) { // user defined page
currPage = page;
needNewState = true;
} else {
// user should align the page when the page is not fit to the data size when remote enable
if (!isRemotePagination()) {
const newPage = alignPage(nextProps.data, currPage, currSizePerPage, pageStartIndex);
@@ -72,12 +69,6 @@ export default (
needNewState = true;
}
}
}
if (typeof sizePerPage !== 'undefined' && currSizePerPage !== sizePerPage) {
currSizePerPage = sizePerPage;
needNewState = true;
}
if (needNewState) {
if (onPageChange) {

View File

@@ -23,10 +23,9 @@ export const alignPage = (
sizePerPage,
pageStartIndex
) => {
const end = endIndex(page, sizePerPage, pageStartIndex);
const dataSize = data.length;
if (end - 1 > dataSize) {
if (page < pageStartIndex || page > (Math.floor(dataSize / sizePerPage) + pageStartIndex)) {
return pageStartIndex;
}
return page;

View File

@@ -126,69 +126,6 @@ describe('PaginationContext', () => {
let instance;
let nextProps;
describe('when nextProps.pagination.options.page is existing', () => {
const onPageChange = jest.fn();
afterEach(() => {
onPageChange.mockReset();
});
describe('and if it is different with currPage', () => {
beforeEach(() => {
wrapper = shallow(shallowContext());
instance = wrapper.instance();
wrapper.render();
nextProps = {
data,
pagination: {
options: {
page: 2,
onPageChange
}
}
};
instance.componentWillReceiveProps(nextProps);
});
it('should call options.onPageChange', () => {
expect(onPageChange).toHaveBeenCalledTimes(1);
expect(onPageChange).toHaveBeenCalledWith(
instance.currPage,
instance.currSizePerPage
);
});
it('should set correct currPage', () => {
expect(instance.currPage).toEqual(nextProps.pagination.options.page);
});
});
describe('and if it is same as currPage', () => {
beforeEach(() => {
wrapper = shallow(shallowContext());
instance = wrapper.instance();
wrapper.render();
nextProps = {
data,
pagination: {
options: {
page: 1,
onPageChange
}
}
};
instance.componentWillReceiveProps(nextProps);
});
it('shouldn\'t call options.onPageChange', () => {
expect(onPageChange).toHaveBeenCalledTimes(0);
});
it('should have correct currPage', () => {
expect(instance.currPage).toEqual(nextProps.pagination.options.page);
});
});
});
describe('when nextProps.pagination.options.page is not existing', () => {
beforeEach(() => {
wrapper = shallow(shallowContext({
@@ -206,69 +143,6 @@ describe('PaginationContext', () => {
});
});
describe('when nextProps.pagination.options.sizePerPage is existing', () => {
const onPageChange = jest.fn();
afterEach(() => {
onPageChange.mockReset();
});
describe('and if it is different with currSizePerPage', () => {
beforeEach(() => {
wrapper = shallow(shallowContext());
instance = wrapper.instance();
wrapper.render();
nextProps = {
data,
pagination: {
options: {
sizePerPage: Const.SIZE_PER_PAGE_LIST[2],
onPageChange
}
}
};
instance.componentWillReceiveProps(nextProps);
});
it('should call options.onPageChange', () => {
expect(onPageChange).toHaveBeenCalledTimes(1);
expect(onPageChange).toHaveBeenCalledWith(
instance.currPage,
instance.currSizePerPage
);
});
it('should set correct currSizePerPage', () => {
expect(instance.currSizePerPage).toEqual(nextProps.pagination.options.sizePerPage);
});
});
describe('and if it is same as currSizePerPage', () => {
beforeEach(() => {
wrapper = shallow(shallowContext());
instance = wrapper.instance();
wrapper.render();
nextProps = {
data,
pagination: {
options: {
sizePerPage: Const.SIZE_PER_PAGE_LIST[0],
onPageChange
}
}
};
instance.componentWillReceiveProps(nextProps);
});
it('shouldn\'t call options.onPageChange', () => {
expect(onPageChange).toHaveBeenCalledTimes(0);
});
it('should have correct currSizePerPage', () => {
expect(instance.currSizePerPage).toEqual(nextProps.pagination.options.sizePerPage);
});
});
});
describe('when nextProps.pagination.options.sizePerPage is not existing', () => {
beforeEach(() => {
wrapper = shallow(shallowContext({
@@ -281,10 +155,53 @@ describe('PaginationContext', () => {
instance.componentWillReceiveProps(nextProps);
});
it('should not set currPage', () => {
it('should not set currSizePerPage', () => {
expect(instance.currSizePerPage).toEqual(Const.SIZE_PER_PAGE_LIST[2]);
});
});
describe('when page is not align', () => {
beforeEach(() => {
wrapper = shallow(shallowContext({
...defaultPagination,
page: 2
}));
instance = wrapper.instance();
wrapper.render();
nextProps = {
data: [],
pagination: { ...defaultPagination }
};
instance.componentWillReceiveProps(nextProps);
});
it('should reset currPage to first page', () => {
expect(instance.currPage).toEqual(1);
});
describe('if options.onPageChange is defined', () => {
const onPageChange = jest.fn();
beforeEach(() => {
onPageChange.mockClear();
wrapper = shallow(shallowContext({
...defaultPagination,
page: 2
}));
instance = wrapper.instance();
wrapper.render();
nextProps = {
data: [],
pagination: { ...defaultPagination, options: { onPageChange } }
};
instance.componentWillReceiveProps(nextProps);
});
it('should call options.onPageChange correctly', () => {
expect(onPageChange).toHaveBeenCalledTimes(1);
expect(onPageChange).toHaveBeenCalledWith(instance.currPage, instance.currSizePerPage);
});
});
});
});
describe('handleChangePage', () => {

View File

@@ -45,8 +45,8 @@ describe('Page Functions', () => {
describe('alignPage', () => {
const pageStartIndex = 1;
const sizePerPage = 10;
const page = 2;
describe('if the length of store.data is less than the end page index', () => {
const page = 3;
describe('if the page does not fit the pages interval calculated from the length of store.data', () => {
beforeEach(() => {
data = [];
for (let i = 0; i < 15; i += 1) {

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-toolkit",
"version": "1.0.1",
"version": "1.0.2",
"description": "The toolkit for react-bootstrap-table2",
"main": "./lib/index.js",
"repository": {

View File

@@ -20,11 +20,26 @@ export default (options = {
searchText: PropTypes.string
}
constructor(props) {
super(props);
this.performRemoteSearch = props.searchText !== '';
}
componentWillReceiveProps(nextProps) {
if (isRemoteSearch()) {
if (nextProps.searchText !== this.props.searchText) {
this.performRemoteSearch = true;
} else {
this.performRemoteSearch = false;
}
}
}
search() {
const { data, columns } = this.props;
let { searchText } = this.props;
if (isRemoteSearch()) {
if (isRemoteSearch() && this.performRemoteSearch) {
handleRemoteSearchChange(searchText);
return data;
}

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table-next",
"version": "1.1.0",
"version": "1.1.2",
"description": "Next generation of react-bootstrap-table",
"main": "./lib/index.js",
"repository": {
@@ -36,7 +36,8 @@
}
],
"dependencies": {
"classnames": "2.2.5"
"classnames": "2.2.5",
"underscore": "1.9.1"
},
"peerDependencies": {
"classnames": "^2.2.5",

View File

@@ -75,6 +75,7 @@ export default class SelectionCell extends Component {
checked={ selected }
disabled={ disabled }
className={ bootstrap4 ? 'selection-input-4' : '' }
onChange={ () => {} }
/>
)
}

View File

@@ -12,6 +12,7 @@ export const CheckBox = ({ className, checked, indeterminate }) => (
ref={ (input) => {
if (input) input.indeterminate = indeterminate; // eslint-disable-line no-param-reassign
} }
onChange={ () => {} }
/>
);

View File

@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SelectionCell /> render should render component correctly 1`] = `
<td
onClick={[Function]}
>
<input
checked={true}
className=""
onChange={[Function]}
type="checkbox"
/>
</td>
`;

View File

@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<CheckBox /> render should render component correctly 1`] = `
<input
checked={true}
onChange={[Function]}
type="checkbox"
/>
`;

View File

@@ -1,6 +1,7 @@
import 'jsdom-global/register';
import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import sinon from 'sinon';
import { shallowWithContext } from '../test-helpers/new-context';
@@ -61,7 +62,8 @@ describe('<SelectionCell />', () => {
mode={ mode }
rowIndex={ rowIndex }
onRowSelect={ mockOnRowSelect }
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
wrapper.find('td').simulate('click');
});
@@ -72,9 +74,7 @@ describe('<SelectionCell />', () => {
it('should calling onRowSelect callback correctly', () => {
expect(mockOnRowSelect.calledOnce).toBe(true);
expect(
mockOnRowSelect.calledWith(rowKey, !selected, rowIndex)
).toBe(true);
expect(mockOnRowSelect.calledWith(rowKey, !selected, rowIndex)).toBe(true);
});
});
@@ -88,7 +88,8 @@ describe('<SelectionCell />', () => {
rowIndex={ rowIndex }
onRowSelect={ mockOnRowSelect }
disabled
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
wrapper.find('td').simulate('click');
});
@@ -111,7 +112,8 @@ describe('<SelectionCell />', () => {
mode="radio"
rowIndex={ rowIndex }
onRowSelect={ mockOnRowSelect }
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
});
@@ -132,11 +134,12 @@ describe('<SelectionCell />', () => {
rowIndex={ rowIndex }
selected
onRowSelect={ mockOnRowSelect }
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
});
it('should be called with correct paramters', () => {
it('should be called with correct parameters', () => {
// first click
wrapper.find('td').simulate('click');
expect(mockOnRowSelect.callCount).toBe(1);
@@ -151,12 +154,8 @@ describe('<SelectionCell />', () => {
beforeEach(() => {
wrapper = shallowWithContext(
<SelectionCell
rowKey={ 1 }
mode={ mode }
rowIndex={ rowIndex }
selected={ selected }
/>, { bootstrap4: false }
<SelectionCell rowKey={ 1 } mode={ mode } rowIndex={ rowIndex } selected={ selected } />,
{ bootstrap4: false }
);
});
@@ -165,6 +164,7 @@ describe('<SelectionCell />', () => {
expect(wrapper.find('input')).toHaveLength(1);
expect(wrapper.find('input').get(0).props.type).toBe(mode);
expect(wrapper.find('input').get(0).props.checked).toBe(selected);
expect(toJson(wrapper)).toMatchSnapshot();
});
describe('when disabled prop give as true', () => {
@@ -176,7 +176,8 @@ describe('<SelectionCell />', () => {
rowIndex={ rowIndex }
selected={ selected }
disabled
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
});
@@ -198,7 +199,8 @@ describe('<SelectionCell />', () => {
rowIndex={ rowIndex }
selected={ selected }
selectionRenderer={ selectionRenderer }
/>, { bootstrap4: false }
/>,
{ bootstrap4: false }
);
});
@@ -219,12 +221,8 @@ describe('<SelectionCell />', () => {
describe('when bootstrap4 context is true', () => {
beforeEach(() => {
wrapper = shallowWithContext(
<SelectionCell
rowKey={ 1 }
mode={ mode }
rowIndex={ rowIndex }
selected={ selected }
/>, { bootstrap4: true }
<SelectionCell rowKey={ 1 } mode={ mode } rowIndex={ rowIndex } selected={ selected } />,
{ bootstrap4: true }
);
});

View File

@@ -1,5 +1,6 @@
import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import sinon from 'sinon';
import { shallowWithContext } from '../test-helpers/new-context';
@@ -201,6 +202,7 @@ describe('<CheckBox />', () => {
expect(wrapper.find('input').length).toBe(1);
expect(wrapper.find('input').prop('checked')).toBe(checked);
expect(wrapper.find('input').prop('type')).toBe('checkbox');
expect(toJson(wrapper)).toMatchSnapshot();
});
});
});

View File

@@ -2711,6 +2711,12 @@ enzyme-adapter-utils@^1.3.0:
object.assign "^4.1.0"
prop-types "^15.6.0"
enzyme-to-json@3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.3.4.tgz#67c6040e931182f183418af2eb9f4323258aa77f"
dependencies:
lodash "^4.17.4"
enzyme@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.3.0.tgz#0971abd167f2d4bf3f5bd508229e1c4b6dc50479"