diff --git a/src/reducers/orderedReducer.js b/src/reducers/orderedReducer.js index 7ba867b7..6ee56796 100644 --- a/src/reducers/orderedReducer.js +++ b/src/reducers/orderedReducer.js @@ -20,15 +20,18 @@ const { /** * Create a new copy of an array with the provided item in a new array index + * * @param {Array} [collectionState=[]] - Redux state of current collection - * @param {object} meta - New array metadata - * @param {object} meta.oldIndex - New array index for the item - * @param {object} meta.newIndex - + * @param {object} meta - Redux Action meta data contains the doc id + * @param {object} ordered - New array metadata + * @param {object} ordered.oldIndex - New array index for the item + * @param {object} ordered.newIndex - * @param {object} newValue - New value of the item * @returns {Array} Array with item moved */ -function newArrayWithItemMoved(collectionState, meta, newValue) { - const { oldIndex, newIndex } = meta || {}; +function newArrayWithItemMoved(collectionState, meta, ordered, newValue) { + const { doc } = meta; + const { oldIndex, newIndex } = ordered || {}; // remove oldIndex from array while creating a copy const arrayWithoutItem = [ ...collectionState.slice(0, oldIndex), @@ -38,7 +41,7 @@ function newArrayWithItemMoved(collectionState, meta, newValue) { return [ ...arrayWithoutItem.slice(0, newIndex), // set new item (falling back to using a copy of the removed item) - newValue || { ...collectionState[oldIndex] }, + { id: doc, ...newValue } || { ...collectionState[oldIndex] }, ...arrayWithoutItem.slice(newIndex), ]; } @@ -59,6 +62,7 @@ function modifyDoc(collectionState, action) { if (!!newIndex && oldIndex > -1 && newIndex !== oldIndex) { return newArrayWithItemMoved( collectionState, + action.meta, action.payload.ordered, action.payload.data, ); diff --git a/test/unit/reducers/orderedReducer.spec.js b/test/unit/reducers/orderedReducer.spec.js index b31b431e..eedc8ea5 100644 --- a/test/unit/reducers/orderedReducer.spec.js +++ b/test/unit/reducers/orderedReducer.spec.js @@ -83,6 +83,45 @@ describe('orderedReducer', () => { }); describe('DOCUMENT_MODIFIED', () => { + it('preserves id on existing document when reordered', () => { + const collection = 'test1'; + const doc = 'test2'; + const someDoc = { some: 'value' }; + const otherDoc = { id: 'id1' }; + const newIndex = 2; + const oldIndex = 0; + const payload = { + ordered: { newIndex, oldIndex }, + data: someDoc, + }; + const meta = { collection, doc }; + action = { meta, payload, type: actionTypes.DOCUMENT_MODIFIED }; + const fakeState = { + [collection]: [someDoc, otherDoc, { id: 'id2' }], + }; + const result = orderedReducer(fakeState, action); + // ID on first item no longer matches + expect(result).to.not.have.nested.property( + `${collection}.${oldIndex}.id`, + doc, + ); + // Old item is moved into removed index + expect(result).to.have.nested.property( + `${collection}.${oldIndex}.id`, + otherDoc.id, + ); + // Value is set to new item index + expect(result).to.have.nested.property( + `${collection}.${newIndex}.some`, + someDoc.some, + ); + // Moved item's id is preserved + expect(result).to.have.nested.property( + `${collection}.${newIndex}.id`, + doc, + ); + }); + it('preserves id on existing document - #252', () => { const collection = 'test1'; const doc = 'test2';