From bbd6e13e1edd2ff13997c25ff08c710e1252c8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Varela?= Date: Sat, 6 Nov 2021 20:13:38 +0000 Subject: [PATCH] Fix lose data on M2M (#9548) * save initial items of m2m relation * merge initial, draft and selected on new selection --- app/src/interfaces/list-m2m/list-m2m.vue | 9 +++++++-- app/src/interfaces/list-m2m/use-preview.ts | 6 +++++- app/src/interfaces/list-m2m/use-selection.ts | 18 ++++++++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/src/interfaces/list-m2m/list-m2m.vue b/app/src/interfaces/list-m2m/list-m2m.vue index a0d78aa889..af4e09b7f6 100644 --- a/app/src/interfaces/list-m2m/list-m2m.vue +++ b/app/src/interfaces/list-m2m/list-m2m.vue @@ -171,7 +171,7 @@ export default defineComponent({ emitter ); - const { tableHeaders, items, loading } = usePreview( + const { tableHeaders, items, initialItems, loading } = usePreview( value, fields, relationInfo, @@ -184,7 +184,12 @@ export default defineComponent({ const { currentlyEditing, editItem, editsAtStart, stageEdits, cancelEdit, relatedPrimaryKey, editModalActive } = useEdit(value, relationInfo, emitter); - const { stageSelection, selectModalActive, selectedPrimaryKeys } = useSelection(items, relationInfo, emitter); + const { stageSelection, selectModalActive, selectedPrimaryKeys } = useSelection( + items, + initialItems, + relationInfo, + emitter + ); const { sort, sortItems, sortedItems } = useSort(relationInfo, fields, items, emitter); diff --git a/app/src/interfaces/list-m2m/use-preview.ts b/app/src/interfaces/list-m2m/use-preview.ts index 83adfbba3c..88ef05e238 100644 --- a/app/src/interfaces/list-m2m/use-preview.ts +++ b/app/src/interfaces/list-m2m/use-preview.ts @@ -11,6 +11,7 @@ import { getEndpoint } from '@/utils/get-endpoint'; type UsablePreview = { tableHeaders: Ref; items: Ref[]>; + initialItems: Ref[]>; loading: Ref; error: Ref; }; @@ -30,6 +31,7 @@ export default function usePreview( const fieldsStore = useFieldsStore(); const tableHeaders = ref([]); const loading = ref(false); + const initialItems = ref[]>([]); const items = ref[]>([]); const error = ref(null); @@ -92,6 +94,8 @@ export default function usePreview( }) .concat(...newItems); + if (!initialItems.value.length) initialItems.value = responseData; + items.value = responseData; } catch (err: any) { error.value = err; @@ -140,7 +144,7 @@ export default function usePreview( { immediate: true } ); - return { tableHeaders, items, loading, error }; + return { tableHeaders, items, initialItems, loading, error }; function getRelatedFields(fields: string[]) { const { junctionField } = relation.value; diff --git a/app/src/interfaces/list-m2m/use-selection.ts b/app/src/interfaces/list-m2m/use-selection.ts index 9830dec56c..3b1a39e99e 100644 --- a/app/src/interfaces/list-m2m/use-selection.ts +++ b/app/src/interfaces/list-m2m/use-selection.ts @@ -10,6 +10,7 @@ type UsableSelection = { export default function useSelection( items: Ref[]>, + initialItems: Ref[]>, relation: Ref, emit: (newVal: any[] | null) => void ): UsableSelection { @@ -30,9 +31,22 @@ export default function useSelection( }); function stageSelection(newSelection: (number | string)[]) { - const { junctionField } = relation.value; + const { junctionField, junctionPkField } = relation.value; - const selection = newSelection.map((item) => ({ [junctionField]: item })); + const selection = newSelection.map((item) => { + const initial = initialItems.value.find((existent) => existent[junctionField][junctionPkField] === item); + const draft = items.value.find((draft) => draft[junctionField][junctionPkField] === item); + + return { + ...initial, + ...draft, + [junctionField]: { + ...initial?.[junctionPkField], + ...draft?.[junctionPkField], + [junctionPkField]: item, + }, + }; + }); if (selection.length === 0) emit(null); else emit(selection);