From f35d644608b0e8eb1642984b467e5be6c69d5cf3 Mon Sep 17 00:00:00 2001 From: Jeremy Nagel Date: Mon, 16 Jul 2018 11:18:02 +1000 Subject: [PATCH 1/7] [BUGFIX] Fix issue with missing onChange prop for selection checkbox --- .../src/row-selection/selection-header-cell.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js index 9879026..c92e7c3 100644 --- a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js +++ b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js @@ -77,6 +77,7 @@ export default class SelectionHeaderCell extends Component { { ...this.props } checked={ checked } indeterminate={ indeterminate } + onChange={ this.handleCheckBoxClick } /> ); attrs.onClick = this.handleCheckBoxClick; From 96d33a60ba14874ae6fb5592be50962a15bd2d5c Mon Sep 17 00:00:00 2001 From: Jeremy Nagel Date: Mon, 13 Aug 2018 16:50:43 +1000 Subject: [PATCH 2/7] Add snapshot tests --- .../__snapshots__/selection-cell.test.js.snap | 14 ++++++++++++++ .../selection-header-cell.test.js.snap | 9 +++++++++ .../test/row-selection/selection-cell.test.js | 8 +++++++- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-cell.test.js.snap create mode 100644 packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-header-cell.test.js.snap diff --git a/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-cell.test.js.snap b/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-cell.test.js.snap new file mode 100644 index 0000000..2f5e4dc --- /dev/null +++ b/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-cell.test.js.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` render should render component correctly 1`] = ` + + + +`; diff --git a/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-header-cell.test.js.snap b/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-header-cell.test.js.snap new file mode 100644 index 0000000..522b3e5 --- /dev/null +++ b/packages/react-bootstrap-table2/test/row-selection/__snapshots__/selection-header-cell.test.js.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` render should render component correctly 1`] = ` + +`; diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js index 967c626..311c361 100644 --- a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js +++ b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js @@ -170,7 +170,13 @@ describe('', () => { describe('when disabled prop give as true', () => { beforeEach(() => { wrapper = shallowWithContext( - , + , { bootstrap4: false } ); }); From 5e63d6ae59434bb0ff586fd186019c42c9487a11 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Wed, 15 Aug 2018 23:08:46 +0800 Subject: [PATCH 3/7] avoid infinite remote search --- .../src/search/context.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/react-bootstrap-table2-toolkit/src/search/context.js b/packages/react-bootstrap-table2-toolkit/src/search/context.js index 67935bf..c579999 100644 --- a/packages/react-bootstrap-table2-toolkit/src/search/context.js +++ b/packages/react-bootstrap-table2-toolkit/src/search/context.js @@ -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; } From 4a3486cc3c00c527b921c6259e9fc25e275033f6 Mon Sep 17 00:00:00 2001 From: copas2 Date: Thu, 16 Aug 2018 11:16:47 +0200 Subject: [PATCH 4/7] 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 --- packages/react-bootstrap-table2-paginator/src/page.js | 3 +-- packages/react-bootstrap-table2-paginator/test/page.test.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js index 40d2a8a..feb1f0a 100644 --- a/packages/react-bootstrap-table2-paginator/src/page.js +++ b/packages/react-bootstrap-table2-paginator/src/page.js @@ -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; diff --git a/packages/react-bootstrap-table2-paginator/test/page.test.js b/packages/react-bootstrap-table2-paginator/test/page.test.js index 28ab1e1..dad8742 100644 --- a/packages/react-bootstrap-table2-paginator/test/page.test.js +++ b/packages/react-bootstrap-table2-paginator/test/page.test.js @@ -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) { From 1b3b68f8a7f4048c94dccf6a096f2008c436ce76 Mon Sep 17 00:00:00 2001 From: Allen Date: Sun, 19 Aug 2018 12:43:52 +0800 Subject: [PATCH 5/7] fix controlled page state will effect the internal page state when internal table rerender (#492) --- .../src/context.js | 27 +-- .../test/context.test.js | 171 +++++------------- 2 files changed, 53 insertions(+), 145 deletions(-) diff --git a/packages/react-bootstrap-table2-paginator/src/context.js b/packages/react-bootstrap-table2-paginator/src/context.js index 10d72ff..eb58ceb 100644 --- a/packages/react-bootstrap-table2-paginator/src/context.js +++ b/packages/react-bootstrap-table2-paginator/src/context.js @@ -54,31 +54,22 @@ 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); - if (currPage !== newPage) { - currPage = newPage; - needNewState = true; - } + // 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); + if (currPage !== newPage) { + currPage = newPage; + needNewState = true; } } - if (typeof sizePerPage !== 'undefined' && currSizePerPage !== sizePerPage) { - currSizePerPage = sizePerPage; - needNewState = true; - } - if (needNewState) { if (onPageChange) { onPageChange(currPage, currSizePerPage); diff --git a/packages/react-bootstrap-table2-paginator/test/context.test.js b/packages/react-bootstrap-table2-paginator/test/context.test.js index 4b9c30d..9d13658 100644 --- a/packages/react-bootstrap-table2-paginator/test/context.test.js +++ b/packages/react-bootstrap-table2-paginator/test/context.test.js @@ -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', () => { From ba1d6fa3ed2f0ffa3500f77f38201a049275995a Mon Sep 17 00:00:00 2001 From: AllenFang Date: Mon, 20 Aug 2018 22:59:14 +0800 Subject: [PATCH 6/7] fix #498 --- .../loading-overlay/empty-table-overlay.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js b/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js index faa0261..6dadff3 100644 --- a/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js +++ b/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js @@ -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 = () => ( +
+
+
+
+
+
+
+); + +const Table = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
} /> { sourceCode }
); -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 ( - Date: Mon, 20 Aug 2018 23:36:22 +0800 Subject: [PATCH 7/7] fixed version --- package.json | 2 +- yarn.lock | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8830bfa..4437f6e 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "css-loader": "0.28.1", "enzyme": "3.3.0", "enzyme-adapter-react-16": "1.1.1", - "enzyme-to-json": "^3.3.4", + "enzyme-to-json": "3.3.4", "eslint": "4.5.0", "eslint-config-airbnb": "15.1.0", "eslint-loader": "1.9.0", diff --git a/yarn.lock b/yarn.lock index 4329d62..b44934f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"