From 87e1ac9938ef9f3e528f944efc9ff82f196df6c1 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 26 Mar 2024 11:10:24 -0400 Subject: [PATCH] [MergeDups] Track deleted senses (#2953) --- .../MergeDuplicates/MergeDupsTreeTypes.ts | 7 +++++- .../MergeDuplicates/Redux/MergeDupsReducer.ts | 24 +++++++++---------- .../Redux/tests/MergeDupsActions.test.tsx | 12 ++++++++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/goals/MergeDuplicates/MergeDupsTreeTypes.ts b/src/goals/MergeDuplicates/MergeDupsTreeTypes.ts index ce1dbf2dc7..28cd73732c 100644 --- a/src/goals/MergeDuplicates/MergeDupsTreeTypes.ts +++ b/src/goals/MergeDuplicates/MergeDupsTreeTypes.ts @@ -94,8 +94,13 @@ export const defaultSidebar: Sidebar = { }; export interface MergeTree { + deletedSenseGuids: string[]; sidebar: Sidebar; words: Hash; } -export const defaultTree: MergeTree = { sidebar: defaultSidebar, words: {} }; +export const defaultTree: MergeTree = { + deletedSenseGuids: [], + sidebar: defaultSidebar, + words: {}, +}; diff --git a/src/goals/MergeDuplicates/Redux/MergeDupsReducer.ts b/src/goals/MergeDuplicates/Redux/MergeDupsReducer.ts index 68fe773b77..35dba783c5 100644 --- a/src/goals/MergeDuplicates/Redux/MergeDupsReducer.ts +++ b/src/goals/MergeDuplicates/Redux/MergeDupsReducer.ts @@ -16,6 +16,7 @@ import { type Sidebar, convertSenseToMergeTreeSense, convertWordToMergeTreeWord, + defaultData, defaultSidebar, defaultTree, newMergeTreeWord, @@ -74,12 +75,13 @@ const mergeDuplicatesSlice = createSlice({ deleteSenseAction: (state, action) => { const srcRef: MergeTreeReference = action.payload; const srcWordId = srcRef.wordId; - const words = state.tree.words; + const { deletedSenseGuids, words } = state.tree; const sensesGuids = words[srcWordId].sensesGuids; const srcGuids = sensesGuids[srcRef.mergeSenseId]; if (srcRef.order === undefined || srcGuids.length === 1) { // A sense deleted from a word. + deletedSenseGuids.push(...srcGuids); delete sensesGuids[srcRef.mergeSenseId]; if (!Object.keys(sensesGuids).length) { delete words[srcWordId]; @@ -92,6 +94,7 @@ const mergeDuplicatesSlice = createSlice({ } } else { // A sense deleted from the sidebar. + deletedSenseGuids.push(srcGuids[srcRef.order]); srcGuids.splice(srcRef.order, 1); if (srcGuids.length < 2) { // If not multiple senses in the sidebar, reset the sidebar. @@ -107,12 +110,9 @@ const mergeDuplicatesSlice = createSlice({ getMergeWordsAction: (state) => { // Handle words with all senses deleted. const possibleWords = Object.values(state.data.words); - // List of all non-deleted senses. - const nonDeletedSenses = Object.values(state.tree.words).flatMap((w) => - Object.values(w.sensesGuids).flatMap((s) => s) - ); + const deletedSenseGuids = state.tree.deletedSenseGuids; const deletedWords = possibleWords.filter((w) => - w.senses.every((s) => !nonDeletedSenses.includes(s.guid)) + w.senses.every((s) => deletedSenseGuids.includes(s.guid)) ); state.mergeWords = deletedWords.map((w) => newMergeWords(w, [{ srcWordId: w.id, getAudio: false }], true) @@ -123,7 +123,7 @@ const mergeDuplicatesSlice = createSlice({ const mergeSenses = buildSenses( mergeWord.sensesGuids, state.data, - nonDeletedSenses + deletedSenseGuids ); const mergeWords = createMergeWords( wordId, @@ -265,7 +265,7 @@ const mergeDuplicatesSlice = createSlice({ }); wordsTree[word.id] = convertWordToMergeTreeWord(word); }); - state.data = { senses, words }; + state.data = { ...defaultData, senses, words }; state.tree = { ...defaultTree, words: wordsTree }; state.mergeWords = []; } @@ -285,7 +285,7 @@ const mergeDuplicatesSlice = createSlice({ function buildSenses( sensesGuids: Hash, data: MergeData, - nonDeletedSenses: string[] + deletedSenseGuids: string[] ): Hash { const senses: Hash = {}; for (const senseGuids of Object.values(sensesGuids)) { @@ -305,9 +305,9 @@ function buildSenses( srcWordId: wordId, sense: { ...sense, - accessibility: nonDeletedSenses.includes(sense.guid) - ? Status.Separate - : Status.Deleted, + accessibility: deletedSenseGuids.includes(sense.guid) + ? Status.Deleted + : Status.Separate, }, }); } diff --git a/src/goals/MergeDuplicates/Redux/tests/MergeDupsActions.test.tsx b/src/goals/MergeDuplicates/Redux/tests/MergeDupsActions.test.tsx index 1bef3d9bf1..7aed209a05 100644 --- a/src/goals/MergeDuplicates/Redux/tests/MergeDupsActions.test.tsx +++ b/src/goals/MergeDuplicates/Redux/tests/MergeDupsActions.test.tsx @@ -214,7 +214,11 @@ describe("MergeDupActions", () => { it("delete one sense from word with multiple senses", async () => { const WA = newMergeTreeWord(vernA, { ID1: [S1] }); const WB = newMergeTreeWord(vernB, { ID1: [S3], ID2: [S4] }); - const tree: MergeTree = { ...defaultTree, words: { WA, WB } }; + const tree: MergeTree = { + ...defaultTree, + deletedSenseGuids: [S2], + words: { WA, WB }, + }; const store = setupStore({ ...preloadedState, mergeDuplicateGoal: { ...defaultMergeState, data, tree }, @@ -237,7 +241,11 @@ describe("MergeDupActions", () => { // Delete both senses from B it("delete all senses from a word", async () => { const WA = newMergeTreeWord(vernA, { ID1: [S1], ID2: [S2] }); - const tree: MergeTree = { ...defaultTree, words: { WA } }; + const tree: MergeTree = { + ...defaultTree, + deletedSenseGuids: [S3, S4], + words: { WA }, + }; const store = setupStore({ ...preloadedState, mergeDuplicateGoal: { ...defaultMergeState, data, tree },