From 216bc1014279acc23c3c7e9c8de325d57b18db9e Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sat, 19 May 2018 18:07:07 +0800 Subject: [PATCH] implement celledit context --- .../react-bootstrap-table2-editor/index.js | 4 +- .../src/{wrapper.js => context.js} | 63 +++++----- .../src/contexts/index.js | 114 ++++++++++++------ .../src/props-resolver/remote-resolver.js | 15 ++- .../src/store/mutate.js | 4 +- 5 files changed, 122 insertions(+), 78 deletions(-) rename packages/react-bootstrap-table2-editor/src/{wrapper.js => context.js} (72%) diff --git a/packages/react-bootstrap-table2-editor/index.js b/packages/react-bootstrap-table2-editor/index.js index 3d07c2c..0bc57b5 100644 --- a/packages/react-bootstrap-table2-editor/index.js +++ b/packages/react-bootstrap-table2-editor/index.js @@ -1,4 +1,4 @@ -import wrapperFactory from './src/wrapper'; +import createContext from './src/context'; import editingCellFactory from './src/editing-cell'; import { EDITTYPE, @@ -8,7 +8,7 @@ import { } from './src/const'; export default (options = {}) => ({ - wrapperFactory, + createContext, editingCellFactory, CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT, diff --git a/packages/react-bootstrap-table2-editor/src/wrapper.js b/packages/react-bootstrap-table2-editor/src/context.js similarity index 72% rename from packages/react-bootstrap-table2-editor/src/wrapper.js rename to packages/react-bootstrap-table2-editor/src/context.js index 97138d4..da0930d 100644 --- a/packages/react-bootstrap-table2-editor/src/wrapper.js +++ b/packages/react-bootstrap-table2-editor/src/context.js @@ -1,16 +1,21 @@ /* eslint react/prop-types: 0 */ -import React, { Component } from 'react'; +/* eslint react/require-default-props: 0 */ +import React from 'react'; import PropTypes from 'prop-types'; - import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const'; export default ( - Base, - { _, remoteResolver } + _, + dataOperator, + isRemoteCellEdit, + handleCellChange ) => { let EditingCell; - return class CellEditWrapper extends remoteResolver(Component) { + const CellEditContext = React.createContext(); + + class CellEditProvider extends React.Component { static propTypes = { + data: PropTypes.array.isRequired, options: PropTypes.shape({ mode: PropTypes.oneOf([CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT]).isRequired, onErrorMessageDisappear: PropTypes.func, @@ -19,7 +24,7 @@ export default ( afterSaveCell: PropTypes.func, nonEditableRows: PropTypes.func, timeToCloseMessage: PropTypes.number, - errorMessage: PropTypes.string + errorMessage: PropTypes.any }) } @@ -33,41 +38,32 @@ export default ( this.state = { ridx: null, cidx: null, - message: null, - isDataChanged: false + message: null }; } componentWillReceiveProps(nextProps) { - if (nextProps.cellEdit && this.isRemoteCellEdit()) { + if (nextProps.cellEdit && isRemoteCellEdit()) { if (nextProps.cellEdit.options.errorMessage) { this.setState(() => ({ - isDataChanged: false, message: nextProps.cellEdit.options.errorMessage })); } else { - this.setState(() => ({ - isDataChanged: true - })); this.escapeEditing(); } - } else { - this.setState(() => ({ - isDataChanged: false - })); } } handleCellUpdate(row, column, newValue) { - const { keyField, cellEdit, store } = this.props; + const { keyField, cellEdit, data } = this.props; const { beforeSaveCell, afterSaveCell } = cellEdit.options; const oldValue = _.get(row, column.dataField); const rowId = _.get(row, keyField); if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column); - if (this.isRemoteCellEdit()) { - this.handleCellChange(rowId, column.dataField, newValue); + if (isRemoteCellEdit()) { + handleCellChange(rowId, column.dataField, newValue); } else { - store.edit(rowId, column.dataField, newValue); + dataOperator.editCell(data, keyField, rowId, column.dataField, newValue); if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column); this.completeEditing(); } @@ -77,8 +73,7 @@ export default ( this.setState(() => ({ ridx: null, cidx: null, - message: null, - isDataChanged: true + message: null })); } @@ -86,8 +81,7 @@ export default ( const editing = () => { this.setState(() => ({ ridx, - cidx, - isDataChanged: false + cidx })); }; @@ -103,7 +97,6 @@ export default ( } render() { - const { isDataChanged, ...stateRest } = this.state; const { cellEdit: { options: { nonEditableRows, errorMessage, ...optionsRest }, @@ -111,10 +104,11 @@ export default ( ...cellEditRest } } = this.props; + const newCellEdit = { ...optionsRest, ...cellEditRest, - ...stateRest, + ...this.state, EditingCell, nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [], onStart: this.startEditing, @@ -123,13 +117,16 @@ export default ( }; return ( - + + { this.props.children } + ); } + } + return { + Provider: CellEditProvider, + Consumer: CellEditContext.Consumer }; }; diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index 7267d80..20ed702 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -1,27 +1,100 @@ /* eslint no-return-assign: 0 */ import React, { Component } from 'react'; +import _ from '../utils'; import createDataContext from './data-context'; import createSortContext from './sort-context'; import createSelectionContext from './selection-context'; import remoteResolver from '../props-resolver/remote-resolver'; +import dataOperator from '../store/operators'; const withContext = (Base) => { let DataContext; let SelectionContext; + let CellEditContext; let SortContext; return class BootstrapTableContainer extends remoteResolver(Component) { constructor(props) { super(props); - DataContext = createDataContext(this.props.data); - SelectionContext = createSelectionContext(); - SortContext = createSortContext(this.isRemoteSort, this.handleSortChange); + DataContext = createDataContext(props.data); + SelectionContext = createSelectionContext(dataOperator); + SortContext = createSortContext(dataOperator, this.isRemoteSort, this.handleSortChange); + if (props.cellEdit && props.cellEdit.createContext) { + CellEditContext = props.cellEdit.createContext( + _, dataOperator, this.isRemoteCellEdit, this.handleCellChange); + } + } + + componentWillReceiveProps(nextProps) { + if (!nextProps.cellEdit) { + CellEditContext = null; + } + } + + renderBase(baseProps) { + return (rootProps, cellEditProps) => ( + this.sortContext = n } + defaultSorted={ this.props.defaultSorted } + defaultSortDirection={ this.props.defaultSortDirection } + data={ rootProps.data } + > + + { + sortProps => ( + + + { + selectionProps => ( + + ) + } + + + ) + } + + + ); + } + + renderWithCellEdit(base, baseProps) { + return rootProps => ( + + + { + cellEditprops => base(rootProps, cellEditprops) + } + + + ); } render() { const { keyField, columns } = this.props; const baseProps = { keyField, columns }; + let base = this.renderBase(baseProps); + + if (CellEditContext) { + base = this.renderWithCellEdit(base, baseProps); + } + return ( { > { - rootProps => ( - - - { - selectionProps => ( - this.sortProvider = n } - { ...baseProps } - defaultSorted={ this.props.defaultSorted } - defaultSortDirection={ this.props.defaultSortDirection } - data={ rootProps.data } - > - - { - sortProps => ( - - ) - } - - - ) - } - - - ) + base } diff --git a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js index dd3d665..4d0e833 100644 --- a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js +++ b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js @@ -3,7 +3,7 @@ import _ from '../utils'; export default ExtendBase => class RemoteResolver extends ExtendBase { /* eslint class-methods-use-this: 0 */ - getNewestState(state = {}) { + getNewestState = (state = {}) => { // const store = this.store || this.props.store; // return { // page: store.page, @@ -14,7 +14,14 @@ export default ExtendBase => // data: store.getAllData(), // ...state // }; - return { ...state, data: this.props.data }; + return { + sortOrder: this.sortContext.state.sortOrder, + sortField: this.sortContext.state.sortColumn ? + this.sortContext.state.sortColumn.dataField : + null, + ...state, + data: this.props.data + }; } isRemotePagination() { @@ -32,7 +39,7 @@ export default ExtendBase => return remote === true || (_.isObject(remote) && remote.sort) || this.isRemotePagination(); } - isRemoteCellEdit() { + isRemoteCellEdit = () => { const { remote } = this.props; return remote === true || (_.isObject(remote) && remote.cellEdit); } @@ -54,7 +61,7 @@ export default ExtendBase => this.props.onTableChange('sort', this.getNewestState({ sortField, sortOrder })); } - handleCellChange(rowId, dataField, newValue) { + handleCellChange = (rowId, dataField, newValue) => { const cellEdit = { rowId, dataField, newValue }; this.props.onTableChange('cellEdit', this.getNewestState({ cellEdit })); } diff --git a/packages/react-bootstrap-table2/src/store/mutate.js b/packages/react-bootstrap-table2/src/store/mutate.js index 43cab2c..9e59bab 100644 --- a/packages/react-bootstrap-table2/src/store/mutate.js +++ b/packages/react-bootstrap-table2/src/store/mutate.js @@ -1,7 +1,7 @@ import _ from '../utils'; import { getRowByRowId } from './rows'; -export const editCell = (rowId, dataField, newValue) => { - const row = getRowByRowId(this)(rowId); +export const editCell = (data, keyField, rowId, dataField, newValue) => { + const row = getRowByRowId(data, keyField, rowId); if (row) _.set(row, dataField, newValue); };