mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-07-04 16:10:03 +00:00
fix wrong higher order wrapping (#112)
* fix wrong higher order wrapping * fix tests for wrong wrapper design
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
/* eslint arrow-body-style: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import _ from '../utils';
|
||||
|
||||
import { cellEditElement } from '../table-factory';
|
||||
|
||||
class CellEditWrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -88,7 +90,8 @@ class CellEditWrapper extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return React.cloneElement(this.props.elem, {
|
||||
return cellEditElement({
|
||||
...this.props,
|
||||
onCellUpdate: this.handleCellUpdate,
|
||||
onStartEditing: this.startEditing,
|
||||
onEscapeEditing: this.escapeEditing,
|
||||
@@ -98,7 +101,6 @@ class CellEditWrapper extends Component {
|
||||
}
|
||||
|
||||
CellEditWrapper.propTypes = {
|
||||
elem: PropTypes.element.isRequired,
|
||||
onUpdateCell: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
71
packages/react-bootstrap-table2/src/container.js
vendored
71
packages/react-bootstrap-table2/src/container.js
vendored
@@ -1,16 +1,18 @@
|
||||
/* eslint arrow-body-style: 0 */
|
||||
/* eslint react/jsx-no-bind: 0 */
|
||||
/* eslint no-return-assign: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import Store from './store/base';
|
||||
import SortWrapper from './sort/wrapper';
|
||||
import CellEditWrapper from './cell-edit/wrapper';
|
||||
import RowSelectionWrapper from './row-selection/wrapper';
|
||||
|
||||
import {
|
||||
wrapWithCellEdit,
|
||||
wrapWithSelection,
|
||||
wrapWithSort
|
||||
} from './table-factory';
|
||||
|
||||
import _ from './utils';
|
||||
|
||||
const withDataStore = (Base) => {
|
||||
return class BootstrapTableContainer extends Component {
|
||||
const withDataStore = Base =>
|
||||
class BootstrapTableContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.store = new Store(props);
|
||||
@@ -46,61 +48,26 @@ const withDataStore = (Base) => {
|
||||
return false;
|
||||
}
|
||||
|
||||
renderCellEdit(elem) {
|
||||
return (
|
||||
<CellEditWrapper
|
||||
keyField={ this.props.keyField }
|
||||
cellEdit={ this.props.cellEdit }
|
||||
ref={ node => this.cellEditWrapper = node }
|
||||
elem={ elem }
|
||||
onUpdateCell={ this.handleUpdateCell }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderRowSelection(elem) {
|
||||
return (
|
||||
<RowSelectionWrapper
|
||||
keyField={ this.props.keyField }
|
||||
selectRow={ this.props.selectRow }
|
||||
store={ this.store }
|
||||
elem={ elem }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSort(elem) {
|
||||
return (
|
||||
<SortWrapper elem={ elem } store={ this.store } />
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const baseProps = {
|
||||
...this.props,
|
||||
store: this.store
|
||||
};
|
||||
|
||||
let element = React.createElement(Base, baseProps);
|
||||
|
||||
// @TODO
|
||||
// the logic of checking sort is enable or not should be placed in the props resolver..
|
||||
// but currently, I've no idea to refactoring this
|
||||
if (this.props.columns.filter(col => col.sort).length > 0) {
|
||||
element = this.renderSort(element);
|
||||
}
|
||||
|
||||
if (this.props.selectRow) {
|
||||
element = this.renderRowSelection(element);
|
||||
}
|
||||
|
||||
if (this.props.cellEdit) {
|
||||
element = this.renderCellEdit(element);
|
||||
return wrapWithCellEdit({
|
||||
ref: node => this.cellEditWrapper = node,
|
||||
onUpdateCell: this.handleUpdateCell,
|
||||
...baseProps
|
||||
});
|
||||
} else if (this.props.selectRow) {
|
||||
return wrapWithSelection(baseProps);
|
||||
} else if (this.props.columns.filter(col => col.sort).length > 0) {
|
||||
return wrapWithSort(baseProps);
|
||||
}
|
||||
|
||||
return element;
|
||||
return React.createElement(Base, baseProps);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default withDataStore;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* eslint arrow-body-style: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { selectionElement } from '../table-factory';
|
||||
|
||||
import Const from '../const';
|
||||
|
||||
@@ -65,7 +66,8 @@ class RowSelectionWrapper extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return React.cloneElement(this.props.elem, {
|
||||
return selectionElement({
|
||||
...this.props,
|
||||
onRowSelect: this.handleRowSelect,
|
||||
onAllRowsSelect: this.handleAllRowsSelect
|
||||
});
|
||||
@@ -73,7 +75,6 @@ class RowSelectionWrapper extends Component {
|
||||
}
|
||||
|
||||
RowSelectionWrapper.propTypes = {
|
||||
elem: PropTypes.element.isRequired,
|
||||
store: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* eslint arrow-body-style: 0 */
|
||||
/* eslint react/prop-types: 0 */
|
||||
/* eslint no-return-assign: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { sortableElement } from '../table-factory';
|
||||
|
||||
class SortWrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -20,7 +22,8 @@ class SortWrapper extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return React.cloneElement(this.props.elem, {
|
||||
return sortableElement({
|
||||
...this.props,
|
||||
ref: node => this.table = node,
|
||||
onSort: this.handleSort
|
||||
});
|
||||
@@ -28,7 +31,6 @@ class SortWrapper extends Component {
|
||||
}
|
||||
|
||||
SortWrapper.propTypes = {
|
||||
elem: PropTypes.element.isRequired,
|
||||
store: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
||||
27
packages/react-bootstrap-table2/src/table-factory.js
vendored
Normal file
27
packages/react-bootstrap-table2/src/table-factory.js
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from './bootstrap-table';
|
||||
|
||||
import SortWrapper from './sort/wrapper';
|
||||
import RowSelectionWrapper from './row-selection/wrapper';
|
||||
import CellEditWrapper from './cell-edit/wrapper';
|
||||
|
||||
|
||||
export const wrapWithCellEdit = props =>
|
||||
React.createElement(CellEditWrapper, { ...props });
|
||||
|
||||
export const wrapWithSelection = props =>
|
||||
React.createElement(RowSelectionWrapper, { ...props });
|
||||
|
||||
export const wrapWithSort = props =>
|
||||
React.createElement(SortWrapper, { ...props });
|
||||
|
||||
export const pureTable = props =>
|
||||
React.createElement(BootstrapTable, { ...props });
|
||||
|
||||
|
||||
export const sortableElement = props => pureTable(props);
|
||||
|
||||
export const selectionElement = props => wrapWithSort(props);
|
||||
|
||||
export const cellEditElement = props => wrapWithSelection(props);
|
||||
@@ -8,7 +8,6 @@ import CellEditWrapper from '../../src/cell-edit/wrapper';
|
||||
|
||||
describe('CellEditWrapper', () => {
|
||||
let wrapper;
|
||||
let elem;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
@@ -35,12 +34,13 @@ describe('CellEditWrapper', () => {
|
||||
const store = new Store({ data, keyField });
|
||||
|
||||
beforeEach(() => {
|
||||
elem = React.createElement(BootstrapTable, { data, cellEdit, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ sinon.stub() }
|
||||
/>
|
||||
);
|
||||
@@ -58,7 +58,7 @@ describe('CellEditWrapper', () => {
|
||||
expect(wrapper.state().editing).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should inject correct props to elem', () => {
|
||||
it('should inject correct props to base component', () => {
|
||||
expect(wrapper.props().onCellUpdate).toBeDefined();
|
||||
expect(wrapper.props().onStartEditing).toBeDefined();
|
||||
expect(wrapper.props().onEscapeEditing).toBeDefined();
|
||||
@@ -74,12 +74,13 @@ describe('CellEditWrapper', () => {
|
||||
|
||||
describe('and cellEdit.editing is false', () => {
|
||||
beforeEach(() => {
|
||||
elem = React.createElement(BootstrapTable, { data, cellEdit, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ sinon.stub() }
|
||||
/>
|
||||
);
|
||||
@@ -104,12 +105,13 @@ describe('CellEditWrapper', () => {
|
||||
const cidx = 2;
|
||||
|
||||
beforeEach(() => {
|
||||
elem = React.createElement(BootstrapTable, { data, cellEdit, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ sinon.stub() }
|
||||
/>
|
||||
);
|
||||
@@ -175,8 +177,10 @@ describe('CellEditWrapper', () => {
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ onUpdateCellCallBack }
|
||||
/>
|
||||
);
|
||||
@@ -204,8 +208,10 @@ describe('CellEditWrapper', () => {
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ onUpdateCellCallBack }
|
||||
/>
|
||||
);
|
||||
@@ -229,8 +235,10 @@ describe('CellEditWrapper', () => {
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ onUpdateCellCallBack }
|
||||
/>
|
||||
);
|
||||
@@ -249,8 +257,10 @@ describe('CellEditWrapper', () => {
|
||||
wrapper = shallow(
|
||||
<CellEditWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
cellEdit={ cellEdit }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ onUpdateCellCallBack }
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,9 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import BootstrapTable from '../src';
|
||||
import SortWrapper from '../src/sort/wrapper';
|
||||
import CellEditWrapper from '../src/cell-edit/wrapper';
|
||||
import RowSelectionWrapper from '../src/row-selection/wrapper';
|
||||
|
||||
describe('withDataStore', () => {
|
||||
let wrapper;
|
||||
@@ -44,8 +47,7 @@ describe('withDataStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when cellEdit is defined', () => {
|
||||
const spy = jest.spyOn(BootstrapTable.prototype, 'renderCellEdit');
|
||||
describe('when cellEdit prop is defined', () => {
|
||||
const cellEdit = {
|
||||
mode: 'click'
|
||||
};
|
||||
@@ -61,15 +63,14 @@ describe('withDataStore', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should calling renderCellEdit function', () => {
|
||||
expect(spy).toHaveBeenCalled();
|
||||
it('should render CellEditWrapper component successfully', () => {
|
||||
const component = wrapper.find(CellEditWrapper);
|
||||
expect(component.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should injecting correct props', () => {
|
||||
expect(wrapper.props().keyField).toEqual('id');
|
||||
expect(wrapper.props().cellEdit).toEqual(cellEdit);
|
||||
expect(wrapper.props().elem).toBeDefined();
|
||||
expect(wrapper.props().onUpdateCell).toBeDefined();
|
||||
it('should injecting correct props to CellEditWrapper', () => {
|
||||
const component = wrapper.find(CellEditWrapper);
|
||||
expect(component.props().onUpdateCell).toBeDefined();
|
||||
});
|
||||
|
||||
describe('for handleUpdateCell function', () => {
|
||||
@@ -129,4 +130,46 @@ describe('withDataStore', () => {
|
||||
describe.skip('when cellEdit.onUpdate callback is define and which return a Promise', () => {});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when selectRow prop is defined', () => {
|
||||
const selectRow = {
|
||||
mode: 'checkbox'
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
<BootstrapTable
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
selectRow={ selectRow }
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it('should render RowSelectionWrapper component successfully', () => {
|
||||
expect(wrapper.find(RowSelectionWrapper).length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when any column.sort is defined', () => {
|
||||
beforeEach(() => {
|
||||
const columnsWithSort = [{
|
||||
dataField: keyField,
|
||||
text: 'ID',
|
||||
sort: true
|
||||
}];
|
||||
wrapper = shallow(
|
||||
<BootstrapTable
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columnsWithSort }
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it('should render SortWrapper component successfully', () => {
|
||||
expect(wrapper.find(SortWrapper).length).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import Store from '../../src/store/base';
|
||||
@@ -8,7 +7,6 @@ import RowSelectionWrapper from '../../src/row-selection/wrapper';
|
||||
|
||||
describe('RowSelectionWrapper', () => {
|
||||
let wrapper;
|
||||
let elem;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
@@ -35,14 +33,13 @@ describe('RowSelectionWrapper', () => {
|
||||
const store = new Store({ data, keyField });
|
||||
|
||||
beforeEach(() => {
|
||||
elem = React.createElement(BootstrapTable, { data, selectRow, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<RowSelectionWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
selectRow={ selectRow }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ sinon.stub() }
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -57,7 +54,7 @@ describe('RowSelectionWrapper', () => {
|
||||
expect(wrapper.state().selectedRowKeys.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should inject correct props to elem', () => {
|
||||
it('should inject correct props to base component', () => {
|
||||
expect(wrapper.props().onRowSelect).toBeDefined();
|
||||
expect(wrapper.props().onAllRowsSelect).toBeDefined();
|
||||
});
|
||||
@@ -81,14 +78,13 @@ describe('RowSelectionWrapper', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
selectRow.mode = 'checkbox';
|
||||
elem = React.createElement(BootstrapTable, { data, selectRow, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<RowSelectionWrapper
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
selectRow={ selectRow }
|
||||
elem={ elem }
|
||||
store={ store }
|
||||
onUpdateCell={ sinon.stub() }
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -9,7 +9,6 @@ import SortWrapper from '../../src/sort/wrapper';
|
||||
|
||||
describe('SortWrapper', () => {
|
||||
let wrapper;
|
||||
let elem;
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
@@ -33,10 +32,11 @@ describe('SortWrapper', () => {
|
||||
let store = new Store({ data, keyField });
|
||||
|
||||
beforeEach(() => {
|
||||
elem = React.createElement(BootstrapTable, { data, columns, keyField, store });
|
||||
wrapper = shallow(
|
||||
<SortWrapper
|
||||
elem={ elem }
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
store={ store }
|
||||
/>
|
||||
);
|
||||
@@ -47,7 +47,7 @@ describe('SortWrapper', () => {
|
||||
expect(wrapper.find(BootstrapTable)).toBeDefined();
|
||||
});
|
||||
|
||||
it('should inject correct props to elem', () => {
|
||||
it('should inject correct props to base component', () => {
|
||||
expect(wrapper.props().onSort).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -58,7 +58,9 @@ describe('SortWrapper', () => {
|
||||
store = new Store({ data, keyField });
|
||||
wrapper = mount(
|
||||
<SortWrapper
|
||||
elem={ elem }
|
||||
keyField={ keyField }
|
||||
data={ data }
|
||||
columns={ columns }
|
||||
store={ store }
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user