Skip to content

Commit

Permalink
Add support for nested grid reducers (#106)
Browse files Browse the repository at this point in the history
* Add support for nested grid reducers
* Added example to the docs
  • Loading branch information
drownbes authored and bencripps committed Feb 17, 2017
1 parent dcbf46b commit b87973f
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 28 deletions.
33 changes: 33 additions & 0 deletions docs/USING_GRID_REDUCERS.md
Expand Up @@ -102,3 +102,36 @@ const config = {

const grid = <Grid { ...config } />;
````

## Nested Grid Reducers

If you want to hide grid reducers from the root of your state:

````js
import { combineReducers } from 'redux';
import { GridRootReducer } from 'react-redux-grid';

import myAppReducer from './customReducers/app';
import myDataReducer from './customReducers/data';

export const rootReducer = combineReducers({
myAppReducer,
myDataReducer,
nested: GridRootReducer
});

export default rootReducer;


import { Grid, Reducers } from 'react-redux-grid';

const config = {
data,
store,
reducerKeys: 'nested'
};

const grid = <Grid { ...config } />;


````
2 changes: 1 addition & 1 deletion src/components/Grid.jsx
Expand Up @@ -236,7 +236,7 @@ export class Grid extends Component {
pageSize: number,
pager: object,
plugins: object,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
selectedRows: object,
showTreeRootNode: bool,
stateKey: string,
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/FixedHeader.jsx
Expand Up @@ -12,7 +12,7 @@ import { isPluginEnabled } from '../../util/isPluginEnabled';
import { gridConfig } from '../../constants/GridConstants';
import { resizeColumns } from '../../actions/GridActions';

const { arrayOf, bool, object, string } = PropTypes;
const { arrayOf, bool, object, string, oneOfType } = PropTypes;

const dragAndDropManager = new DragAndDropManager();

Expand Down Expand Up @@ -215,7 +215,7 @@ class FixedHeader extends Component {
menuState: object,
pager: object,
plugins: object,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
selectionModel: object,
stateKey: string,
stateful: bool,
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/Header.jsx
Expand Up @@ -9,7 +9,7 @@ import { shouldHeaderUpdate } from '../../util/shouldComponentUpdate';
import { keyFromObject } from '../../util/keyGenerator';
import { gridConfig } from '../../constants/GridConstants';

const { arrayOf, bool, object, string } = PropTypes;
const { arrayOf, bool, object, string, oneOfType } = PropTypes;

const dragAndDropManager = new DragAndDropManager();

Expand Down Expand Up @@ -95,7 +95,7 @@ class Header extends Component {
dataSource: object,
pager: object,
plugins: object,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
selectionModel: object,
stateKey: string,
store: object,
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/TableRow.jsx
Expand Up @@ -23,7 +23,7 @@ import {
import Row from './table-row/Row';
import { PlaceHolder } from './row/PlaceHolder';

const { arrayOf, bool, func, number, object, string } = PropTypes;
const { arrayOf, bool, func, number, object, string, oneOfType } = PropTypes;

export class TableRow extends Component {

Expand Down Expand Up @@ -97,7 +97,7 @@ export class TableRow extends Component {
pager: object,
plugins: object,
readFunc: func,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
selectedRows: object,
selectionModel: object,
showTreeRootNode: bool,
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/table-row/Row.jsx
Expand Up @@ -11,7 +11,7 @@ import { fireEvent } from '../../../util/fire';
import { getData, getRowKey } from '../../../util/getData';
import { gridConfig } from '../../../constants/GridConstants';

const { arrayOf, bool, func, object, string, oneOf, number } = PropTypes;
const { arrayOf, bool, func, object, string, oneOf, number, oneOfType } = PropTypes;

const DRAG_INCREMENT = 15;

Expand Down Expand Up @@ -198,7 +198,7 @@ export class Row extends Component {
plugins: object,
previousRow: object,
readFunc: func,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
row: object,
selectedRows: object,
selectionModel: object,
Expand Down
2 changes: 1 addition & 1 deletion src/components/plugins/editor/Inline.jsx
Expand Up @@ -231,7 +231,7 @@ Inline.propTypes = {
config: PropTypes.object.isRequired,
editorState: PropTypes.object,
events: PropTypes.object,
reducerKeys: PropTypes.object,
reducerKeys: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
stateKey: PropTypes.string,
store: PropTypes.object
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/plugins/gridactions/ActionColumn.jsx
Expand Up @@ -152,7 +152,7 @@ export class ActionColumn extends Component {
headerActionItemBuilder: PropTypes.func,
iconCls: PropTypes.string,
menuState: PropTypes.object,
reducerKeys: PropTypes.object,
reducerKeys: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
rowData: PropTypes.object,
rowId: PropTypes.string,
rowIndex: PropTypes.number,
Expand Down
2 changes: 1 addition & 1 deletion src/components/plugins/gridactions/actioncolumn/Menu.jsx
Expand Up @@ -61,7 +61,7 @@ Menu.propTypes = {
columns: PropTypes.arrayOf(PropTypes.object),
editor: PropTypes.object,
maxHeight: PropTypes.number,
reducerKeys: PropTypes.object,
reducerKeys: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
rowData: PropTypes.object,
rowId: PropTypes.string,
rowIndex: PropTypes.number,
Expand Down
4 changes: 2 additions & 2 deletions src/components/plugins/selection/CheckBox.jsx
Expand Up @@ -153,13 +153,13 @@ export const getColumn = (checkBoxContainerProps, checkBoxProps) => {

};

const { any, func, number, object, string } = PropTypes;
const { any, func, number, object, string, oneOfType } = PropTypes;

CheckBox.propTypes = {
dataSource: object,
index: number,
onSelect: func,
reducerKeys: object,
reducerKeys: oneOfType([object, string]),
rowId: any,
selectedRows: object,
selectionModelConfig: object,
Expand Down
17 changes: 12 additions & 5 deletions src/util/lastUpdate.js
Expand Up @@ -17,13 +17,20 @@ export const generateLastUpdate = () => ++num;
export const resetLastUpdate = () => { num = 0; };

export const getLastUpdate = (store, key, reducerKeys = REDUCER_KEYS) => {
const state = store.getState();
let state = store.getState();
let keys;

let keys = Object.keys(reducerKeys);

if (!keys.length) {
reducerKeys = REDUCER_KEYS;
if (typeof reducerKeys === 'string') {
state = state[reducerKeys];
keys = Object.keys(REDUCER_KEYS);
reducerKeys = REDUCER_KEYS;
}
else {
keys = Object.keys(reducerKeys);
if (!keys.length) {
reducerKeys = REDUCER_KEYS;
keys = Object.keys(REDUCER_KEYS);
}
}

return keys.reduce((prev, reducerAccessor) => {
Expand Down
22 changes: 13 additions & 9 deletions src/util/stateGetter.js
Expand Up @@ -10,15 +10,19 @@

export const stateGetter = (state, props, key, entry) => {

if (props
&& props.reducerKeys
&& Object.keys(props.reducerKeys).length > 0
&& props.reducerKeys[key]) {

const dynamicKey = props.reducerKeys[key];
const dynamicState = get(state, dynamicKey, entry);

return dynamicState;
if (props && props.reducerKeys) {
if (typeof props.reducerKeys === 'string') {
return get(state[props.reducerKeys], key, entry);
}
else if (typeof props.reducerKeys === 'object' &&
Object.keys(props.reducerKeys).length > 0 &&
props.reducerKeys[key]) {

const dynamicKey = props.reducerKeys[key];
const dynamicState = get(state, dynamicKey, entry);

return dynamicState;
}
}

const val = get(state, key, entry);
Expand Down
36 changes: 36 additions & 0 deletions test/util/stateGetter.test.js
Expand Up @@ -80,6 +80,42 @@ describe('State Getter Function', () => {
).toEqual(null);
});

it('Should return state when it is nested and registered', () => {
const state = { nested: {filterState: { get: getState } } };
const props = {
reducerKeys: 'nested'
};
expect(
stateGetter(state, props, 'filterState', 'someProp')
).toBeTruthy();
});

it(['Should return state when it is nested ',
'and has immutable state'].join(''), () => {
const state = {
nested: { filterState: { get: getStateWithImmutable } }
};

const props = {
reducerKeys: 'nested'
};
expect(
stateGetter(state, props, 'filterState', 'someProp')
).toEqual(Map({
x: 1
}));
});

it('Should return null if state is nested and not registered', () => {
const state = { nested: {} };
const props = {
reducerKeys: 'nested'
};
expect(
stateGetter(state, props, 'filterState', 'someProp')
).toEqual(null);
});

it('Should return null when no keys and no state are provided', () => {
const state = {};
const props = {};
Expand Down

0 comments on commit b87973f

Please sign in to comment.