From 26747086d0d13b0b74ce519ff9e3cc3e939ae66c Mon Sep 17 00:00:00 2001 From: Gustav Hansen Date: Wed, 7 Sep 2022 19:45:33 +0200 Subject: [PATCH] RelationInputWrapper: Fix 1:1 relations reducer --- .../EditViewDataManagerProvider/index.js | 3 +- .../EditViewDataManagerProvider/reducer.js | 10 +- .../tests/reducer.test.js | 93 +++++++++++++++---- .../RelationInputWrapper.js | 6 +- 4 files changed, 83 insertions(+), 29 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js index 9abec84d80..d1336c5efb 100644 --- a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +++ b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js @@ -156,11 +156,12 @@ const EditViewDataManagerProvider = ({ }); }, []); - const connectRelation = useCallback(({ target: { name, value } }) => { + const connectRelation = useCallback(({ target: { name, value, replace } }) => { dispatch({ type: 'CONNECT_RELATION', keys: name.split('.'), value, + replace, }); }, []); diff --git a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js index c18dbcce8f..86f890777f 100644 --- a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +++ b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js @@ -84,10 +84,14 @@ const reducer = (state, action) => } case 'CONNECT_RELATION': { const path = ['modifiedData', ...action.keys]; - const { value } = action; + const { value, replace = false } = action; - const nextValue = get(draftState, [...path, 'connect']); - nextValue.push(value); + if (replace) { + set(draftState, [...path, 'connect'], [value]); + } else { + const nextValue = get(draftState, [...path, 'connect']); + nextValue.push(value); + } break; } diff --git a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/tests/reducer.test.js b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/tests/reducer.test.js index f6f2de70a8..707717c7ef 100644 --- a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/tests/reducer.test.js +++ b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/tests/reducer.test.js @@ -258,28 +258,27 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer', }); describe('CONNECT_RELATION', () => { - it.skip('should add a relation in the modifiedData', () => { + it('should add a relation in the modifiedData', () => { const state = { ...initialState, - initialData: { - name: 'name', - }, + initialData: {}, modifiedData: { - name: 'name', + relation: { + connect: [], + disconnect: [], + }, }, }; const expected = { ...initialState, componentsDataStructure: {}, - initialData: { - name: 'name', - }, + initialData: {}, modifiedData: { - name: 'name', relation: { connect: [{ id: 1 }], + disconnect: [], }, }, }; @@ -292,6 +291,59 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer', expect(reducer(state, action)).toEqual(expected); }); + + it('should overwrite existing data, when replace is set to true', () => { + const state = { + ...initialState, + + initialData: {}, + modifiedData: { + relation: { + connect: [], + disconnect: [], + }, + }, + }; + + const action = { + type: 'CONNECT_RELATION', + keys: ['relation'], + value: { id: 1 }, + }; + + let nextState = reducer(state, action); + + expect(nextState).toEqual({ + ...initialState, + componentsDataStructure: {}, + initialData: {}, + modifiedData: { + relation: { + connect: [{ id: 1 }], + disconnect: [], + }, + }, + }); + + nextState = reducer(nextState, { + type: 'CONNECT_RELATION', + keys: ['relation'], + value: { id: 2 }, + replace: true, + }); + + expect(nextState).toEqual({ + ...initialState, + componentsDataStructure: {}, + initialData: {}, + modifiedData: { + relation: { + connect: [{ id: 2 }], + disconnect: [], + }, + }, + }); + }); }); describe('LOAD_RELATION', () => { @@ -310,7 +362,9 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer', expect(nextState).toStrictEqual({ ...initialState, initialData: { - relation: [{ id: 1 }], + relation: { + results: [{ id: 1 }], + }, }, modifiedData: { relation: { @@ -329,7 +383,7 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer', ).toStrictEqual({ ...initialState, initialData: { - relation: [{ id: 2 }, { id: 1 }], + relation: { results: [{ id: 2 }, { id: 1 }] }, }, modifiedData: { relation: { @@ -342,27 +396,26 @@ describe('CONTENT MANAGER | COMPONENTS | EditViewDataManagerProvider | reducer', }); describe('DISCONNECT_RELATION', () => { - it.skip('should remove a relation from modifiedData', () => { + it('should remove a relation from modifiedData', () => { const state = { ...initialState, - initialData: { - name: 'name', - }, + initialData: {}, modifiedData: { - name: 'name', + relation: { + connect: [], + disconnect: [], + }, }, }; const expected = { ...initialState, componentsDataStructure: {}, - initialData: { - name: 'name', - }, + initialData: {}, modifiedData: { - name: 'name', relation: { + connect: [], disconnect: [{ id: 1 }], }, }, diff --git a/packages/core/admin/admin/src/content-manager/components/RelationInputWrapper/RelationInputWrapper.js b/packages/core/admin/admin/src/content-manager/components/RelationInputWrapper/RelationInputWrapper.js index 10ff99534b..08b49c83fd 100644 --- a/packages/core/admin/admin/src/content-manager/components/RelationInputWrapper/RelationInputWrapper.js +++ b/packages/core/admin/admin/src/content-manager/components/RelationInputWrapper/RelationInputWrapper.js @@ -82,11 +82,7 @@ export const RelationInputWrapper = ({ }, [isMorph, isCreatingEntry, editable, isFieldAllowed, isFieldReadable]); const handleRelationAdd = (relation) => { - if (isSingleRelation) { - // TODO remove all relations from relations before - } - - connectRelation({ target: { name, value: relation } }); + connectRelation({ target: { name, value: relation, replace: isSingleRelation } }); }; const handleRelationRemove = (relation) => {