Fix update deduplication in useRelationMultiple (#18159)

* Check for duplicate update in useRelationMultiple update action

* Add test

---------

Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
Hannes Küttner
2023-04-13 17:36:39 +02:00
committed by GitHub
parent 2bcd0e4ba4
commit 3f2dfdcbc7
2 changed files with 55 additions and 0 deletions

View File

@@ -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 },

View File

@@ -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') {