From 85a9ab72af0c3350205a2f983ee1c73b1f02c166 Mon Sep 17 00:00:00 2001 From: Allen Date: Sun, 15 Jul 2018 14:11:15 +0800 Subject: [PATCH 1/2] fix #402 (#412) --- .../src/page.js | 39 ++++++++++++++++--- .../src/wrapper.js | 10 +++-- .../test/page.test.js | 38 +++++++++++++++++- .../test/wrapper.test.js | 17 -------- 4 files changed, 77 insertions(+), 27 deletions(-) diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js index aa3085a..3a9b863 100644 --- a/packages/react-bootstrap-table2-paginator/src/page.js +++ b/packages/react-bootstrap-table2-paginator/src/page.js @@ -1,12 +1,39 @@ +/* eslint no-param-reassign: 0 */ + +const getNormalizedPage = ( + page, + pageStartIndex +) => { + const offset = Math.abs(1 - pageStartIndex); + return page + offset; +}; + +const endIndex = ( + page, + sizePerPage, + pageStartIndex +) => (getNormalizedPage(page, pageStartIndex) * sizePerPage) - 1; + +const startIndex = ( + end, + sizePerPage, +) => end - (sizePerPage - 1); + +export const alignPage = (store, pageStartIndex, sizePerPage) => { + const end = endIndex(store.page, sizePerPage, pageStartIndex); + const dataSize = store.data.length; + + if (end - 1 > dataSize) { + return pageStartIndex; + } + return store.page; +}; + export const getByCurrPage = (store, pageStartIndex) => { const dataSize = store.data.length; if (!dataSize) return []; - const getNormalizedPage = () => { - const offset = Math.abs(1 - pageStartIndex); - return store.page + offset; - }; - const end = (getNormalizedPage() * store.sizePerPage) - 1; - const start = end - (store.sizePerPage - 1); + const end = endIndex(store.page, store.sizePerPage, pageStartIndex); + const start = startIndex(end, store.sizePerPage); const result = []; for (let i = start; i <= end; i += 1) { diff --git a/packages/react-bootstrap-table2-paginator/src/wrapper.js b/packages/react-bootstrap-table2-paginator/src/wrapper.js index ff88c59..784687a 100644 --- a/packages/react-bootstrap-table2-paginator/src/wrapper.js +++ b/packages/react-bootstrap-table2-paginator/src/wrapper.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import Const from './const'; import Pagination from './pagination'; -import { getByCurrPage } from './page'; +import { getByCurrPage, alignPage } from './page'; export default (Base, { remoteResolver @@ -49,17 +49,21 @@ export default (Base, { componentWillReceiveProps(nextProps) { let needNewState = false; let { currPage, currSizePerPage } = this.state; - const { page, sizePerPage, pageStartIndex, onPageChange } = nextProps.pagination.options; + const { page, sizePerPage, 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 if (nextProps.isDataChanged) { + currPage = alignPage(this.props.store, pageStartIndex, currSizePerPage); needNewState = true; } if (typeof currPage === 'undefined') { - currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX; + currPage = pageStartIndex; } if (typeof sizePerPage !== 'undefined') { diff --git a/packages/react-bootstrap-table2-paginator/test/page.test.js b/packages/react-bootstrap-table2-paginator/test/page.test.js index 1e092c9..bd63574 100644 --- a/packages/react-bootstrap-table2-paginator/test/page.test.js +++ b/packages/react-bootstrap-table2-paginator/test/page.test.js @@ -1,5 +1,5 @@ import Store from 'react-bootstrap-table-next/src/store'; -import { getByCurrPage } from '../src/page'; +import { getByCurrPage, alignPage } from '../src/page'; describe('Page Functions', () => { let data; @@ -48,4 +48,40 @@ describe('Page Functions', () => { }); }); }); + + describe('alignPage', () => { + const pageStartIndex = 1; + const sizePerPage = 10; + describe('if the length of store.data is less than the end page index', () => { + beforeEach(() => { + data = []; + for (let i = 0; i < 15; i += 1) { + data.push({ id: i, name: `test_name${i}` }); + } + store = new Store('id'); + store.data = data; + store.page = 2; + }); + + it('should return pageStartIndex argument', () => { + expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(pageStartIndex); + }); + }); + + describe('if the length of store.data is large than the end page index', () => { + beforeEach(() => { + data = []; + for (let i = 0; i < 30; i += 1) { + data.push({ id: i, name: `test_name${i}` }); + } + store = new Store('id'); + store.data = data; + store.page = 2; + }); + + it('should return current page', () => { + expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(store.page); + }); + }); + }); }); diff --git a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js index feea75c..f636fe3 100644 --- a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js +++ b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js @@ -176,23 +176,6 @@ describe('Wrapper', () => { expect(props.store.page).toEqual(instance.state.currPage); }); }); - - describe('when nextProps.isDataChanged is true, currPage is undefined and options.pageStartIndex exists', () => { - beforeEach(() => { - nextProps.isDataChanged = true; - nextProps.pagination.options.pageStartIndex = 0; - instance.state.currPage = undefined; - instance.componentWillReceiveProps(nextProps); - }); - - it('should setting currPage state correctly', () => { - expect(instance.state.currPage).toBe(nextProps.pagination.options.pageStartIndex); - }); - - it('should saving store.page correctly', () => { - expect(props.store.page).toEqual(instance.state.currPage); - }); - }); }); }); From 6f5bd1a13dda7962733790d7aa2992600b135231 Mon Sep 17 00:00:00 2001 From: Allen Date: Sun, 15 Jul 2018 14:43:29 +0800 Subject: [PATCH 2/2] fix #394 (#414) --- docs/README.md | 5 ++ .../header-columns/header-class-table.js | 52 +++++++++++++++++++ .../stories/index.js | 4 +- .../stories/stylesheet/columns/_index.scss | 4 ++ .../src/bootstrap-table.js | 2 + packages/react-bootstrap-table2/src/header.js | 6 ++- .../test/header.test.js | 19 +++++++ 7 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js diff --git a/docs/README.md b/docs/README.md index 83213a6..14782fe 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,6 +18,7 @@ * [id](#id) * [classes](#classes) * [wrapperClasses](#wrapperClasses) +* [headerClasses](#headerClasses) * [cellEdit](#cellEdit) * [selectRow](#selectRow) * [rowStyle](#rowStyle) @@ -111,6 +112,10 @@ Customize class on `table` element. ### wrapperClasses - [String] Customize class on the outer element which wrap up the `table` element. + +### headerClasses - [String] +Customize class on the header row(`tr`). + ### cellEdit - [Object] Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail. diff --git a/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js b/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js new file mode 100644 index 0000000..2c480c1 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/header-columns/header-class-table.js @@ -0,0 +1,52 @@ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const products = productsGenerator(); + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price' +}]; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price' +}]; + + +`; + +export default () => ( +
+ + { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index 64c4909..77dc4c9 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -33,6 +33,7 @@ import HeaderColumnEventTable from 'examples/header-columns/column-event-table'; import HeaderColumnClassTable from 'examples/header-columns/column-class-table'; import HeaderColumnStyleTable from 'examples/header-columns/column-style-table'; import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table'; +import HeaderClassTable from 'examples/header-columns/header-class-table'; // column filter import TextFilter from 'examples/column-filter/text-filter'; @@ -165,7 +166,8 @@ storiesOf('Work on Header Columns', module) .add('Column Event', () => ) .add('Customize Column Class', () => ) .add('Customize Column Style', () => ) - .add('Customize Column HTML attribute', () => ); + .add('Customize Column HTML attribute', () => ) + .add('Header Class', () => ); storiesOf('Column Filter', module) .add('Text Filter', () => ) diff --git a/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss b/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss index 3468c70..a0ec3d1 100644 --- a/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss +++ b/packages/react-bootstrap-table2-example/stories/stylesheet/columns/_index.scss @@ -9,4 +9,8 @@ .demo-row-odd { background-color: $green-lighten-4; +} + +.header-class { + background-color: $green-lighten-4; } \ No newline at end of file diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index fe6865c..e9ee145 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -86,6 +86,7 @@ class BootstrapTable extends PropsBaseResolver(Component) { { tableCaption }
{ const { ROW_SELECT_DISABLED } = Const; const { + className, columns, onSort, onFilter, @@ -21,7 +22,7 @@ const Header = (props) => { return ( - + { (selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn) ? : null @@ -60,7 +61,8 @@ Header.propTypes = { sortField: PropTypes.string, sortOrder: PropTypes.string, selectRow: PropTypes.object, - onExternalFilter: PropTypes.func + onExternalFilter: PropTypes.func, + className: PropTypes.string }; export default Header; diff --git a/packages/react-bootstrap-table2/test/header.test.js b/packages/react-bootstrap-table2/test/header.test.js index c502602..d8db9cd 100644 --- a/packages/react-bootstrap-table2/test/header.test.js +++ b/packages/react-bootstrap-table2/test/header.test.js @@ -29,6 +29,25 @@ describe('Header', () => { }); }); + describe('className prop is exists', () => { + const className = 'test-class'; + + beforeEach(() => { + wrapper = shallow( +
+ ); + }); + + it('should render successfully', () => { + expect(wrapper.length).toBe(1); + expect(wrapper.find(`.${className}`).length).toBe(1); + }); + }); + describe('header with columns enable sort', () => { const sortField = columns[1].dataField;