Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ export function setPageSize(pageSize) {
}
}

export function updateState({ data, pageProperties = {}, sortProperties = {} }) {
export function updateState(newState) {
return {
type: GRIDDLE_UPDATE_STATE,
newState: { data, pageProperties, sortProperties }
newState
}
}
1 change: 1 addition & 0 deletions src/module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ export interface GriddleSortKey {
export interface GriddleStyleElements<T> {
Cell?: T;
Filter?: T;
Layout?: T;
Loading?: T;
NextButton?: T;
NoResults?: T;
Expand Down
68 changes: 68 additions & 0 deletions src/reducers/__tests__/dataReducerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,71 @@ test('toggle column works when there is no visible property', (t) => {


});

test('update state merges non-data', (t) => {
const initialState = Immutable.fromJS({
changed: 1,
unchanged: 2,
nested: {
changed: 3,
unchanged: 4,
},
data: [],
lookup: {},
});
const newState = {
changed: -1,
nested: {
changed: -3,
},
};

const state = reducers.GRIDDLE_UPDATE_STATE(initialState, { newState });

t.deepEqual(state.toJSON(), {
changed: -1,
unchanged: 2,
nested: {
changed: -3,
unchanged: 4,
},
data: [],
lookup: {},
});
});

test('update state transforms data', (t) => {
const initialState = Immutable.fromJS({
unchanged: 2,
nested: {
unchanged: 4,
},
data: [
{name: "one", griddleKey: 0},
{name: "two", griddleKey: 1},
],
lookup: { 0: 0, 1: 1 },
});
const newState = {
data: [
{ name: 'uno' },
{ name: 'dos' },
{ name: 'tre' },
]
};

const state = reducers.GRIDDLE_UPDATE_STATE(initialState, { newState });

t.deepEqual(state.toJSON(), {
unchanged: 2,
nested: {
unchanged: 4,
},
data: [
{name: "uno", griddleKey: 0},
{name: "dos", griddleKey: 1},
{name: "tre", griddleKey: 2},
],
lookup: { 0: 0, 1: 1, 2: 2 },
});
});
12 changes: 10 additions & 2 deletions src/reducers/dataReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,19 @@ export function GRIDDLE_TOGGLE_COLUMN(state, action) {
new Immutable.Map({ id: action.columnId, visible: true }));
}

const defaultRenderProperties = Immutable.fromJS({});
export function GRIDDLE_UPDATE_STATE(state, action) {
const { data, ...newState } = action.newState;
const transformedData = transformData(data, state.get('renderProperties').toJSON());

return state.mergeDeep(Immutable.fromJS(newState))
var mergedState = state.mergeDeep(Immutable.fromJS(newState));
if (!data) {
return mergedState;
}

const renderProperties = state.get('renderProperties', defaultRenderProperties).toJSON();
const transformedData = transformData(data, renderProperties);

return mergedState
.set('data', transformedData.data)
.set('lookup', transformedData.lookup);
}
6 changes: 3 additions & 3 deletions src/utils/__tests__/initilizerTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ test('init succeeds given empty defaults and props', (assert) => {
test('init returns defaults given minimum props', (assert) => {
const ctx = { props: { data: [] } };
const defaults = {
reducers: { REDUCE: () => ({ reduced: true }) },
reducer: { REDUCE: () => ({ reduced: true }) },
components: { Layout: () => null },
settingsComponentObjects: { mySettings: { order: 10 } },
selectors: { aSelector: () => null },
Expand All @@ -82,7 +82,7 @@ test('init returns defaults given minimum props', (assert) => {
});

assert.is(typeof res.reducers, 'function');
assert.deepEqual(Object.keys(res.reducers), Object.keys(defaults.reducers));
assert.deepEqual(Object.keys(res.reducers), Object.keys(defaults.reducer));
assert.deepEqual(res.reducers({}, { type: 'REDUCE' }), { reduced: true });

assert.deepEqual(res.reduxMiddleware, []);
Expand Down Expand Up @@ -244,7 +244,7 @@ test('init returns composed reducer given plugins', (assert) => {
},
};
const defaults = {
reducers: {
reducer: {
DEFAULTS: () => ({ defaults: true }),
PLUGIN: () => ({ plugin: false }),
},
Expand Down
2 changes: 1 addition & 1 deletion src/utils/initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = function initializer(defaults) {
if (!this) throw new Error('this missing!');

const {
reducers: dataReducers,
reducer: dataReducers,
components,
settingsComponentObjects,
selectors,
Expand Down
52 changes: 52 additions & 0 deletions stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,58 @@ storiesOf('Griddle main', module)
</Griddle>
)
})
.add('with external prop changes', () => {
const NoResultsWithN = connect(
(state: any) => ({
n: state.get('n'),
addTen: state.get('addTen'),
}),
() => {}
)(({ n, addTen }) => (
<div>
<p><code>n = {n}</code></p>
<button onClick={addTen}>+10</button>
</div>
));

class Stateful extends React.Component<{}, { n: number }> {
constructor(props) {
super(props);
this.state = { n: 0 };
}

render() {
const { n } = this.state;
return (
<div>
<p>
Click to change Griddle props:{' '}
<button onClick={() => this.setState(({ n }) => ({ n: n+1 }))}>{n}</button>
<button onClick={() => this.setState({ n: 0 })}>Reset</button>
</p>
<Griddle
n={n}
addTen={() => this.setState(({ n }) => ({ n: n + 10 }))}
plugins={[LocalPlugin]}
data={fakeData.filter((d,i) => i % n === 0)}
components={{
NoResults: NoResultsWithN
}}
styleConfig={{
styles: {
Layout: { color: n % 3 ? 'blue' : 'inherit' },
},
}}
textProperties={{
settingsToggle: `Settings (${n})`
}}
/>
</div>
);
}
}
return <Stateful />;
})
.add('with local, delayed data', () => {
class DeferredGriddle extends React.Component<GriddleProps<FakeData>, { data?: FakeData[] }> {
private timeout;
Expand Down