Compare commits

...

4 Commits

Author SHA1 Message Date
AllenFang
2585a62697 Publish
- react-bootstrap-table2-example@0.1.11
 - react-bootstrap-table2-paginator@0.1.6
 - react-bootstrap-table-next@0.1.15
2018-07-15 16:08:59 +08:00
Allen
6afe58a081 Merge pull request #415 from react-bootstrap-table/develop
20180715 release
2018-07-15 16:02:47 +08:00
Allen
6f5bd1a13d fix #394 (#414) 2018-07-15 14:43:29 +08:00
Allen
85a9ab72af fix #402 (#412) 2018-07-15 14:18:21 +08:00
14 changed files with 169 additions and 33 deletions

View File

@@ -18,6 +18,7 @@
* [id](#id) * [id](#id)
* [classes](#classes) * [classes](#classes)
* [wrapperClasses](#wrapperClasses) * [wrapperClasses](#wrapperClasses)
* [headerClasses](#headerClasses)
* [cellEdit](#cellEdit) * [cellEdit](#cellEdit)
* [selectRow](#selectRow) * [selectRow](#selectRow)
* [rowStyle](#rowStyle) * [rowStyle](#rowStyle)
@@ -111,6 +112,10 @@ Customize class on `table` element.
### <a name='wrapperClasses'>wrapperClasses - [String]</a> ### <a name='wrapperClasses'>wrapperClasses - [String]</a>
Customize class on the outer element which wrap up the `table` element. Customize class on the outer element which wrap up the `table` element.
### <a name='headerClasses'>headerClasses - [String]</a>
Customize class on the header row(`tr`).
### <a name='cellEdit'>cellEdit - [Object]</a> ### <a name='cellEdit'>cellEdit - [Object]</a>
Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail. Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail.

View File

@@ -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'
}];
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
headerClasses="header-class"
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
headerClasses="header-class"
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

@@ -33,6 +33,7 @@ import HeaderColumnEventTable from 'examples/header-columns/column-event-table';
import HeaderColumnClassTable from 'examples/header-columns/column-class-table'; import HeaderColumnClassTable from 'examples/header-columns/column-class-table';
import HeaderColumnStyleTable from 'examples/header-columns/column-style-table'; import HeaderColumnStyleTable from 'examples/header-columns/column-style-table';
import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table'; import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
import HeaderClassTable from 'examples/header-columns/header-class-table';
// column filter // column filter
import TextFilter from 'examples/column-filter/text-filter'; import TextFilter from 'examples/column-filter/text-filter';
@@ -165,7 +166,8 @@ storiesOf('Work on Header Columns', module)
.add('Column Event', () => <HeaderColumnEventTable />) .add('Column Event', () => <HeaderColumnEventTable />)
.add('Customize Column Class', () => <HeaderColumnClassTable />) .add('Customize Column Class', () => <HeaderColumnClassTable />)
.add('Customize Column Style', () => <HeaderColumnStyleTable />) .add('Customize Column Style', () => <HeaderColumnStyleTable />)
.add('Customize Column HTML attribute', () => <HeaderColumnAttrsTable />); .add('Customize Column HTML attribute', () => <HeaderColumnAttrsTable />)
.add('Header Class', () => <HeaderClassTable />);
storiesOf('Column Filter', module) storiesOf('Column Filter', module)
.add('Text Filter', () => <TextFilter />) .add('Text Filter', () => <TextFilter />)

View File

@@ -10,3 +10,7 @@
.demo-row-odd { .demo-row-odd {
background-color: $green-lighten-4; background-color: $green-lighten-4;
} }
.header-class {
background-color: $green-lighten-4;
}

View File

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

View File

@@ -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) => { export const getByCurrPage = (store, pageStartIndex) => {
const dataSize = store.data.length; const dataSize = store.data.length;
if (!dataSize) return []; if (!dataSize) return [];
const getNormalizedPage = () => { const end = endIndex(store.page, store.sizePerPage, pageStartIndex);
const offset = Math.abs(1 - pageStartIndex); const start = startIndex(end, store.sizePerPage);
return store.page + offset;
};
const end = (getNormalizedPage() * store.sizePerPage) - 1;
const start = end - (store.sizePerPage - 1);
const result = []; const result = [];
for (let i = start; i <= end; i += 1) { for (let i = start; i <= end; i += 1) {

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import Const from './const'; import Const from './const';
import Pagination from './pagination'; import Pagination from './pagination';
import { getByCurrPage } from './page'; import { getByCurrPage, alignPage } from './page';
export default (Base, { export default (Base, {
remoteResolver remoteResolver
@@ -49,17 +49,21 @@ export default (Base, {
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
let needNewState = false; let needNewState = false;
let { currPage, currSizePerPage } = this.state; 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 if (typeof page !== 'undefined' && currPage !== page) { // user defined page
currPage = page; currPage = page;
needNewState = true; needNewState = true;
} else if (nextProps.isDataChanged) { } else if (nextProps.isDataChanged) {
currPage = alignPage(this.props.store, pageStartIndex, currSizePerPage);
needNewState = true; needNewState = true;
} }
if (typeof currPage === 'undefined') { if (typeof currPage === 'undefined') {
currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX; currPage = pageStartIndex;
} }
if (typeof sizePerPage !== 'undefined') { if (typeof sizePerPage !== 'undefined') {

View File

@@ -1,5 +1,5 @@
import Store from 'react-bootstrap-table-next/src/store'; import Store from 'react-bootstrap-table-next/src/store';
import { getByCurrPage } from '../src/page'; import { getByCurrPage, alignPage } from '../src/page';
describe('Page Functions', () => { describe('Page Functions', () => {
let data; 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);
});
});
});
}); });

View File

@@ -176,23 +176,6 @@ describe('Wrapper', () => {
expect(props.store.page).toEqual(instance.state.currPage); 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);
});
});
}); });
}); });

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table-next", "name": "react-bootstrap-table-next",
"version": "0.1.14", "version": "0.1.15",
"description": "Next generation of react-bootstrap-table", "description": "Next generation of react-bootstrap-table",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -86,6 +86,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
{ tableCaption } { tableCaption }
<Header <Header
columns={ columns } columns={ columns }
className={ this.props.headerClasses }
sortField={ store.sortField } sortField={ store.sortField }
sortOrder={ store.sortOrder } sortOrder={ store.sortOrder }
onSort={ this.props.onSort } onSort={ this.props.onSort }
@@ -155,6 +156,7 @@ BootstrapTable.propTypes = {
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
rowEvents: PropTypes.object, rowEvents: PropTypes.object,
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
headerClasses: PropTypes.string,
defaultSorted: PropTypes.arrayOf(PropTypes.shape({ defaultSorted: PropTypes.arrayOf(PropTypes.shape({
dataField: PropTypes.string.isRequired, dataField: PropTypes.string.isRequired,
order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired

View File

@@ -10,6 +10,7 @@ const Header = (props) => {
const { ROW_SELECT_DISABLED } = Const; const { ROW_SELECT_DISABLED } = Const;
const { const {
className,
columns, columns,
onSort, onSort,
onFilter, onFilter,
@@ -21,7 +22,7 @@ const Header = (props) => {
return ( return (
<thead> <thead>
<tr> <tr className={ className }>
{ {
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn) (selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn)
? <SelectionHeaderCell { ...selectRow } /> : null ? <SelectionHeaderCell { ...selectRow } /> : null
@@ -60,7 +61,8 @@ Header.propTypes = {
sortField: PropTypes.string, sortField: PropTypes.string,
sortOrder: PropTypes.string, sortOrder: PropTypes.string,
selectRow: PropTypes.object, selectRow: PropTypes.object,
onExternalFilter: PropTypes.func onExternalFilter: PropTypes.func,
className: PropTypes.string
}; };
export default Header; export default Header;

View File

@@ -29,6 +29,25 @@ describe('Header', () => {
}); });
}); });
describe('className prop is exists', () => {
const className = 'test-class';
beforeEach(() => {
wrapper = shallow(
<Header
{ ...mockHeaderResolvedProps }
columns={ columns }
className={ className }
/>
);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find(`.${className}`).length).toBe(1);
});
});
describe('header with columns enable sort', () => { describe('header with columns enable sort', () => {
const sortField = columns[1].dataField; const sortField = columns[1].dataField;