From e1e8c002714ccfd85b2f37490761371d35dbebe8 Mon Sep 17 00:00:00 2001 From: Allen Date: Sun, 29 Oct 2017 16:58:37 +0800 Subject: [PATCH] fix #64 * implement default sort * add story for default sort * add test for default sort * patch docs for default sort * a workaround to avoid render twice by story.add --- docs/README.md | 13 +++- .../examples/sort/default-sort-table.js | 59 +++++++++++++++++++ .../stories/index.js | 2 + .../src/bootstrap-table.js | 6 +- .../src/sort/wrapper.js | 17 +++++- .../react-bootstrap-table2/src/store/base.js | 6 +- .../test/sort/wrapper.test.js | 34 ++++++++++- .../test/store/base.test.js | 5 ++ 8 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 packages/react-bootstrap-table2-example/examples/sort/default-sort-table.js diff --git a/docs/README.md b/docs/README.md index 4140d37..1d45c9e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ * [condensed](#condensed) * [cellEdit](#cellEdit) * [selectRow](#selectRow) +* [defaultSorted](#defaultSorted) ### keyField(**required**) - [String] Tells `react-bootstrap-table2` which column is unique. @@ -41,4 +42,14 @@ Same as bootstrap `.table-condensed` class for making a table more compact by cu Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail. ### selectRow - [Object] -Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail. \ No newline at end of file +Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail. + +### defaultSorted - [Array] +`defaultSorted` accept an object array which allow you to define the default sort columns when first render. + +```js +const defaultSorted = [{ + dataField: 'name', // if dataField is not match to any column you defined, it will be ignored. + order: 'desc' // desc or asc +}]; +``` \ No newline at end of file diff --git a/packages/react-bootstrap-table2-example/examples/sort/default-sort-table.js b/packages/react-bootstrap-table2-example/examples/sort/default-sort-table.js new file mode 100644 index 0000000..0f238a8 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/sort/default-sort-table.js @@ -0,0 +1,59 @@ +/* eslint react/prefer-stateless-function: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table2'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const products = productsGenerator(); + +const columns = [{ + dataField: 'id', + text: 'Product ID', + sort: true +}, { + dataField: 'name', + text: 'Product Name', + sort: true +}, { + dataField: 'price', + text: 'Product Price', + sort: true +}]; + +const defaultSorted = [{ + dataField: 'name', + order: 'desc' +}]; + +const sourceCode = `\ +const columns = [{ + dataField: 'id', + text: 'Product ID', + sort: true +}, { + dataField: 'name', + text: 'Product Name', + sort: true +}, { + dataField: 'price', + text: 'Product Price', + sort: true +}]; + + +`; + + +class DefaultSortTable extends React.PureComponent { + render() { + return ( +
+ + { sourceCode } +
+ ); + } +} + +export default DefaultSortTable; diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index 99cee5a..98d0331 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -34,6 +34,7 @@ import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table'; // table sort import EnableSortTable from 'examples/sort/enable-sort-table'; +import DefaultSortTable from 'examples/sort/default-sort-table'; import CustomSortTable from 'examples/sort/custom-sort-table'; // cell editing @@ -104,6 +105,7 @@ storiesOf('Work on Header Columns', module) storiesOf('Sort Table', module) .add('Enable Sort', () => ) + .add('Default Sort Table', () => ) .add('Custom Sort Fuction', () => ); storiesOf('Cell Editing', module) diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index cb6734c..2c4e2fd 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -139,7 +139,11 @@ BootstrapTable.propTypes = { hideSelectColumn: PropTypes.bool }), onRowSelect: PropTypes.func, - onAllRowsSelect: PropTypes.func + onAllRowsSelect: PropTypes.func, + defaultSorted: PropTypes.arrayOf(PropTypes.shape({ + dataField: PropTypes.string.isRequired, + order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired + })) }; BootstrapTable.defaultProps = { diff --git a/packages/react-bootstrap-table2/src/sort/wrapper.js b/packages/react-bootstrap-table2/src/sort/wrapper.js index af16eed..78e4c03 100644 --- a/packages/react-bootstrap-table2/src/sort/wrapper.js +++ b/packages/react-bootstrap-table2/src/sort/wrapper.js @@ -12,6 +12,20 @@ class SortWrapper extends Component { this.handleSort = this.handleSort.bind(this); } + componentWillMount() { + const { columns, defaultSorted, store } = this.props; + // defaultSorted is an array, it's ready to use as multi / single sort + // when we start to support multi sort, please update following code to use array.forEach + if (defaultSorted && defaultSorted.length > 0) { + const dataField = defaultSorted[0].dataField; + const order = defaultSorted[0].order; + const column = columns.filter(col => col.dataField === dataField); + if (column.length > 0) { + store.sortBy(column[0], order); + } + } + } + handleSort(column) { const { store } = this.props; store.sortBy(column); @@ -25,7 +39,8 @@ class SortWrapper extends Component { return sortableElement({ ...this.props, ref: node => this.table = node, - onSort: this.handleSort + onSort: this.handleSort, + data: this.props.store.get() }); } } diff --git a/packages/react-bootstrap-table2/src/store/base.js b/packages/react-bootstrap-table2/src/store/base.js index 509dc63..bc0dcf4 100644 --- a/packages/react-bootstrap-table2/src/store/base.js +++ b/packages/react-bootstrap-table2/src/store/base.js @@ -18,8 +18,10 @@ export default class Store { return this.data.length === 0; } - sortBy({ dataField, sortFunc }) { - if (dataField !== this.sortField) { + sortBy({ dataField, sortFunc }, order) { + if (order) { + this.sortOrder = order; + } else if (dataField !== this.sortField) { this.sortOrder = Const.SORT_DESC; } else { this.sortOrder = this.sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC; diff --git a/packages/react-bootstrap-table2/test/sort/wrapper.test.js b/packages/react-bootstrap-table2/test/sort/wrapper.test.js index f6f9613..6dafc1b 100644 --- a/packages/react-bootstrap-table2/test/sort/wrapper.test.js +++ b/packages/react-bootstrap-table2/test/sort/wrapper.test.js @@ -16,7 +16,8 @@ describe('SortWrapper', () => { sort: true }, { dataField: 'name', - text: 'Name' + text: 'Name', + sort: true }]; const data = [{ @@ -80,4 +81,35 @@ describe('SortWrapper', () => { expect(store.sortField).toEqual(sortColumn.dataField); }); }); + + describe('when defaultSorted prop is defined', () => { + const defaultSorted = [{ + dataField: 'name', + order: Const.SORT_DESC + }]; + + beforeEach(() => { + wrapper = shallow( + + ); + }); + + it('should render table with correct default sorted', () => { + expect(wrapper.props().data).toEqual(store.get()); + }); + + it('should update store.sortField correctly', () => { + expect(store.sortField).toEqual(defaultSorted[0].dataField); + }); + + it('should update store.sortOrder correctly', () => { + expect(store.sortOrder).toEqual(defaultSorted[0].order); + }); + }); }); diff --git a/packages/react-bootstrap-table2/test/store/base.test.js b/packages/react-bootstrap-table2/test/store/base.test.js index 7bfb8f6..c60260f 100644 --- a/packages/react-bootstrap-table2/test/store/base.test.js +++ b/packages/react-bootstrap-table2/test/store/base.test.js @@ -73,6 +73,11 @@ describe('Store Base', () => { expect(e[dataField]).toEqual(result[i]); }); }); + + it('should force assign sortOrder correctly if second argument is passed', () => { + store.sortBy({ dataField }, Const.SORT_DESC); + expect(store.sortOrder).toEqual(Const.SORT_DESC); + }); }); describe('getRowByRowId', () => {