This commit is contained in:
AllenFang 2019-02-06 18:05:53 +08:00
parent 8bef7eb348
commit ecea3efdaa
5 changed files with 126 additions and 31 deletions

View File

@ -17,7 +17,8 @@ export default (
class FilterProvider extends React.Component { class FilterProvider extends React.Component {
static propTypes = { static propTypes = {
data: PropTypes.array.isRequired, data: PropTypes.array.isRequired,
columns: PropTypes.array.isRequired columns: PropTypes.array.isRequired,
listenerForPagination: PropTypes.object
} }
constructor(props) { constructor(props) {
@ -25,6 +26,9 @@ export default (
this.currFilters = {}; this.currFilters = {};
this.onFilter = this.onFilter.bind(this); this.onFilter = this.onFilter.bind(this);
this.onExternalFilter = this.onExternalFilter.bind(this); this.onExternalFilter = this.onExternalFilter.bind(this);
this.state = {
data: props.data
};
} }
componentDidMount() { componentDidMount() {
@ -68,7 +72,12 @@ export default (
filter.props.onFilter(filterVal); filter.props.onFilter(filterVal);
} }
this.forceUpdate(); const { listenerForPagination, data } = this.props;
const result = filters(data, this.props.columns, _)(this.currFilters);
if (listenerForPagination) {
listenerForPagination.emit('filterChanged', result.length);
}
this.setState({ data: result });
}; };
} }
@ -79,13 +88,9 @@ export default (
} }
render() { render() {
let { data } = this.props;
if (!isRemoteFiltering()) {
data = filters(data, this.props.columns, _)(this.currFilters);
}
return ( return (
<FilterContext.Provider value={ { <FilterContext.Provider value={ {
data, data: this.state.data,
onFilter: this.onFilter, onFilter: this.onFilter,
onExternalFilter: this.onExternalFilter onExternalFilter: this.onExternalFilter
} } } }

View File

@ -45,7 +45,8 @@ describe('FilterContext', () => {
function shallowContext( function shallowContext(
enableRemote = false, enableRemote = false,
tableColumns = columns tableColumns = columns,
listenerForPagination,
) { ) {
mockBase.mockReset(); mockBase.mockReset();
handleFilterChange.mockReset(); handleFilterChange.mockReset();
@ -59,6 +60,7 @@ describe('FilterContext', () => {
<FilterContext.Provider <FilterContext.Provider
columns={ tableColumns } columns={ tableColumns }
data={ data } data={ data }
listenerForPagination={ listenerForPagination }
> >
<FilterContext.Consumer> <FilterContext.Consumer>
{ {
@ -252,6 +254,23 @@ describe('FilterContext', () => {
}); });
}); });
describe('when props.listenerForPagination is defined', () => {
const filterVal = '3';
const newDataLength = 0;
const listenerForPagination = { emit: jest.fn() };
beforeEach(() => {
wrapper = shallow(shallowContext(false, columns, listenerForPagination));
wrapper.render();
instance = wrapper.instance();
});
it('should call listenerForPagination.emit correctly', () => {
instance.onFilter(columns[1], FILTER_TYPE.TEXT)(filterVal);
expect(listenerForPagination.emit).toHaveBeenCalledWith('filterChanged', newDataLength);
});
});
describe('combination', () => { describe('combination', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(shallowContext()); wrapper = shallow(shallowContext());

View File

@ -2,7 +2,9 @@
/* eslint react/require-default-props: 0 */ /* eslint react/require-default-props: 0 */
/* eslint no-lonely-if: 0 */ /* eslint no-lonely-if: 0 */
import React from 'react'; import React from 'react';
import EventEmitter from 'events';
import Const from './const'; import Const from './const';
import { alignPage } from './page';
const StateContext = React.createContext(); const StateContext = React.createContext();
@ -10,6 +12,7 @@ class StateProvider extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleChangePage = this.handleChangePage.bind(this); this.handleChangePage = this.handleChangePage.bind(this);
this.handleDataSizeChange = this.handleDataSizeChange.bind(this);
this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this); this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
let currPage; let currPage;
@ -36,7 +39,10 @@ class StateProvider extends React.Component {
} }
this.currPage = currPage; this.currPage = currPage;
this.dataSize = options.totalSize;
this.currSizePerPage = currSizePerPage; this.currSizePerPage = currSizePerPage;
this.filterListener = new EventEmitter();
this.filterListener.on('filterChanged', this.handleDataSizeChange);
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
@ -51,7 +57,7 @@ class StateProvider extends React.Component {
getPaginationProps = () => { getPaginationProps = () => {
const { pagination: { options }, bootstrap4 } = this.props; const { pagination: { options }, bootstrap4 } = this.props;
const { currPage, currSizePerPage } = this; const { currPage, currSizePerPage, dataSize } = this;
const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ? const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
Const.With_FIRST_AND_LAST : options.withFirstAndLast; Const.With_FIRST_AND_LAST : options.withFirstAndLast;
const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ? const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
@ -72,7 +78,7 @@ class StateProvider extends React.Component {
hideSizePerPage, hideSizePerPage,
alwaysShowAllBtns, alwaysShowAllBtns,
withFirstAndLast, withFirstAndLast,
dataSize: options.totalSize, dataSize,
sizePerPageList: options.sizePerPageList || Const.SIZE_PER_PAGE_LIST, sizePerPageList: options.sizePerPageList || Const.SIZE_PER_PAGE_LIST,
paginationSize: options.paginationSize || Const.PAGINATION_SIZE, paginationSize: options.paginationSize || Const.PAGINATION_SIZE,
showTotal: options.showTotal, showTotal: options.showTotal,
@ -106,6 +112,20 @@ class StateProvider extends React.Component {
return e.result; return e.result;
}; };
handleDataSizeChange(newDataSize) {
const { pagination: { options } } = this.props;
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
Const.PAGE_START_INDEX : options.pageStartIndex;
this.dataSize = newDataSize;
this.currPage = alignPage(
newDataSize,
this.currPage,
this.currSizePerPage,
pageStartIndex
);
this.forceUpdate();
}
handleChangePage(currPage) { handleChangePage(currPage) {
const { currSizePerPage } = this; const { currSizePerPage } = this;
const { pagination: { options } } = this.props; const { pagination: { options } } = this.props;
@ -153,7 +173,8 @@ class StateProvider extends React.Component {
paginationProps, paginationProps,
paginationTableProps: { paginationTableProps: {
pagination, pagination,
setPaginationRemoteEmitter: this.setPaginationRemoteEmitter setPaginationRemoteEmitter: this.setPaginationRemoteEmitter,
listenerForPagination: this.filterListener
} }
} } } }
> >

View File

@ -91,6 +91,10 @@ describe('PaginationStateContext', () => {
expect(wrapper.instance().currSizePerPage).toEqual(Const.SIZE_PER_PAGE_LIST[0]); expect(wrapper.instance().currSizePerPage).toEqual(Const.SIZE_PER_PAGE_LIST[0]);
}); });
it('should have correct dataSize', () => {
expect(wrapper.instance().dataSize).toEqual(options.totalSize);
});
it('should get correct pagination props', () => { it('should get correct pagination props', () => {
const instance = wrapper.instance(); const instance = wrapper.instance();
expect(wrapper.length).toBe(1); expect(wrapper.length).toBe(1);
@ -102,7 +106,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -182,6 +187,31 @@ describe('PaginationStateContext', () => {
}); });
}); });
describe('handleDataSizeChange', () => {
let instance;
const newTotalSize = 8;
beforeEach(() => {
wrapper = shallow(shallowContext({
...defaultPagination,
page: 3
}));
instance = wrapper.instance();
setRemotePaginationEmitter(instance);
jest.spyOn(instance, 'forceUpdate');
instance.handleDataSizeChange(newTotalSize);
});
it('should update dataSize correctly', () => {
expect(instance.dataSize).toEqual(newTotalSize);
expect(instance.forceUpdate).toHaveBeenCalledTimes(1);
});
it('should update currPage correctly if page list shrink', () => {
expect(instance.currPage).toEqual(Const.PAGE_START_INDEX);
expect(instance.forceUpdate).toHaveBeenCalledTimes(1);
});
});
describe('handleChangePage', () => { describe('handleChangePage', () => {
let instance; let instance;
const newPage = 3; const newPage = 3;
@ -343,7 +373,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -374,7 +405,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -401,7 +433,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -428,7 +461,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -455,7 +489,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -482,7 +517,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -509,7 +545,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -536,7 +573,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -563,7 +601,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -590,7 +629,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -617,7 +657,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -644,7 +685,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -671,7 +713,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -698,7 +741,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -725,7 +769,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -752,7 +797,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -779,7 +825,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -806,7 +853,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });
@ -833,7 +881,8 @@ describe('PaginationStateContext', () => {
createContext: expect.any(Function), createContext: expect.any(Function),
options: instance.getPaginationProps() options: instance.getPaginationProps()
}, },
setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter setPaginationRemoteEmitter: instance.setPaginationRemoteEmitter,
listenerForPagination: instance.filterListener
} }
}); });
}); });

View File

@ -237,6 +237,7 @@ const withContext = Base =>
{ ...baseProps } { ...baseProps }
ref={ n => this.filterContext = n } ref={ n => this.filterContext = n }
data={ rootProps.getData() } data={ rootProps.getData() }
listenerForPagination={ this.props.listenerForPagination }
> >
<this.FilterContext.Consumer> <this.FilterContext.Consumer>
{ {