diff --git a/src/goals/Redux/GoalActions.ts b/src/goals/Redux/GoalActions.ts index e5409d9ce0..a437ae29bc 100644 --- a/src/goals/Redux/GoalActions.ts +++ b/src/goals/Redux/GoalActions.ts @@ -201,6 +201,14 @@ export function dispatchStepData(goal: Goal) { }; } +/** Add entry update to the current goal. */ +export function asyncUpdateEntry(oldId: string, newId: string) { + return async (dispatch: StoreStateDispatch) => { + dispatch(addEntryEditToGoal({ newId, oldId })); + await dispatch(asyncUpdateGoal()); + }; +} + // Helper Functions export function getUserEditId(): string | undefined { diff --git a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditDialog.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditDialog.tsx index 5f3428ccd1..674e9a62ed 100644 --- a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditDialog.tsx +++ b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditDialog.tsx @@ -35,14 +35,13 @@ import { CancelConfirmDialog } from "components/Dialogs"; import PronunciationsBackend from "components/Pronunciations/PronunciationsBackend"; import PronunciationsFrontend from "components/Pronunciations/PronunciationsFrontend"; import { uploadFileFromPronunciation } from "components/Pronunciations/utilities"; -import { addEntryEditToGoal, asyncUpdateGoal } from "goals/Redux/GoalActions"; import EditSensesCardContent from "goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditSensesCardContent"; import { cleanWord, isSenseChanged, } from "goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/utilities"; -import { useAppDispatch, useAppSelector } from "rootRedux/hooks"; -import { type StoreState, type StoreStateDispatch } from "rootRedux/types"; +import { useAppSelector } from "rootRedux/hooks"; +import { type StoreState } from "rootRedux/types"; import { themeColors } from "types/theme"; import { type FileWithSpeakerId, @@ -54,14 +53,6 @@ import { TextFieldWithFont, } from "utilities/fontComponents"; -/** Add word update to the current goal. */ -function asyncUpdateWord(oldId: string, newId: string) { - return async (dispatch: StoreStateDispatch) => { - dispatch(addEntryEditToGoal({ newId, oldId })); - await dispatch(asyncUpdateGoal()); - }; -} - /** Update word in the backend */ export async function updateFrontierWord( newWord: Word, @@ -116,8 +107,6 @@ interface EditDialogProps { } export default function EditDialog(props: EditDialogProps): ReactElement { - const dispatch = useAppDispatch(); - const analysisWritingSystems = useAppSelector( (state: StoreState) => state.currentProjectState.project.analysisWritingSystems @@ -297,10 +286,7 @@ export default function EditDialog(props: EditDialogProps): ReactElement { props.word.audio ); - // Update in goal - await dispatch(asyncUpdateWord(props.word.id, newId)); - - // Update in ReviewEntries state + // Update in goal and ReviewEntries state await props.confirm(newId); // Close diff --git a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditDialog.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditDialog.test.tsx index e872403871..667382fb87 100644 --- a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditDialog.test.tsx +++ b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditDialog.test.tsx @@ -34,15 +34,10 @@ jest.mock( "goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditSenseDialog" ); jest.mock("i18n", () => ({})); -jest.mock("rootRedux/hooks", () => ({ - ...jest.requireActual("rootRedux/hooks"), - useAppDispatch: () => mockDispatch, -})); const mockClose = jest.fn(); const mockConfirm = jest.fn(); const mockDeleteAudio = jest.fn(); -const mockDispatch = jest.fn(); const mockUpdateWord = jest.fn(); const mockTextFieldEvent = ( @@ -116,7 +111,6 @@ describe("EditDialog", () => { expect(mockClose).toHaveBeenCalledTimes(1); expect(mockConfirm).not.toHaveBeenCalled(); expect(mockUpdateWord).not.toHaveBeenCalled(); - expect(mockDispatch).not.toHaveBeenCalled(); }); test("cancel button opens dialog if changes", async () => { @@ -147,7 +141,6 @@ describe("EditDialog", () => { expect(mockClose).not.toHaveBeenCalled(); expect(mockConfirm).not.toHaveBeenCalled(); expect(mockUpdateWord).not.toHaveBeenCalled(); - expect(mockDispatch).not.toHaveBeenCalled(); // Click the cancel button and confirm the cancel await act(async () => { @@ -164,7 +157,6 @@ describe("EditDialog", () => { expect(mockClose).toHaveBeenCalledTimes(1); expect(mockConfirm).not.toHaveBeenCalled(); expect(mockUpdateWord).not.toHaveBeenCalled(); - expect(mockDispatch).not.toHaveBeenCalled(); }); test("save button closes if no changes", async () => { @@ -180,7 +172,6 @@ describe("EditDialog", () => { expect(mockClose).toHaveBeenCalledTimes(1); expect(mockConfirm).not.toHaveBeenCalled(); expect(mockUpdateWord).not.toHaveBeenCalled(); - expect(mockDispatch).not.toHaveBeenCalled(); }); test("save button saves changes and closes", async () => { @@ -207,7 +198,6 @@ describe("EditDialog", () => { expect(mockUpdateWord).toHaveBeenCalledTimes(1); const updatedWord: Word = mockUpdateWord.mock.calls[0][0]; expect(updatedWord.flag.text).toEqual(newFlagText); - expect(mockDispatch).toHaveBeenCalled(); }); }); diff --git a/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx index b8dfaff759..f8fa7b2917 100644 --- a/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx +++ b/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx @@ -25,6 +25,7 @@ import { setReviewEntriesColumnOrder, setReviewEntriesColumnVisibility, } from "components/Project/ProjectActions"; +import { asyncUpdateEntry } from "goals/Redux/GoalActions"; import * as Cell from "goals/ReviewEntries/ReviewEntriesTable/Cells"; import * as ff from "goals/ReviewEntries/ReviewEntriesTable/filterFn"; import * as sf from "goals/ReviewEntries/ReviewEntriesTable/sortingFn"; @@ -173,9 +174,11 @@ export default function ReviewEntriesTable(props: { }); }; - /** Replaces word (`.id === oldId`) in the state + /** Adds the word update to the current Goal, then + * replaces word (`.id === oldId`) in the state * with word (`.id === newId`) fetched from the backend. */ const replaceWord = async (oldId: string, newId: string): Promise => { + await dispatch(asyncUpdateEntry(oldId, newId)); const newWord = await getWord(newId); setData((prev) => { // Prevent table from jumping back to first page