From 2525465a5a9c2c519be6db4cd271d59a968a1d20 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sun, 13 May 2018 16:14:21 +0800 Subject: [PATCH] implement sort context --- .../src/contexts/sort-context.js | 88 +++++++++++++++++++ .../src/sort/wrapper.js | 81 ----------------- .../react-bootstrap-table2/src/store/sort.js | 22 ++--- 3 files changed, 99 insertions(+), 92 deletions(-) create mode 100644 packages/react-bootstrap-table2/src/contexts/sort-context.js delete mode 100644 packages/react-bootstrap-table2/src/sort/wrapper.js diff --git a/packages/react-bootstrap-table2/src/contexts/sort-context.js b/packages/react-bootstrap-table2/src/contexts/sort-context.js new file mode 100644 index 0000000..17d029e --- /dev/null +++ b/packages/react-bootstrap-table2/src/contexts/sort-context.js @@ -0,0 +1,88 @@ + +import React from 'react'; +import PropTypes from 'prop-types'; +import Const from '../const'; +import { sort, nextOrder } from '../store/sort'; +import remoteResolver from '../props-resolver/remote-resolver'; + +export default () => { + const SortContext = React.createContext(); + + class SortProvider extends remoteResolver(React.Component) { + static propTypes = { + columns: PropTypes.array.isRequired, + defaultSorted: PropTypes.arrayOf(PropTypes.shape({ + dataField: PropTypes.string.isRequired, + order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired + })), + defaultSortDirection: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]) + } + + constructor(props) { + super(props); + let sortOrder; + let sortColumn; + const { columns, defaultSorted, defaultSortDirection } = props; + + if (defaultSorted && defaultSorted.length > 0) { + const sortField = defaultSorted[0].dataField; + sortOrder = defaultSorted[0].order || defaultSortDirection; + const sortColumns = columns.filter(col => col.dataField === sortField); + if (sortColumns.length > 0) { + sortColumn = sortColumns[0]; + + if (sortColumn.onSort) { + sortColumn.onSort(sortField, sortOrder); + } + + if (this.isRemoteSort() || this.isRemotePagination()) { + this.handleSortChange(); + } + } + } + this.state = { sortOrder, sortColumn }; + } + + handleSort = (column) => { + const sortOrder = nextOrder(column, this.state, this.props.defaultSortDirection); + + if (column.onSort) { + column.onSort(column.dataField, sortOrder); + } + + if (this.isRemoteSort() || this.isRemotePagination()) { + this.handleSortChange(); + } else { + this.setState(() => ({ + sortOrder, + sortColumn: column + })); + } + } + + render() { + let { data } = this.props; + const { sortOrder, sortColumn } = this.state; + if (!this.isRemoteSort() && !this.isRemotePagination() && sortColumn) { + data = sort(data, sortOrder, sortColumn); + } + + return ( + + { this.props.children } + + ); + } + } + return { + Provider: SortProvider, + Consumer: SortContext.Consumer + }; +}; diff --git a/packages/react-bootstrap-table2/src/sort/wrapper.js b/packages/react-bootstrap-table2/src/sort/wrapper.js deleted file mode 100644 index 6d55f1c..0000000 --- a/packages/react-bootstrap-table2/src/sort/wrapper.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint react/prop-types: 0 */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import remoteResolver from '../props-resolver/remote-resolver'; - -export default Base => - class SortWrapper extends remoteResolver(Component) { - static propTypes = { - store: PropTypes.object.isRequired - } - - constructor(props) { - super(props); - this.handleSort = this.handleSort.bind(this); - } - - componentWillMount() { - const { columns, defaultSorted, defaultSortDirection, 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.setSort(column[0], order, defaultSortDirection); - - if (column[0].onSort) { - column[0].onSort(store.sortField, store.sortOrder); - } - - if (this.isRemoteSort() || this.isRemotePagination()) { - this.handleSortChange(); - } else { - store.sortBy(column[0]); - } - } - } - } - - componentWillReceiveProps(nextProps) { - if (!this.isRemoteSort() && !this.isRemotePagination()) { - let sortedColumn; - for (let i = 0; i < nextProps.columns.length; i += 1) { - if (nextProps.columns[i].dataField === nextProps.store.sortField) { - sortedColumn = nextProps.columns[i]; - break; - } - } - if (sortedColumn && sortedColumn.sort) { - nextProps.store.sortBy(sortedColumn); - } - } - } - - handleSort(column) { - const { store } = this.props; - store.setSort(column, undefined, this.props.defaultSortDirection); - - if (column.onSort) { - column.onSort(store.sortField, store.sortOrder); - } - - if (this.isRemoteSort() || this.isRemotePagination()) { - this.handleSortChange(); - } else { - store.sortBy(column); - this.forceUpdate(); - } - } - - render() { - return ( - - ); - } - }; diff --git a/packages/react-bootstrap-table2/src/store/sort.js b/packages/react-bootstrap-table2/src/store/sort.js index 1987e0e..ecbfbd7 100644 --- a/packages/react-bootstrap-table2/src/store/sort.js +++ b/packages/react-bootstrap-table2/src/store/sort.js @@ -14,17 +14,17 @@ function comparator(a, b) { return result; } -export const sort = ({ data, sortOrder, sortField }) => (sortFunc) => { +export const sort = (data, sortOrder, { dataField, sortFunc }) => { const _data = [...data]; _data.sort((a, b) => { let result; - let valueA = _.get(a, sortField); - let valueB = _.get(b, sortField); + let valueA = _.get(a, dataField); + let valueB = _.get(b, dataField); valueA = _.isDefined(valueA) ? valueA : ''; valueB = _.isDefined(valueB) ? valueB : ''; if (sortFunc) { - result = sortFunc(valueA, valueB, sortOrder, sortField); + result = sortFunc(valueA, valueB, sortOrder, dataField); } else { if (sortOrder === Const.SORT_DESC) { result = comparator(valueA, valueB); @@ -37,11 +37,11 @@ export const sort = ({ data, sortOrder, sortField }) => (sortFunc) => { return _data; }; -export const nextOrder = store => (field, order, defaultOrder = Const.SORT_DESC) => { - if (order) return order; - - if (field !== store.sortField) { - return defaultOrder; - } - return store.sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC; +export const nextOrder = ( + currentSortColumn, + { sortOrder, sortColumn }, + defaultOrder = Const.SORT_DESC +) => { + if (!sortColumn || currentSortColumn.dataField !== sortColumn.dataField) return defaultOrder; + return sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC; };