From 3f2dfdcbc73994fdd87c3a7e2b496a06d21724cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20K=C3=BCttner?= Date: Thu, 13 Apr 2023 17:36:39 +0200 Subject: [PATCH] Fix update deduplication in useRelationMultiple (#18159) * Check for duplicate update in useRelationMultiple update action * Add test --------- Co-authored-by: Pascal Jufer Co-authored-by: Rijk van Zanten --- .../composables/use-relation-multiple.test.ts | 40 +++++++++++++++++++ app/src/composables/use-relation-multiple.ts | 15 +++++++ 2 files changed, 55 insertions(+) diff --git a/app/src/composables/use-relation-multiple.test.ts b/app/src/composables/use-relation-multiple.test.ts index 807a8f4a83..b5d5fe18d9 100644 --- a/app/src/composables/use-relation-multiple.test.ts +++ b/app/src/composables/use-relation-multiple.test.ts @@ -223,6 +223,46 @@ describe('test o2m relation', () => { ]); }); + test('updating an item twice without $index', async () => { + const wrapper = mount(TestComponent, { + props: { relation: relationO2M, value: [], id: 1 }, + }); + + wrapper.vm.update({ id: 2, name: 'test2-edited' }); + wrapper.vm.update({ id: 2, name: 'test2-edited again' }); + + await flushPromises(); + + const changes = cloneDeep(workerData); + changes.splice(1, 1, { id: 2, name: 'test2-edited again', facility: 1, $edits: 0, $type: 'updated', $index: 0 }); + + expect(wrapper.vm.displayItems).toEqual(changes); + expect(wrapper.emitted()['update:value'][0]).toEqual([ + { + create: [], + update: [ + { + id: 2, + name: 'test2-edited', + }, + ], + delete: [], + }, + ]); + expect(wrapper.emitted()['update:value'][1]).toEqual([ + { + create: [], + update: [ + { + id: 2, + name: 'test2-edited again', + }, + ], + delete: [], + }, + ]); + }); + test('removing an item', async () => { const wrapper = mount(TestComponent, { props: { relation: relationO2M, value: [], id: 1 }, diff --git a/app/src/composables/use-relation-multiple.ts b/app/src/composables/use-relation-multiple.ts index 9a9311d7b5..a351555dde 100644 --- a/app/src/composables/use-relation-multiple.ts +++ b/app/src/composables/use-relation-multiple.ts @@ -206,7 +206,22 @@ export function useRelationMultiple( function update(...items: DisplayItem[]) { if (!relation.value) return; + const targetPKField = + relation.value.type === 'o2m' + ? relation.value.relatedPrimaryKeyField.field + : relation.value.junctionPrimaryKeyField.field; + for (const item of items) { + const editsIndex = + item.$index ?? + target.value.update.findIndex( + (edit: any) => typeof edit === 'object' && edit[targetPKField] === item[targetPKField] + ); + if (item.$index === undefined && editsIndex !== -1) { + item.$index = editsIndex; + item.$type = 'updated'; + } + if (item.$type === undefined || item.$index === undefined) { target.value.update.push(cleanItem(item)); } else if (item.$type === 'created') {