From 04226077039519b6011d0faabc6845b855fda19a Mon Sep 17 00:00:00 2001 From: Ryan Lanciaux Date: Fri, 22 Dec 2017 22:12:05 -0500 Subject: [PATCH 1/6] Fix typo (reducers => reducer) --- src/utils/__tests__/initilizerTests.js | 6 +++--- src/utils/initializer.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/__tests__/initilizerTests.js b/src/utils/__tests__/initilizerTests.js index 31522b38..7309c09c 100644 --- a/src/utils/__tests__/initilizerTests.js +++ b/src/utils/__tests__/initilizerTests.js @@ -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 }, @@ -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, []); @@ -244,7 +244,7 @@ test('init returns composed reducer given plugins', (assert) => { }, }; const defaults = { - reducers: { + reducer: { DEFAULTS: () => ({ defaults: true }), PLUGIN: () => ({ plugin: false }), }, diff --git a/src/utils/initializer.js b/src/utils/initializer.js index 193c7e86..2238b8ab 100644 --- a/src/utils/initializer.js +++ b/src/utils/initializer.js @@ -7,7 +7,7 @@ module.exports = function initializer(defaults) { if (!this) throw new Error('this missing!'); const { - reducers: dataReducers, + reducer: dataReducers, components, settingsComponentObjects, selectors, From a6a67c321e214c515edcb615c68b5af52f512cc0 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 23 Dec 2017 13:47:00 -0600 Subject: [PATCH 2/6] Add simple repro for #781 --- stories/index.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/stories/index.tsx b/stories/index.tsx index 67ada22e..f9e0762c 100644 --- a/stories/index.tsx +++ b/stories/index.tsx @@ -105,6 +105,28 @@ storiesOf('Griddle main', module) ) }) + .add('with local with extra prop change', () => { + class Stateful extends React.Component<{}, { n: number }> { + constructor(props) { + super(props); + this.state = { n: 0 }; + } + + render() { + const { n } = this.state; + return ( +
+

+ Click me to change extra Griddle state:{' '} + +

+ +
+ ); + } + } + return ; + }) .add('with local, delayed data', () => { class DeferredGriddle extends React.Component, { data?: FakeData[] }> { private timeout; From 9e91846fe0e9922c6fac62b9a00b39ce745848a1 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 23 Dec 2017 15:03:27 -0600 Subject: [PATCH 3/6] Add GRIDDLE_UPDATE_STATE tests --- src/reducers/__tests__/dataReducerTest.js | 73 +++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/reducers/__tests__/dataReducerTest.js b/src/reducers/__tests__/dataReducerTest.js index d53dc8aa..7da6e2c1 100644 --- a/src/reducers/__tests__/dataReducerTest.js +++ b/src/reducers/__tests__/dataReducerTest.js @@ -183,3 +183,76 @@ 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: {}, + renderProperties: {}, + }); + 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, + }, + // This seems wrong + data: undefined, + lookup: undefined, + renderProperties: {}, + }); +}); + +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 }, + renderProperties: {}, + }); + 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 }, + renderProperties: {}, + }); +}); From ef0aa2d9b475ad3a33207ba12922ee8e303ea72a Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 23 Dec 2017 15:54:29 -0600 Subject: [PATCH 4/6] Make renderProperties optional --- src/reducers/__tests__/dataReducerTest.js | 4 ---- src/reducers/dataReducer.js | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/reducers/__tests__/dataReducerTest.js b/src/reducers/__tests__/dataReducerTest.js index 7da6e2c1..7a07c601 100644 --- a/src/reducers/__tests__/dataReducerTest.js +++ b/src/reducers/__tests__/dataReducerTest.js @@ -194,7 +194,6 @@ test('update state merges non-data', (t) => { }, data: [], lookup: {}, - renderProperties: {}, }); const newState = { changed: -1, @@ -215,7 +214,6 @@ test('update state merges non-data', (t) => { // This seems wrong data: undefined, lookup: undefined, - renderProperties: {}, }); }); @@ -230,7 +228,6 @@ test('update state transforms data', (t) => { {name: "two", griddleKey: 1}, ], lookup: { 0: 0, 1: 1 }, - renderProperties: {}, }); const newState = { data: [ @@ -253,6 +250,5 @@ test('update state transforms data', (t) => { {name: "tre", griddleKey: 2}, ], lookup: { 0: 0, 1: 1, 2: 2 }, - renderProperties: {}, }); }); diff --git a/src/reducers/dataReducer.js b/src/reducers/dataReducer.js index 26d7c44f..17689960 100644 --- a/src/reducers/dataReducer.js +++ b/src/reducers/dataReducer.js @@ -132,9 +132,12 @@ 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()); + + const renderProperties = state.get('renderProperties', defaultRenderProperties).toJSON(); + const transformedData = transformData(data, renderProperties); return state.mergeDeep(Immutable.fromJS(newState)) .set('data', transformedData.data) From 415b9729053a3f6c783eed28009c22ad3806c9d8 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 23 Dec 2017 15:56:51 -0600 Subject: [PATCH 5/6] Avoid overwriting data if missing from newState --- src/reducers/__tests__/dataReducerTest.js | 5 ++--- src/reducers/dataReducer.js | 7 ++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/reducers/__tests__/dataReducerTest.js b/src/reducers/__tests__/dataReducerTest.js index 7a07c601..82e88524 100644 --- a/src/reducers/__tests__/dataReducerTest.js +++ b/src/reducers/__tests__/dataReducerTest.js @@ -211,9 +211,8 @@ test('update state merges non-data', (t) => { changed: -3, unchanged: 4, }, - // This seems wrong - data: undefined, - lookup: undefined, + data: [], + lookup: {}, }); }); diff --git a/src/reducers/dataReducer.js b/src/reducers/dataReducer.js index 17689960..c2fb4b2d 100644 --- a/src/reducers/dataReducer.js +++ b/src/reducers/dataReducer.js @@ -136,10 +136,15 @@ const defaultRenderProperties = Immutable.fromJS({}); export function GRIDDLE_UPDATE_STATE(state, action) { const { data, ...newState } = action.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 state.mergeDeep(Immutable.fromJS(newState)) + return mergedState .set('data', transformedData.data) .set('lookup', transformedData.lookup); } From 44608964fbeede2e827297a253a1a5fef7c29cff Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 23 Dec 2017 23:55:29 -0600 Subject: [PATCH 6/6] Expand prop change story --- src/actions/index.js | 4 ++-- src/module.d.ts | 1 + stories/index.tsx | 36 +++++++++++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 15043442..2c3276f4 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -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 } } diff --git a/src/module.d.ts b/src/module.d.ts index 283c9a76..2325a8f2 100644 --- a/src/module.d.ts +++ b/src/module.d.ts @@ -315,6 +315,7 @@ export interface GriddleSortKey { export interface GriddleStyleElements { Cell?: T; Filter?: T; + Layout?: T; Loading?: T; NextButton?: T; NoResults?: T; diff --git a/stories/index.tsx b/stories/index.tsx index f9e0762c..b8e511d6 100644 --- a/stories/index.tsx +++ b/stories/index.tsx @@ -105,7 +105,20 @@ storiesOf('Griddle main', module) ) }) - .add('with local with extra prop change', () => { + .add('with external prop changes', () => { + const NoResultsWithN = connect( + (state: any) => ({ + n: state.get('n'), + addTen: state.get('addTen'), + }), + () => {} + )(({ n, addTen }) => ( +
+

n = {n}

+ +
+ )); + class Stateful extends React.Component<{}, { n: number }> { constructor(props) { super(props); @@ -117,10 +130,27 @@ storiesOf('Griddle main', module) return (

- Click me to change extra Griddle state:{' '} + Click to change Griddle props:{' '} +

- + 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})` + }} + />
); }